/*
 * 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.pmStorageConstruction.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
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.pmStorageConstruction.param.*;
import com.unis.projectManagement.modular.pmStorageConstructionFile.entity.PmStorageConstructionFile;
import com.unis.projectManagement.modular.pmStorageConstructionFile.mapper.PmStorageConstructionFileMapper;
import com.unis.projectManagement.modular.pmStorageConstructionFile.service.PmStorageConstructionFileService;
import com.unis.projectManagement.modular.pmStorageConstructionPlan.entity.PmStorageConstructionPlan;
import com.unis.projectManagement.modular.pmStorageConstructionPlan.mapper.PmStorageConstructionPlanMapper;
import com.unis.projectManagement.modular.pmStorageConstructionPlan.service.PmStorageConstructionPlanService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.unis.common.enums.CommonSortOrderEnum;
import com.unis.common.exception.CommonException;
import com.unis.common.page.CommonPageRequest;
import com.unis.projectManagement.modular.pmStorageConstruction.entity.PmStorageConstruction;
import com.unis.projectManagement.modular.pmStorageConstruction.mapper.PmStorageConstructionMapper;
import com.unis.projectManagement.modular.pmStorageConstruction.service.PmStorageConstructionService;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 仓储设施投资-仓储设施建设表Service接口实现类
 *
 * @author hjc
 * @date 2024/05/30 15:58
 **/
@Service
public class PmStorageConstructionServiceImpl extends ServiceImpl<PmStorageConstructionMapper, PmStorageConstruction> implements PmStorageConstructionService {

    private static Map<String, Integer> sequenceNumbers = new HashMap<>(); // 映射：仓房代码到顺序号
    private static final int MAX_SEQUENCE_NUMBER = 1000; // 顺序号的最大值
    private static final String DATE_FORMAT = "yyyyMMdd";
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(DATE_FORMAT);
    @Autowired
    private PmStorageConstructionFileMapper pmStorageConstructionFileMapper;

    @Autowired
    private PmStorageConstructionPlanMapper pmStorageConstructionPlanMapper;

    @Autowired
    private AuditRequestMapper auditRequestMapper;

    @Autowired
    private AuditRecordMapper auditRecordMapper;

    @Override
    public Page<PmStorageConstruction> page(PmStorageConstructionPageParam pmStorageConstructionPageParam) {
        QueryWrapper<PmStorageConstruction> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(pmStorageConstructionPageParam.getProjectName())) {
            queryWrapper.like("project_name", pmStorageConstructionPageParam.getProjectName());
        }
        if (ObjectUtil.isAllNotEmpty(pmStorageConstructionPageParam.getSortField(), pmStorageConstructionPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(pmStorageConstructionPageParam.getSortOrder());
            queryWrapper.orderBy(true, pmStorageConstructionPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(pmStorageConstructionPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByDesc(PmStorageConstruction::getCreateTime);
        }
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(PmStorageConstructionAddParam pmStorageConstructionAddParam) {
        PmStorageConstruction pmStorageConstruction = BeanUtil.toBean(pmStorageConstructionAddParam, PmStorageConstruction.class);
        sequenceNumbers.putIfAbsent("CCSSJS", 0);
        // 增加当前货位的顺序号，并在达到最大值时重置为0
        int sequenceNumber = (sequenceNumbers.get("CCSSJS") + 1) % MAX_SEQUENCE_NUMBER;
        sequenceNumbers.put("CCSSJS", sequenceNumber);
        // 确保顺序号是4位数
        String formattedSequenceNumber = String.format("%04d", sequenceNumber);
        // 获取当前日期并格式化为yyyyMMdd
        String currentDate = LocalDate.now().format(DATE_FORMATTER);
        // 合并、日期和顺序号
        String projectCode = "CCSSJS" + currentDate + formattedSequenceNumber;

        pmStorageConstruction.setProjectCode(projectCode);
        this.save(pmStorageConstruction);

        //添加进度计划
        List<PmStorageConstructionPlan> pmStorageConstructionPlanList = pmStorageConstructionAddParam.getPmStorageConstructionPlanList();
        for (PmStorageConstructionPlan pmStorageConstructionPlan : pmStorageConstructionPlanList) {
            pmStorageConstructionPlan.setPmStorageConstructionId(pmStorageConstruction.getId());
            pmStorageConstructionPlanMapper.insert(pmStorageConstructionPlan);
        }

        //添加申报资料
        List<PmStorageConstructionFile> pmStorageConstructionFileList = pmStorageConstructionAddParam.getPmStorageConstructionFileList();
        for (PmStorageConstructionFile pmStorageConstructionFile : pmStorageConstructionFileList) {
            pmStorageConstructionFile.setPmStorageConstructionId(pmStorageConstruction.getId());
            pmStorageConstructionFileMapper.insert(pmStorageConstructionFile);
        }

        if (pmStorageConstructionAddParam.getStatus() == 1) {
            //提交审核申请
            AuditRequest auditRequest = new AuditRequest();
            auditRequest.setType(9);
            auditRequest.setStep(1);
            auditRequest.setRequestId(pmStorageConstruction.getId());
            auditRequest.setAuditStatus(0);
            auditRequest.setCreateTime(new Date());
            if (auditRequestMapper.insert(auditRequest) == 0) {
                throw new RuntimeException("保存申请审核失败");
            }
            //保存申请记录
            AuditRecord auditRecord = new AuditRecord();
            auditRecord.setAuditRequestId(auditRequest.getId());
            auditRecord.setStep(auditRequest.getStep());
            auditRecord.setType(auditRequest.getType());
            auditRecord.setRequestId(pmStorageConstruction.getId()); //申请id
            auditRecord.setAuditStatus(auditRequest.getAuditStatus());
            auditRecord.setAuditAdvice(auditRequest.getAuditAdvice());
            auditRecord.setCreateTime(new Date());

            if (auditRecordMapper.insert(auditRecord) == 0) {
                throw new RuntimeException("保存审核记录失败");
            }
        }

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(PmStorageConstructionEditParam pmStorageConstructionEditParam) {


        PmStorageConstruction pmStorageConstruction = this.queryEntity(pmStorageConstructionEditParam.getId());
        BeanUtil.copyProperties(pmStorageConstructionEditParam, pmStorageConstruction);
        this.updateById(pmStorageConstruction);

        //先删除
        pmStorageConstructionPlanMapper.delete(Wrappers.lambdaQuery(PmStorageConstructionPlan.class)
                .in(PmStorageConstructionPlan::getPmStorageConstructionId, pmStorageConstruction.getId()));
        pmStorageConstructionFileMapper.delete(Wrappers.lambdaQuery(PmStorageConstructionFile.class)
                .in(PmStorageConstructionFile::getPmStorageConstructionId, pmStorageConstruction.getId()));

        //保存
        //添加进度计划
        List<PmStorageConstructionPlan> pmStorageConstructionPlanList = pmStorageConstructionEditParam.getPmStorageConstructionPlanList();
        for (PmStorageConstructionPlan pmStorageConstructionPlan : pmStorageConstructionPlanList) {
            pmStorageConstructionPlan.setPmStorageConstructionId(pmStorageConstruction.getId());
            pmStorageConstructionPlanMapper.insert(pmStorageConstructionPlan);
        }

        //添加申报资料
        List<PmStorageConstructionFile> pmStorageConstructionFileList = pmStorageConstructionEditParam.getPmStorageConstructionFileList();
        for (PmStorageConstructionFile pmStorageConstructionFile : pmStorageConstructionFileList) {
            pmStorageConstructionFile.setPmStorageConstructionId(pmStorageConstruction.getId());
            pmStorageConstructionFileMapper.insert(pmStorageConstructionFile);
        }

        //数据维护完成提交至市州审核
        if (pmStorageConstructionEditParam.getStatus() == 1) {
            AuditRequest auditRequest1 = auditRequestMapper.selectOne(Wrappers.lambdaQuery(AuditRequest.class)
                    .eq(AuditRequest::getRequestId, pmStorageConstructionEditParam.getId()));

            if (ObjectUtils.isEmpty(auditRequest1)) {
                AuditRequest auditRequest = new AuditRequest();
                //提交审核申请
                auditRequest.setType(9);
                auditRequest.setStep(1);
                auditRequest.setRequestId(pmStorageConstructionEditParam.getId());
                auditRequest.setAuditStatus(0);
                auditRequest.setCreateTime(new Date());
                if (auditRequestMapper.insert(auditRequest) == 0) {
                    throw new RuntimeException("保存申请审核失败");
                }
                //保存申请记录
                AuditRecord auditRecord = new AuditRecord();
                auditRecord.setAuditRequestId(auditRequest.getId());
                auditRecord.setStep(auditRequest.getStep());
                auditRecord.setType(auditRequest.getType());
                auditRecord.setRequestId(pmStorageConstructionEditParam.getId()); //申请id
                auditRecord.setAuditStatus(auditRequest.getAuditStatus());
                auditRecord.setAuditAdvice(auditRequest.getAuditAdvice());
                auditRecord.setCreateTime(new Date());

                if (auditRecordMapper.insert(auditRecord) == 0) {
                    throw new RuntimeException("保存审核记录失败");
                }
            } else {

                //有数据，就更新状态
                auditRequestMapper.update(null, Wrappers.lambdaUpdate(AuditRequest.class)
                        .eq(AuditRequest::getRequestId, pmStorageConstructionEditParam.getId())
                        .set(AuditRequest::getAuditStatus, 0));

                //保存申请记录
                AuditRecord auditRecord = new AuditRecord();
                auditRecord.setAuditRequestId(auditRequest1.getId());
                auditRecord.setStep(auditRequest1.getStep());
                auditRecord.setType(auditRequest1.getType());
                auditRecord.setRequestId(pmStorageConstructionEditParam.getId()); //申请id
                auditRecord.setAuditStatus(auditRequest1.getAuditStatus());
                auditRecord.setAuditAdvice(auditRequest1.getAuditAdvice());
                auditRecord.setCreateTime(new Date());

                if (auditRecordMapper.insert(auditRecord) == 0) {
                    throw new RuntimeException("保存审核记录失败");
                }

            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<PmStorageConstructionIdParam> pmStorageConstructionIdParamList) {

        //提交的数据不删除

        //先删除进度计划和申报资料
        PmStorageConstruction pmStorageConstruction = this.queryEntity(pmStorageConstructionIdParamList.get(0).getId());
        if (pmStorageConstruction.getStatus() == 1) {
            throw new CommonException("数据正在申报中，不能删除");
        }

        pmStorageConstructionPlanMapper.delete(Wrappers.lambdaQuery(PmStorageConstructionPlan.class)
                .in(PmStorageConstructionPlan::getPmStorageConstructionId, pmStorageConstruction.getId()));
        pmStorageConstructionFileMapper.delete(Wrappers.lambdaQuery(PmStorageConstructionFile.class)
                .in(PmStorageConstructionFile::getPmStorageConstructionId, pmStorageConstruction.getId()));

        // 执行删除
        this.removeByIds(CollStreamUtil.toList(pmStorageConstructionIdParamList, PmStorageConstructionIdParam::getId));
    }

    @Override
    public JSONObject detail(PmStorageConstructionIdParam pmStorageConstructionIdParam) {

        JSONObject jsonObject = new JSONObject();

        //添加基本信息
        PmStorageConstruction pmStorageConstruction = this.queryEntity(pmStorageConstructionIdParam.getId());
        jsonObject.put("pmStorageConstruction", pmStorageConstruction);

        //添加进度计划
        List<PmStorageConstructionPlan> pmStorageConstructionPlanList = pmStorageConstructionPlanMapper.selectList(Wrappers.lambdaQuery(PmStorageConstructionPlan.class)
                .eq(PmStorageConstructionPlan::getPmStorageConstructionId, pmStorageConstruction.getId()));
        jsonObject.put("pmStorageConstructionPlanList", pmStorageConstructionPlanList);

        //添加申报资料
        List<PmStorageConstructionFile> pmStorageConstructionFileList = pmStorageConstructionFileMapper.selectList(Wrappers.lambdaQuery(PmStorageConstructionFile.class)
                .eq(PmStorageConstructionFile::getPmStorageConstructionId, pmStorageConstruction.getId()));
        jsonObject.put("pmStorageConstructionFileList", pmStorageConstructionFileList);

        return jsonObject;
    }

    @Override
    public PmStorageConstruction queryEntity(String id) {
        PmStorageConstruction pmStorageConstruction = this.getById(id);
        if (ObjectUtil.isEmpty(pmStorageConstruction)) {
            throw new CommonException("仓储设施投资-仓储设施建设表不存在，id值为：{}", id);
        }
        return pmStorageConstruction;
    }

    /**
     * 获取仓储设施投资-申报
     *
     * @author hjc
     * @date 2024/05/30 15:58
     */
    @Override
    public void declare(PmStorageConstructionDeclareParam declareParam) {
        PmStorageConstruction pmStorageConstruction = this.queryEntity(declareParam.getId());
        if (pmStorageConstruction.getStatus() == 3) {
            throw new CommonException("此数据已批复，不能进行申报");
        }
        //状态是0保存时，才可以进行申报
        pmStorageConstruction.setStatus(declareParam.getStatus());

        this.updateById(pmStorageConstruction);

    }
}
