/**
 * Copyright (c) 2018-2099, Chill Zhuang 庄骞 (bladejava@qq.com).
 * <p>
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/lgpl.html
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.xiaoniu.subsystem.business.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.xiaoniu.common.core.result.R;
import com.xiaoniu.common.core.utils.BeanUtil;
import com.xiaoniu.common.core.utils.poi.ExcelUtil;
import com.xiaoniu.common.log.annotation.Log;
import com.xiaoniu.common.log.enums.BusinessType;
import com.xiaoniu.subsystem.business.domain.Expense;
import com.xiaoniu.subsystem.business.domain.Flight;
import com.xiaoniu.subsystem.business.domain.Profile;
import com.xiaoniu.subsystem.business.domain.ProfileManage;
import com.xiaoniu.subsystem.business.domain.dto.ProfileDTO;
import com.xiaoniu.subsystem.business.domain.dto.ProfileManageDTO;
import com.xiaoniu.subsystem.business.domain.dto.ProfilePageDTO;
import com.xiaoniu.subsystem.business.domain.dto.ProfileSaveDTO;
import com.xiaoniu.subsystem.business.domain.vo.ProfileVO;
import com.xiaoniu.subsystem.business.service.IExpenseService;
import com.xiaoniu.subsystem.business.service.IManageFileService;
import com.xiaoniu.subsystem.business.service.IProfileManageService;
import com.xiaoniu.subsystem.business.service.IProfileService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import static com.xiaoniu.common.security.utils.SecurityUtils.getUnitId;
import static com.xiaoniu.common.security.utils.SecurityUtils.getUserId;

/**
 * 资料管理表 控制器
 *
 * @author sst
 * @since 2024-11-26
 */
@RestController
@AllArgsConstructor
@RequestMapping("/profile")
@Tag(name = "资料管理表", description = "资料管理表接口")
public class ProfileController {


    private IProfileService profileService;

    private IExpenseService expenseService;

    private IProfileManageService profileManageService;

    /**
     * 详情
     */
    @GetMapping("/detail")
    @ApiOperationSupport(order = 1)
    @Operation(summary = "详情", description = "传入profile")
    public R<ProfileVO> detail(@Parameter(description = "主键", required = true) @RequestParam Long profileId) {
        Profile detail = profileService.getById(profileId);
        return R.data(BeanUtil.copy(detail, ProfileVO.class));
    }

    /**
     * 详情
     */
    @GetMapping("/flight/detail")
    @ApiOperationSupport(order = 1)
    @Operation(summary = "班次详情", description = "传入profile")
    public R<ProfileVO> flightDetail(ProfilePageDTO dto) {
        Profile detail = profileService.getOne(new LambdaQueryWrapper<Profile>()
                .eq(Profile::getType, dto.getType())
                .eq(Profile::getFlightId, dto.getFlightId())
        );
        return R.data(BeanUtil.copy(detail, ProfileVO.class));
    }


    /**
     * 分页 资料管理表
     */
    @GetMapping("/page")
    @ApiOperationSupport(order = 2)
    @Operation(summary = "分页", description = "传入profile")
    public R<IPage<ProfileVO>> page(@Validated ProfilePageDTO dto) {
        IPage<Profile> pages = profileService.page(new Page<>(dto.getPageNum(), dto.getPageSize()),
                new LambdaQueryWrapper<Profile>()
                        .eq(Profile::getType, dto.getType())
                        .eq(null != dto.getFlightId(), Profile::getFlightId, dto.getFlightId())
                        .eq(Profile::getTrainingUnitId, getUnitId())
                        .like(StringUtils.isNotBlank(dto.getFlightName()), Profile::getFlightName, dto.getFlightName())
                        .like(StringUtils.isNotBlank(dto.getFlightCode()), Profile::getFlightCode, dto.getFlightCode())
                        .like(StringUtils.isNotBlank(dto.getProfileName()), Profile::getProfileName, dto.getProfileName())
                        .eq(StringUtils.isNotBlank(dto.getYear()), Profile::getYear, dto.getYear())
                        .orderByDesc(Profile::getCreateTime));
        return R.data(BeanUtil.copy(pages, ProfileVO.class));
    }

    /**
     * 导出
     */
    @GetMapping("/export")
    @ApiOperationSupport(order = 3)
    @Log(title = "资料导出", businessType = BusinessType.EXPORT)
    @Operation(summary = "导出", description = "传入ids")
    public void export(HttpServletResponse response, @Validated ProfilePageDTO dto) {
        List<Profile> list = new ArrayList<>();
        if (StringUtils.isNotBlank(dto.getIds())) {
            list.addAll(profileService.list(new LambdaQueryWrapper<Profile>()
                    .orderByDesc(Profile::getCreateTime)
                    .in(StringUtils.isNotBlank(dto.getIds()), Profile::getProfileId,
                            Arrays.stream(dto.getIds().split(",")).toList())));
        } else {
            list.addAll(profileService.list(new LambdaQueryWrapper<Profile>()
                    .orderByDesc(Profile::getCreateTime)
                    .eq(Profile::getType, dto.getType())
                    .eq(null != dto.getFlightId(), Profile::getFlightId, dto.getFlightId())
                    .like(StringUtils.isNotBlank(dto.getFlightName()), Profile::getFlightName, dto.getFlightName())
                    .like(StringUtils.isNotBlank(dto.getFlightCode()), Profile::getFlightCode, dto.getFlightCode())
                    .like(StringUtils.isNotBlank(dto.getProfileName()), Profile::getProfileName, dto.getProfileName())
                    .eq(StringUtils.isNotBlank(dto.getYear()), Profile::getYear, dto.getYear())));
        }
        ExcelUtil<Profile> excelUtil = new ExcelUtil<>(Profile.class);
        excelUtil.exportExcel(response, list, (StringUtils.equals(dto.getType(), "0") ? "培训资料数据" :
                StringUtils.equals(dto.getType(), "1") ? "结算资料数据" : "评审资料"));

    }

    /**
     * 新增 资料管理表
     */
    @PostMapping("/save")
    @ApiOperationSupport(order = 4)
    @Operation(summary = "新增", description = "传入profile")
    public R save(@Valid @RequestBody ProfileDTO dto) {
        Profile profile = profileService.getOne(new LambdaQueryWrapper<Profile>()
                .eq(Profile::getFlightId, dto.getFlightId())
                .eq(Profile::getType, dto.getType())
        );
        if (profile != null) {
            profileService.updateById(profile.setUrl(dto.getUrl()));
            return R.status(profileService.updateById(profile.setUrl(dto.getUrl()).setUpdateUser(getUserId()).setUpdateTime(new Date())));
        }
        return R.status(profileService.save(
                dto.setYear(String.valueOf(LocalDate.now().getYear()))
                        .setCreateDept(getUnitId()).setCreateUser(getUserId()).setCreateTime(new Date())));
    }

    /**
     * 新增 资料管理表
     */
    @PostMapping("/flight/Save")
    @ApiOperationSupport(order = 4)
    @Operation(summary = "班次新增", description = "传入profile")
    public R flightSave(@Valid @RequestBody ProfileDTO dto) {
        Profile profile = profileService.getOne(new LambdaQueryWrapper<Profile>()
                .eq(Profile::getFlightId, dto.getFlightId())
                .eq(Profile::getType, dto.getType())
        );
        //type--0预算 1结算，只有结算解析数据
        if (dto.getType().equals("1")){
            if (profile != null) {
                boolean b = profileService.updateById(profile.setUrl(dto.getUrl()));
                if (!b) {
                    return R.status(b);
                }

                //解析数据
                Expense expense = expenseService.getExpense(dto.getFlightId());
                if (expense != null) {
                    expenseService.removeById(expense);
                }
                profileService.extracted(profile.setUrl(dto.getUrl()));

                //同步ProfileManage数据
                ProfileManage file = profileManageService.getOne(new LambdaQueryWrapper<ProfileManage>()
                        .eq(ProfileManage::getFlightId, dto.getFlightId())
                        .eq(ProfileManage::getType,"1")
                        .eq(ProfileManage::getProfileName, "结算单"));
                file.setUpdateUser(getUserId())
                        .setUpdateTime(new Date())
                        .setUrl(dto.getUrl());
                profileManageService.updateById(file);

            }else {
                boolean save = profileService.save(
                        dto.setYear(String.valueOf(LocalDate.now().getYear()))
                                .setCreateDept(getUnitId()).setCreateUser(getUserId()).setCreateTime(new Date()));

                if (!save) {
                    R.status(save);
                }
                //解析结算数据
                Profile detail = profileService.getOne(new LambdaQueryWrapper<Profile>()
                        .eq(Profile::getType, dto.getType())
                        .eq(Profile::getFlightId, dto.getFlightId())
                );
                profileService.extracted(detail.setUrl(dto.getUrl()));

                //同步数据
                ProfileManage file = profileManageService.getOne(new LambdaQueryWrapper<ProfileManage>()
                        .eq(ProfileManage::getFlightId, dto.getFlightId())
                        .eq(ProfileManage::getType,"1")
                        .eq(ProfileManage::getProfileName, "结算单"));
                file.setUpdateUser(getUserId())
                        .setUpdateTime(new Date())
                        .setUrl(dto.getUrl());
                profileManageService.updateById(file);
            }
            return R.status(true);

        }else{
            if (profile != null) {
                boolean b = profileService.updateById(profile.setUrl(dto.getUrl()));
                if (!b) {
                    return R.status(b);
                }
            }else{
                boolean save = profileService.save(
                        dto.setYear(String.valueOf(LocalDate.now().getYear()))
                                .setCreateDept(getUnitId()).setCreateUser(getUserId()).setCreateTime(new Date()));
                if (!save) {
                    return R.status(save);
                }
            }
            //同步数据
            ProfileManage file = profileManageService.getOne(new LambdaQueryWrapper<ProfileManage>()
                    .eq(ProfileManage::getFlightId, dto.getFlightId())
                    .eq(ProfileManage::getType,"1")
                    .eq(ProfileManage::getProfileName, "预算表"));
            file.setUpdateUser(getUserId())
                    .setUpdateTime(new Date())
                    .setUrl(dto.getUrl());
            profileManageService.updateById(file);
            return R.status(true);
        }

    }

    /**
     * 修改 资料管理表
     */
    @PostMapping("/update")
    @ApiOperationSupport(order = 5)
    @Operation(summary = "修改", description = "传入profile")
    public R update(@Valid @RequestBody ProfileDTO dto) {
        return R.status(profileService.updateById(
                dto.setUpdateUser(getUserId()).setUpdateTime(new Date())));
    }

    /**
     * 获取连接集合
     */
    @GetMapping("/getUrls")
    @ApiOperationSupport(order = 6)
    @Operation(summary = "获取连接集合", description = "传入dto")
    public R<List<String>> getUrls(@Validated ProfilePageDTO dto) {
        List<Profile> list = new ArrayList<>();
        if (StringUtils.isNotBlank(dto.getIds())) {
            list.addAll(profileService.list(new LambdaQueryWrapper<Profile>()
                    .orderByDesc(Profile::getCreateTime)
                    .in(StringUtils.isNotBlank(dto.getIds()), Profile::getProfileId,
                            Arrays.stream(dto.getIds().split(",")).toList())));
        } else {
            list.addAll(profileService.list(new LambdaQueryWrapper<Profile>()
                    .orderByDesc(Profile::getCreateTime)
                    .eq(Profile::getType, dto.getType())
                    .eq(null != dto.getFlightId(), Profile::getFlightId, dto.getFlightId())
                    .like(StringUtils.isNotBlank(dto.getFlightName()), Profile::getFlightName, dto.getFlightName())
                    .like(StringUtils.isNotBlank(dto.getFlightCode()), Profile::getFlightCode, dto.getFlightCode())
                    .like(StringUtils.isNotBlank(dto.getProfileName()), Profile::getProfileName, dto.getProfileName())
                    .eq(StringUtils.isNotBlank(dto.getYear()), Profile::getYear, dto.getYear())));
        }
        List<String> urls = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            for (Profile profile : list) {
                urls.add(profile.getUrl());
            }
        }
        return R.data(urls);
    }

    /**
     * 删除 资料管理表
     */
    @PostMapping("/remove")
    @ApiOperationSupport(order = 7)
    @Operation(summary = "删除", description = "传入ids")
    public R remove(@NotNull @Parameter(description = "主键集合", required = true) @RequestParam String profileIds) {
        return R.status(profileService.removeByIds(Arrays.stream(profileIds.split(",")).toList()));
    }

    @Operation(summary = "导入文件（压缩包）")
    @PostMapping(value = "/importProFile")
    @ApiOperationSupport(order = 8)
    public R<String> importProFile(@RequestPart(value = "file") MultipartFile file,
                                   ProfileSaveDTO dto) {
        profileService.importProFile(file, dto);
        return R.status(true);
    }

}
