/*
 * 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.pmPerformance.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.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.pmBudget.entity.PmBudget;
import com.unis.projectManagement.modular.pmBudget.mapper.PmBudgetMapper;
import com.unis.projectManagement.modular.pmPerformance.entity.PmBudgetBase;
import com.unis.projectManagement.modular.pmPerformance.entity.PmBudgetParam;
import com.unis.projectManagement.modular.projectInfoPlan.entity.ProjectInfoPlan;
import com.unis.projectManagement.modular.projectInfoPlan.mapper.ProjectInfoPlanMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.unis.common.exception.CommonException;
import com.unis.common.page.CommonPageRequest;
import com.unis.projectManagement.modular.pmPerformance.entity.PmPerformance;
import com.unis.projectManagement.modular.pmPerformance.mapper.PmPerformanceMapper;
import com.unis.projectManagement.modular.pmPerformance.param.PmPerformanceAddParam;
import com.unis.projectManagement.modular.pmPerformance.param.PmPerformanceEditParam;
import com.unis.projectManagement.modular.pmPerformance.param.PmPerformanceIdParam;
import com.unis.projectManagement.modular.pmPerformance.param.PmPerformancePageParam;
import com.unis.projectManagement.modular.pmPerformance.service.PmPerformanceService;

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

/**
 * 绩效上报管理Service接口实现类
 *
 * @author QSHan
 * @date 2024/05/30 19:34
 **/
@Service
public class PmPerformanceServiceImpl extends ServiceImpl<PmPerformanceMapper, PmPerformance> implements PmPerformanceService {
    @Resource
    private PmPerformanceMapper performanceMapper;
    @Resource
    private PmBudgetMapper budgetMapper;
    @Resource
    private ProjectInfoPlanMapper projectInfoPlanMapper;
    @Resource
    private AuditRequestMapper auditRequestMapper;
    @Resource
    private AuditRecordMapper auditRecordMapper;

    @Override
    public Page<PmPerformance> page(PmPerformancePageParam param) {
        QueryWrapper<PmPerformance> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(param.getProjectName()))
            wrapper.like("bpa.project_name", param.getProjectName());
        if (ObjectUtils.isNotEmpty(param.getStatus())) {
            if (0 != param.getStatus())
                wrapper.ne("bpp.`status`", 0);
        }
        wrapper.lambda().orderByDesc(PmPerformance::getId);
        return performanceMapper.pageList(CommonPageRequest.defaultPage(), wrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(PmPerformanceAddParam pmPerformanceAddParam) {
        // 保存主表数据
        PmPerformance pmPerformance = BeanUtil.toBean(pmPerformanceAddParam, PmPerformance.class);
        this.save(pmPerformance);
        // 保存关联数据
        List<ProjectInfoPlan> projectInfoPlan = pmPerformanceAddParam.getProjectInfoPlan();
        if (CollectionUtils.isNotEmpty(projectInfoPlan)) {
            projectInfoPlan.forEach(info -> projectInfoPlanMapper.updateById(info));
        }
        // 审批记录(0:保存(待申报);1:提交(待批复);2:驳回;3:已批复)
        if (1 == pmPerformanceAddParam.getStatus()) {
            this.addAndEditAudit(pmPerformance);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(PmPerformanceEditParam pmPerformanceEditParam) {
        PmPerformance pmPerformance = this.queryEntity(pmPerformanceEditParam.getId());
        BeanUtil.copyProperties(pmPerformanceEditParam, pmPerformance);
        this.updateById(pmPerformance);
        // 修改 项目实施进度计划
        List<ProjectInfoPlan> projectInfoPlan = pmPerformanceEditParam.getProjectInfoPlan();
        if (CollectionUtils.isNotEmpty(projectInfoPlan)) {
            projectInfoPlan.forEach(plan -> projectInfoPlanMapper.updateById(plan));
        }
        // 审批记录(0:保存(待申报);1:提交(待批复);2:驳回;3:已批复)
        if (0 != pmPerformanceEditParam.getStatus()) {
            this.addAndEditAudit(pmPerformance);
        }
    }

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

    @Override
    public PmPerformance detail(PmPerformanceIdParam pmPerformanceIdParam) {
        return this.queryEntity(pmPerformanceIdParam.getId());
    }

    @Override
    public PmPerformance queryEntity(String id) {
        PmPerformance pmPerformance = this.getById(id);
        if (ObjectUtil.isEmpty(pmPerformance)) {
            throw new CommonException("绩效上报管理不存在，id值为：{}", id);
        }
        return pmPerformance;
    }

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

    @Override
    public PmBudgetBase getDetailAllList(String budgetId, String pmApplicationId, String id) {
        // budgetId查询项目预算资金数据
        PmBudgetParam pmBudgetParam = budgetMapper.selectByDetailId(budgetId);
        PmBudgetBase pmBudgetBase = BeanUtil.toBean(pmBudgetParam, PmBudgetBase.class);
        // 项目实施进度计划
        QueryWrapper<ProjectInfoPlan> wrapper = new QueryWrapper<>();
        wrapper.eq("pm_application_id", pmApplicationId);
        List<ProjectInfoPlan> projectInfoPlan = projectInfoPlanMapper.selectList(wrapper);
        if (ObjectUtils.isEmpty(pmBudgetBase))
            return new PmBudgetBase();
        if (CollectionUtils.isNotEmpty(projectInfoPlan))
            pmBudgetBase.setProjectInfoPlan(projectInfoPlan);
        // 查询审核意见
        QueryWrapper<AuditRequest> requestWrapper = new QueryWrapper<>();
        requestWrapper.eq("request_id", id);
        AuditRequest request = auditRequestMapper.selectOne(requestWrapper);
        if (ObjectUtils.isNotEmpty(request)) {
            String auditAdvice = request.getAuditAdvice();
            if (StringUtils.isNotEmpty(auditAdvice))
                pmBudgetBase.setAuditAdvice(auditAdvice);
        }
        return pmBudgetBase;
    }

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

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