package com.dsk.cscec.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.cscec.constant.CbProjectConstants;
import com.dsk.cscec.domain.CbProjectFile;
import com.dsk.cscec.domain.CbProjectRecord;
import com.dsk.cscec.domain.bo.AddProjectFileUploadBo;
import com.dsk.cscec.domain.vo.QueryProjectFileUploadDetailVo;
import com.dsk.cscec.mapper.CbProjectFileMapper;
import com.dsk.cscec.mapper.CbProjectRecordMapper;
import com.dsk.cscec.service.CbProjectFileService;
import com.dsk.system.domain.vo.SysOssVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * 项目成本文件表(CbProjectFile)表服务实现类
 *
 * @author sxk
 * @since 2024-02-05 14:01:06
 */
@Service("cbProjectFileService")
public class CbProjectFileServiceImpl extends ServiceImpl<CbProjectFileMapper, CbProjectFile> implements CbProjectFileService {
    @Resource
    private CbProjectFileMapper baseMapper;
    @Resource
    private CbProjectRecordMapper projectRecordMapper;
    @Resource
    private CbProjectFileMapper projectFileMapper;

    /**
     * 校验同一成本类型下是否存在相同文件
     *
     * @param fileUploadBo 上传信息
     */
    @Override
    public Boolean checkProjectFileExist(AddProjectFileUploadBo fileUploadBo) {
        String filename = fileUploadBo.getFile().getOriginalFilename();
        assert filename != null;
        projectFileMapper.selectList(new LambdaQueryWrapper<CbProjectFile>()
                .eq(CbProjectFile::getProjectId, fileUploadBo.getProjectId())
                .eq(CbProjectFile::getCbType, fileUploadBo.getCbType())).forEach(projectFile -> {
            //仅对比文件名,不考虑文件格式
            Assert.isFalse(projectFile.getFileName().substring(0, projectFile.getFileName().lastIndexOf(".")).equals(filename.substring(0, filename.lastIndexOf(".")))
                    , "当前成本类型下存在同名文件,请重新上传");
        });
        return true;
    }

    /**
     * 添加项目上传文件记录
     *
     * @param fileUploadBo 上传信息
     * @param oss          oss信息
     * @return 文件记录
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CbProjectFile addProjectFile(AddProjectFileUploadBo fileUploadBo, SysOssVo oss) {
        //校验项目是否存在
        CbProjectRecord projectRecord = this.checkProjectExist(fileUploadBo.getProjectId());

        CbProjectFile projectFile = BeanUtil.toBean(fileUploadBo, CbProjectFile.class);
        projectFile.setCbStage(projectRecord.getCbStage());
        projectFile.setFileName(oss.getOriginalName());
        projectFile.setFileOssId(oss.getOssId());
        projectFile.setFileOssUrl(oss.getUrl());
        //项目文件状态:准备中
        projectFile.setFileParseStatus(CbProjectConstants.PROJECT_FILE_STATUS_PREPARING);
        baseMapper.insert(projectFile);
        return projectFile;
    }

    /**
     * 批量逻辑删除项目上传文件记录
     *
     * @param fileIds 文件ID
     * @return 删除结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer deleteProjectFile(Long[] fileIds) {
        int flag = 0;
        //查询待删除文件
        List<CbProjectFile> fileList = baseMapper.selectList(new LambdaQueryWrapper<CbProjectFile>()
                .in(ObjectUtil.isNotNull(fileIds), CbProjectFile::getId, Arrays.asList(fileIds)));
        for (CbProjectFile file : fileList) {
            //不允许删除解析中的文件
            Integer fileParseStatus = file.getFileParseStatus();
            Assert.isFalse(fileParseStatus.equals(CbProjectConstants.PROJECT_FILE_STATUS_PARSING),
                    "文件正在解析中,不允许删除");
            //准备中、的文件设为已删除,否则设为待删除
            //设为待删除是为了方便各个成本类型删除数据
            if (fileParseStatus.equals(CbProjectConstants.PROJECT_FILE_STATUS_PREPARING)) {
                flag = baseMapper.deleteById(file);
            } else {
                flag = baseMapper.update(null, new UpdateWrapper<CbProjectFile>()
                        .set("del_flag", CbProjectConstants.DELETE_FLAG_WAIT_DELETE)
                        .eq("id", file.getId()));
            }
        }
        return flag;
    }

    /**
     * 获取项目文件上传详情
     *
     * @param projectId 项目ID
     * @return 文件列表
     */
    @Override
    public QueryProjectFileUploadDetailVo getProjectFileUploadDetail(Long projectId) {
        //校验项目是否存在
        this.checkProjectExist(projectId);

        List<CbProjectFile> projectFileList = baseMapper.selectList(new LambdaQueryWrapper<CbProjectFile>()
                .eq(CbProjectFile::getProjectId, projectId)
                //成本阶段
                //.eq(CbProjectFile::getCbStage, uploadDetailBo.getCbStage())
                //删除状态:否
                .eq(CbProjectFile::getDelFlag, CbProjectConstants.DELETE_FLAG_EXIST));

        QueryProjectFileUploadDetailVo draftDetailVo = new QueryProjectFileUploadDetailVo();
        draftDetailVo.setProjectId(projectId);
        if (projectFileList.isEmpty()) {
            return null;
        }

        //按照成本类型分类填充
        projectFileList.forEach(fileList -> {
            //TODO:此写法太丑陋,待优化
            if (Objects.equals(fileList.getCbType(), CbProjectConstants.CB_TYPE_DIRECT_EXPENSE)) {
                //直接费成本
                draftDetailVo.getDirectExpense().add(fileList);
            } else if (Objects.equals(fileList.getCbType(), CbProjectConstants.CB_TYPE_QUANTITY_SUMMARY)) {
                //工料汇总
                draftDetailVo.getQuantitySummary().add(fileList);
            } else if (Objects.equals(fileList.getCbType(), CbProjectConstants.CB_TYPE_MEASURE_PROJECT)) {
                //措施项目
                draftDetailVo.getMeasureProject().add(fileList);
            } else if (Objects.equals(fileList.getCbType(), CbProjectConstants.CB_TYPE_OTHER_PROJECT)) {
                //其他项目
                draftDetailVo.getOtherProject().add(fileList);
            } else if (Objects.equals(fileList.getCbType(), CbProjectConstants.CB_TYPE_SCENE_EXPENSE)) {
                //现场经费
                draftDetailVo.getSceneExpense().add(fileList);
            } else if (Objects.equals(fileList.getCbType(), CbProjectConstants.CB_TYPE_SUMMARY)) {
                //成本汇总
                draftDetailVo.getCbSummary().add(fileList);
            }
        });
        return draftDetailVo;
    }

    /**
     * 校验项目是否存在
     *
     * @param projectId 项目ID
     * @return 项目实体
     */
    private CbProjectRecord checkProjectExist(Long projectId) {
        //校验项目是否存在
        CbProjectRecord projectRecord = projectRecordMapper.selectById(projectId);
        Assert.notNull(projectRecord, "该项目不存在");
        return projectRecord;
    }
}
