/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package com.unis.projectManagement.modular.pmBudget.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.unis.policy.info.modular.auditRecord.entity.AuditRecord;
import com.unis.policy.info.modular.auditRecord.mapper.AuditRecordMapper;
import com.unis.policy.info.modular.auditRequest.entity.AuditRequest;
import com.unis.policy.info.modular.auditRequest.mapper.AuditRequestMapper;
import com.unis.projectManagement.modular.pmProjectInfoFile.entity.PmProjectInfoFile;
import com.unis.projectManagement.modular.pmProjectInfoFile.mapper.PmProjectInfoFileMapper;
import com.unis.projectManagement.modular.projectInfoPlan.entity.ProjectInfoPlan;
import com.unis.projectManagement.modular.projectInfoPlan.mapper.ProjectInfoPlanMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.unis.common.exception.CommonException;
import com.unis.projectManagement.modular.pmBudget.entity.PmBudget;
import com.unis.projectManagement.modular.pmBudget.mapper.PmBudgetMapper;
import com.unis.projectManagement.modular.pmBudget.param.PmBudgetAddParam;
import com.unis.projectManagement.modular.pmBudget.param.PmBudgetEditParam;
import com.unis.projectManagement.modular.pmBudget.param.PmBudgetIdParam;
import com.unis.projectManagement.modular.pmBudget.param.PmBudgetPageParam;
import com.unis.projectManagement.modular.pmBudget.service.PmBudgetService;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * 项目预算资金Service接口实现类
 *
 * @author QSHan
 * @date 2024/05/28 16:04
 **/
@Service
public class PmBudgetServiceImpl extends ServiceImpl<PmBudgetMapper, PmBudget> implements PmBudgetService {
    @Resource
    private PmBudgetMapper pmBudgetMapper;
    @Resource
    private ProjectInfoPlanMapper projectInfoPlanMapper;
    @Resource
    private AuditRequestMapper auditRequestMapper;
    @Resource
    private AuditRecordMapper auditRecordMapper;
    @Resource
    private PmProjectInfoFileMapper projectInfoFileMapper;

    @Override
    public Page<PmBudget> page(PmBudgetPageParam pmBudgetPageParam) {
        QueryWrapper<PmBudget> queryWrapper = new QueryWrapper<>();
        if (ObjectUtils.isNotEmpty(pmBudgetPageParam.getProjectName())) {
            queryWrapper.like("bpa.project_name", pmBudgetPageParam.getProjectName());
        }
        // 状态(1,3为审批列表) 0:保存(待申报);1:提交(待批复);2:驳回;3:已批复
        Integer status = pmBudgetPageParam.getStatus();
        if (ObjectUtils.isNotEmpty(status))
            if (status == 1 || status == 3)
                queryWrapper.in("bpb.`status`", 1, 3);
        queryWrapper.lambda().orderByDesc(PmBudget::getId);
        return pmBudgetMapper.pageList(new Page<>(pmBudgetPageParam.getCurrent(), pmBudgetPageParam.getSize()), queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(PmBudgetAddParam pmBudgetAddParam) {
        PmBudget pmBudget = BeanUtil.toBean(pmBudgetAddParam, PmBudget.class);
        this.save(pmBudget);
        // 修改详情-项目实施进度计划
        this.addAndEditUtil(pmBudget.getProjectInfoPlan());
        // 保存审批状态和审批记录(1:提交(待批复);2:驳回;3：已批复)
        this.addAndEditAudit(pmBudget);
        // 附件上传
        this.upFileUtil(pmBudget);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(PmBudgetEditParam pmBudgetEditParam) {
        PmBudget pmBudget = this.queryEntity(pmBudgetEditParam.getId());
        BeanUtil.copyProperties(pmBudgetEditParam, pmBudget);
        this.updateById(pmBudget);
        // 修改详情-项目实施进度计划
        this.addAndEditUtil(pmBudget.getProjectInfoPlan());
        // 保存审批状态和审批记录(1:提交(待批复);2:驳回;3：已批复)
        this.addAndEditAudit(pmBudget);
        // 附件上传
        this.upFileUtil(pmBudget);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<PmBudgetIdParam> pmBudgetIdParamList) {
        // 执行删除
        this.removeByIds(CollStreamUtil.toList(pmBudgetIdParamList, PmBudgetIdParam::getId));
    }

    @Override
    public PmBudget detail(PmBudgetIdParam pmBudgetIdParam) {
        // 查询详情
        PmBudget pmBudget = pmBudgetMapper.queryDetail(pmBudgetIdParam.getId());
        // 查询项目实施进度计划
        QueryWrapper<ProjectInfoPlan> wrapper = new QueryWrapper<>();
        wrapper.eq("pm_application_id", pmBudget.getPmApplicationId());
        List<ProjectInfoPlan> projectInfoPlans = projectInfoPlanMapper.selectList(wrapper);
        if (CollectionUtils.isNotEmpty(projectInfoPlans))
            pmBudget.setProjectInfoPlan(projectInfoPlans);
        // 查询审批意见
        QueryWrapper<AuditRequest> requestWrapper = new QueryWrapper<>();
        requestWrapper.eq("request_id", pmBudget.getId());
        AuditRequest auditRequest = auditRequestMapper.selectOne(requestWrapper);
        if (ObjectUtils.isNotEmpty(auditRequest))
            if (StringUtils.isNotEmpty(auditRequest.getAuditAdvice()))
                pmBudget.setAuditAdvice(auditRequest.getAuditAdvice());
        // 查询文件
        PmProjectInfoFile file = this.selectFileObject(pmBudget.getId());
        if (ObjectUtils.isNotEmpty(file)) {
            if (StringUtils.isNotEmpty(file.getFileName()))
                pmBudget.setFileName(file.getFileName());
            if (StringUtils.isNotEmpty(file.getVersion()))
                pmBudget.setVersion(file.getVersion());
            if (StringUtils.isNotEmpty(file.getAttachment()))
                pmBudget.setAttachment(file.getAttachment());
        }
        return pmBudget;
    }

    @Override
    public PmBudget queryEntity(String id) {
        PmBudget pmBudget = this.getById(id);
        if (ObjectUtil.isEmpty(pmBudget)) {
            throw new CommonException("项目预算资金不存在，id值为：{}", id);
        }
        return pmBudget;
    }

    @Override
    public List<Map<String, Object>> getProjectList() {
        return pmBudgetMapper.getProjectList();
    }

    @Override
    public Map<String, Object> getProjectCode(String id) {
        return pmBudgetMapper.getProjectCode(id);
    }

    @Override
    public List<ProjectInfoPlan> getProjectPlanList(String pmApplicationId) {
        // 查询项目实施进度计划
        QueryWrapper<ProjectInfoPlan> wrapper = new QueryWrapper<>();
        wrapper.eq("pm_application_id", pmApplicationId);
        return projectInfoPlanMapper.selectList(wrapper);
    }

    // 修改详情-项目实施进度计划
    private void addAndEditUtil(List<ProjectInfoPlan> projectInfoPlan) {
        if (CollectionUtils.isNotEmpty(projectInfoPlan)) {
            int sum = 0;
            for (ProjectInfoPlan plan : projectInfoPlan) {
                /*QueryWrapper<ProjectInfoPlan> planQueryWrapper = new QueryWrapper<>();
                planQueryWrapper.eq("pm_application_id", plan.getPmApplicationId());
                sum += projectInfoPlanMapper.update(plan, planQueryWrapper);*/
                sum += projectInfoPlanMapper.updateById(plan);
            }
            if (sum != projectInfoPlan.size())
                throw new CommonException("项目实施进度计划更新失败");
        }
    }

    // 保存审批状态和审批记录(1:提交(待批复);2:驳回;3：已批复)
    private void addAndEditAudit(PmBudget pmBudget) {
        // 控制事务
        int num = 0;
        Integer status = pmBudget.getStatus();
        if (ObjectUtils.isNotEmpty(status) && (status == 1 || status == 2 || status == 3)) {
            // 审批状态保存或更新
            QueryWrapper<AuditRequest> wrapper = new QueryWrapper<>();
            wrapper.eq("request_id", pmBudget.getId());
            wrapper.eq("delete_flag", "NOT_DELETE");
            AuditRequest auditRequest = auditRequestMapper.selectOne(wrapper);
            // 审批状态
            AuditRequest request = new AuditRequest();
            // 审批记录
            AuditRecord record = new AuditRecord();
            if (ObjectUtils.isEmpty(auditRequest)) {
                // type:审批功能模块(项目审批)
                request.setType(7);
                // step:审批类型(项目预算资金审核)
                request.setStep(1);
                // 业务id
                request.setRequestId(pmBudget.getId());
                // 审批状态
                request.setAuditStatus(pmBudget.getStatus());
                // 审批意见
                request.setAuditAdvice(pmBudget.getAuditAdvice());
                num += auditRequestMapper.insert(request);
                // 审批记录-子表
                record.setAuditRequestId(request.getId());

            } else {
                request.setId(auditRequest.getId());
                // 审批状态
                request.setAuditStatus(pmBudget.getStatus());
                // 审批意见
                request.setAuditAdvice(pmBudget.getAuditAdvice());
                num += auditRequestMapper.updateById(request);
                // 审批记录-子表
                record.setAuditRequestId(auditRequest.getId());
            }
            record.setType(7);
            record.setStep(1);
            record.setRequestId(pmBudget.getId());
            record.setAuditStatus(pmBudget.getStatus());
            record.setAuditAdvice(pmBudget.getAuditAdvice());
            num += auditRecordMapper.insert(record);
            // 主表新增或修改 1,审批记录表必须有1条记录 so 1+1=2 结果必须为2,否则事务回滚
            if (num != 2)
                throw new CommonException("审批状态或审批记录更新失败");
        }
    }

    private void upFileUtil(PmBudget pmBudget) {
        String attachment = pmBudget.getAttachment();
        if (StringUtils.isNotEmpty(attachment)) {
            // 定义事务
            int i = 0;
            PmProjectInfoFile fileObject = this.selectFileObject(pmBudget.getId());
            PmProjectInfoFile file = new PmProjectInfoFile();
            file.setPmApplicationId(pmBudget.getPmApplicationId());
            file.setFileName(pmBudget.getFileName());
            file.setVersion(pmBudget.getId());
            file.setRemark(pmBudget.getRemark());
            file.setAttachment(pmBudget.getAttachment());
            if (ObjectUtils.isEmpty(fileObject)) {
                i += projectInfoFileMapper.insert(file);
            } else {
                file.setId(fileObject.getId());
                i += projectInfoFileMapper.updateById(file);
            }
            if (i != 1)
                throw new CommonException("附件上传保存失败");
        }
    }

    private PmProjectInfoFile selectFileObject(String applicationId) {
        QueryWrapper<PmProjectInfoFile> wrapper = new QueryWrapper<>();
        wrapper.eq("version", applicationId);
        return projectInfoFileMapper.selectOne(wrapper);
    }

}
