/**
 * 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.DateUtils;
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.Profile;
import com.xiaoniu.subsystem.business.domain.ProfileFile;
import com.xiaoniu.subsystem.business.domain.dto.ProfileDTO;
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.IProfileFileService;
import com.xiaoniu.subsystem.business.service.IProfileService;
import com.xiaoniu.subsystem.system.utils.MysqlDataBackupUtil;
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.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
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.*;

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
@RequiredArgsConstructor
@RequestMapping("/profile")
@Tag(name = "资料管理表", description = "资料管理表接口")
public class ProfileController {

    /**
     * 资源映射路径 前缀
     */
    @Value("${file.prefix}")
    private String localFilePrefix;

    /**
     * 上传文件存储在本地的根路径
     */
    @Value("${file.path}")
    private String localFilePath;

    private final IProfileService profileService;
    private final IProfileFileService profileFileService;

    /**
     * 详情
     */
    @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("/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(Profile::getCreateDept,getUnitId())
                        .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())
                        .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 one = profileService.getOne(new LambdaQueryWrapper<Profile>()
                .eq(Profile::getFlightName, dto.getFlightName())
                .eq(Profile::getType, dto.getType())
                .eq(Profile::getTrainingTime, dto.getTrainingTime())
                .eq(Profile::getYear, dto.getYear())
                .eq(Profile::getFlightId, dto.getFlightId())
                .eq(Profile::getProfileCode, dto.getProfileCode()));
        if (null != one) {
            return R.fail("已存在年度：" + dto.getYear() +
                    "度,开训时间：" + DateUtils.dateTime(dto.getTrainingTime()) +
                    ",专业（班次）名称：" + dto.getFlightName() +
                    ",编码：" + dto.getProfileCode() +
                    "的资料，请核对");
        }
        return R.status(profileService.save(
                dto.setYear(String.valueOf(LocalDate.now().getYear()))
                        .setCreateDept(getUnitId()).setCreateUser(getUserId()).setCreateTime(new Date())));
    }

    /**
     * 修改 资料管理表
     */
    @PostMapping("/update")
    @ApiOperationSupport(order = 5)
    @Operation(summary = "修改", description = "传入profile")
    public R update(@Valid @RequestBody ProfileDTO dto) {
        Profile one = profileService.getOne(new LambdaQueryWrapper<Profile>()
                .eq(Profile::getFlightName, dto.getFlightName())
                .eq(Profile::getType, dto.getType())
                .eq(Profile::getTrainingTime, dto.getTrainingTime())
                .ne(Profile::getProfileId, dto.getProfileId())
                .eq(Profile::getFlightId, dto.getFlightId())
                .eq(Profile::getProfileCode, dto.getProfileCode()));
        if (null != one) {
            return R.fail("已存在年度：" + dto.getYear() +
                    "度,开训时间：" + DateUtils.dateTime(dto.getTrainingTime()) +
                    ",专业（班次）名称：" + dto.getFlightName() +
                    ",编码：" + dto.getProfileCode() +
                    "的资料，请核对");
        }
        return R.status(profileService.updateById(
                dto.setUpdateUser(getUserId()).setUpdateTime(new Date())));
    }
    /**
     * 获取需求报名人数
     */
    @GetMapping("/get/flightIds")
    @ApiOperationSupport(order = 13)
    @Operation(summary = "获取协议/合同班次ids")
    public R<List<Long>> getPeopleNum(@Parameter(description = "类型(0培训资料 1结算资料 2评审资料)", required = true) @RequestParam Integer type) {
        List<Profile> list = profileService.list(new LambdaQueryWrapper<Profile>()
                .eq(Profile::getType, type)
                .eq(Profile::getCreateDept,getUnitId()));
        if (CollectionUtils.isEmpty(list)) return R.data(Collections.emptyList());
        return R.data(list.stream().map(Profile::getFlightId).toList());
    }
    /**
     * 获取连接集合
     */
    @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) {
        List<Profile> profiles = profileService.listByIds(Arrays.stream(profileIds.split(",")).toList());
        for (Profile profile : profiles) {
            if (MysqlDataBackupUtil.MysqlPathSystem){
                String file = localFilePath + profile.getUrl().replaceAll(localFilePrefix, "");
                MysqlDataBackupUtil.deleteFiles(file);
                List<ProfileFile> list = profileFileService.list(new LambdaQueryWrapper<ProfileFile>()
                        .eq(ProfileFile::getProfileId, profile.getProfileId()));
                if (CollectionUtils.isNotEmpty(list)) {
                    for (ProfileFile profileFile : list) {
                        String profileFileUel = localFilePath + profileFile.getUrl().replaceAll(localFilePrefix, "");
                        MysqlDataBackupUtil.deleteFiles(profileFileUel);
                    }
                    profileFileService.removeByIds(list.stream().map(ProfileFile::getProfileFileId).toList());
                }
            }
        }
        return R.status(profileService.removeByIds(profiles.stream().map(Profile::getProfileId).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);
    }

}
