/*
 * 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.pmApplication.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.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.basic.info.modular.unitInfo.entity.BasicEnum;
import com.unis.basic.info.modular.unitInfo.mapper.EnumMapper;
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.pmApplication.vo.ConstructionLocationVo;
import org.jetbrains.annotations.Nullable;
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.pmApplication.entity.PmApplication;
import com.unis.projectManagement.modular.pmApplication.mapper.PmApplicationMapper;
import com.unis.projectManagement.modular.pmApplication.param.PmApplicationAddParam;
import com.unis.projectManagement.modular.pmApplication.param.PmApplicationEditParam;
import com.unis.projectManagement.modular.pmApplication.param.PmApplicationIdParam;
import com.unis.projectManagement.modular.pmApplication.param.PmApplicationPageParam;
import com.unis.projectManagement.modular.pmApplication.service.PmApplicationService;

import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 项目申报管理表Service接口实现类
 *
 * @author hjc
 * @date 2024/05/27 17:26
 **/
@Service
public class PmApplicationServiceImpl extends ServiceImpl<PmApplicationMapper, PmApplication> implements PmApplicationService {

    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 PmApplicationMapper pmApplicationMapper;

    @Autowired
    private EnumMapper enumMapper;

    @Autowired
    private AuditRequestMapper auditRequestMapper;

    @Autowired
    private AuditRecordMapper auditRecordMapper;

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

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(PmApplicationAddParam pmApplicationAddParam) {

        if (pmApplicationAddParam.getLegalRepresentativeIdNumber().length() != 18) {
            throw new CommonException("证照号码格式输入错误，请重新输入");
        }
        PmApplication DBpmApplication = pmApplicationMapper.selectOne(Wrappers.lambdaQuery(PmApplication.class)
                .eq(PmApplication::getLegalRepresentativeIdNumber, pmApplicationAddParam.getLegalRepresentativeIdNumber()));
        if (ObjectUtil.isNotEmpty(DBpmApplication)) {
            throw new CommonException("证照号码重复，请重新输入");
        }
        PmApplication pmApplication = BeanUtil.toBean(pmApplicationAddParam, PmApplication.class);

        sequenceNumbers.putIfAbsent("XMSB", 0);
        // 增加当前货位的顺序号，并在达到最大值时重置为0
        int sequenceNumber = (sequenceNumbers.get("XMSB") + 1) % MAX_SEQUENCE_NUMBER;
        sequenceNumbers.put("XMSB", sequenceNumber);
        // 确保顺序号是4位数
        String formattedSequenceNumber = String.format("%04d", sequenceNumber);
        // 获取当前日期并格式化为yyyyMMdd
        String currentDate = LocalDate.now().format(DATE_FORMATTER);
        // 合并、日期和顺序号
        String projectCode = "XMSB" + currentDate + formattedSequenceNumber;

        pmApplication.setProjectCode(projectCode);


        try {
            this.save(pmApplication);
        } catch (Exception e) {
            log.error("新增数据失败:{}", e);
            throw new CommonException("项目申报管理保存失败");

        }

        //数据维护完成 提交审核
        if (pmApplicationAddParam.getStatus() == 1) {
            //提交审核申请
            AuditRequest auditRequest = new AuditRequest();
            auditRequest.setType(6);
            auditRequest.setStep(1);
            auditRequest.setRequestId(pmApplication.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(pmApplication.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(PmApplicationEditParam pmApplicationEditParam) {
        if (pmApplicationEditParam.getLegalRepresentativeIdNumber().length() != 18) {
            throw new CommonException("证照号码格式输入错误，请重新输入");
        }
        PmApplication DBpmApplication = pmApplicationMapper.selectOne(Wrappers.lambdaQuery(PmApplication.class)
                .eq(PmApplication::getLegalRepresentativeIdNumber, pmApplicationEditParam.getLegalRepresentativeIdNumber()));
        if (ObjectUtil.isNotEmpty(DBpmApplication) && !Objects.equals(pmApplicationEditParam.getId(), DBpmApplication.getId())) {
            throw new CommonException("证照号码重复，请重新输入");
        }

        PmApplication pmApplication = this.queryEntity(pmApplicationEditParam.getId());
        BeanUtil.copyProperties(pmApplicationEditParam, pmApplication);
        try {
            this.updateById(pmApplication);
        } catch (Exception e) {
            log.error("项目申报管理修改失败：{}", e);
            throw new CommonException("项目申报管理修改失败");
        }

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

            if (ObjectUtils.isEmpty(auditRequest1)) {
                AuditRequest auditRequest = new AuditRequest();
                //提交审核申请
                auditRequest.setType(6);
                auditRequest.setStep(1);
                auditRequest.setRequestId(pmApplicationEditParam.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(pmApplicationEditParam.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, pmApplicationEditParam.getId())
                        .set(AuditRequest::getAuditStatus, 0));

                //保存申请记录
                AuditRecord auditRecord = new AuditRecord();
                auditRecord.setAuditRequestId(auditRequest1.getId());
                auditRecord.setStep(auditRequest1.getStep());
                auditRecord.setType(auditRequest1.getType());
                auditRecord.setRequestId(pmApplicationEditParam.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<PmApplicationIdParam> pmApplicationIdParamList) {
        PmApplication pmApplication = this.queryEntity(pmApplicationIdParamList.get(0).getId());
        if (pmApplication.getStatus() == 1) {
            throw new CommonException("该数据正在审批中，不能进行删除");
        }

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

    @Override
    public PmApplication detail(PmApplicationIdParam pmApplicationIdParam) {


        PmApplication pmApplication = this.queryEntity(pmApplicationIdParam.getId());
        //设置省
        if (StringUtils.isNotEmpty(pmApplication.getConstructionLocationProvince())) {
            BasicEnum province = enumMapper.selectById(pmApplication.getConstructionLocationProvince());
            if (ObjectUtils.isNotEmpty(province)) {
                pmApplication.setConstructionLocationProvinceName(province.getDictLabel());
            }
        }
        //设置市
        if (StringUtils.isNotEmpty(pmApplication.getConstructionLocationCity())) {
            BasicEnum city = enumMapper.selectById(pmApplication.getConstructionLocationCity());
            if (ObjectUtils.isNotEmpty(city)) {
                pmApplication.setConstructionLocationCityName(city.getDictLabel());
            }

        }
        //设置区
        if (StringUtils.isNotEmpty(pmApplication.getConstructionLocationDistrict())) {
            BasicEnum district = enumMapper.selectById(pmApplication.getConstructionLocationDistrict());
            if (ObjectUtils.isNotEmpty(district)){
                pmApplication.setConstructionLocationDistrictName(district.getDictLabel());
            }

        }

        return pmApplication;
    }

    @Override
    public PmApplication queryEntity(String id) {
        PmApplication pmApplication = this.getById(id);
        if (ObjectUtil.isEmpty(pmApplication)) {
            throw new CommonException("项目申报管理表不存在，id值为：{}", id);
        }
        return pmApplication;
    }

}
