package com.yeejoin.amos.boot.module.jg.biz.data.fix.service;

import cn.hutool.core.date.StopWatch;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yeejoin.amos.boot.biz.common.entity.BaseEntity;
import com.yeejoin.amos.boot.module.common.api.enums.CylinderTypeEnum;
import com.yeejoin.amos.boot.module.jg.api.entity.*;
import com.yeejoin.amos.boot.module.jg.biz.service.impl.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

@Slf4j
@Component
@RequiredArgsConstructor
public class ReceiveOrgFixService {

    private final JgScrapCancelServiceImpl jgScrapCancelService;

    private final JgChangeRegistrationTransferServiceImpl changeRegistrationTransferService;

    private final JgChangeRegistrationUnitServiceImpl changeRegistrationUnitService;

    private final JgChangeRegistrationNameServiceImpl changeRegistrationNameService;

    private final CommonServiceImpl commonService;

    private final JgUseRegistrationManageServiceImpl jgUseRegistrationManageService;

    /**
     * 登记类单据-详情证列表登记机关由监管机构调整到行政审批
     * 数据范围：状态为已完成、已作废
     *
     * @return 刷库数量
     */
    public Integer doFix() {
        StopWatch watch = new StopWatch();
        watch.start("注销报废由监管机构调整到行政审批");
        AtomicReference<Integer> dealNum = new AtomicReference<>(0);
        Map<String, JgUseRegistrationManage> certSeqEnteyMap = new HashMap<>();
        // 注销报废
        List<JgScrapCancel> scrapCancels = jgScrapCancelService.list(new LambdaQueryWrapper<JgScrapCancel>().in(JgScrapCancel::getAuditStatus, Arrays.asList("已完成", "已作废")).select(BaseEntity::getSequenceNbr, JgScrapCancel::getApplyNo));
        scrapCancels.forEach(scrapCancel -> {
            JSONObject jsonObject = commonService.queryHistoryData(scrapCancel.getSequenceNbr());
            String certKey = "";
            if (jsonObject != null) {
                List<JSONObject> certs = new ArrayList<>();
                if (jsonObject.containsKey("cylCertificates")) {
                    certKey = "cylCertificates";
                    certs = JSONArray.parseArray(jsonObject.get(certKey).toString(), JSONObject.class);
                } else if (jsonObject.containsKey("certificates")) {
                    certKey = "certificates";
                    certs = JSONArray.parseArray(jsonObject.get(certKey).toString(), JSONObject.class);
                }
                if (!certs.isEmpty()) {
                    certs.forEach(c -> {
                        JgUseRegistrationManage manage = certSeqEnteyMap.computeIfAbsent(c.getString("sequenceNbr"), jgUseRegistrationManageService::getById);
                        if (manage != null) {
                            c.put("receiveCompanyCode", manage.getReceiveCompanyCode());
                            c.put("receiveOrgName", manage.getReceiveOrgName());
                        }
                    });
                    dealNum.getAndSet(dealNum.get() + 1);
                    jsonObject.put(certKey, certs);
                    commonService.saveOrUpdateHistory(null, jsonObject, null, scrapCancel.getSequenceNbr().toString());
                }
            }
        });
        watch.stop();
        watch.start("移装变更登记由监管机构调整到行政审批");
        // 移装变更登记
        List<JgChangeRegistrationTransfer> changeRegistrationTransfers = changeRegistrationTransferService.list(new LambdaQueryWrapper<JgChangeRegistrationTransfer>().in(JgChangeRegistrationTransfer::getAuditStatus, Arrays.asList("已完成", "已作废")).select(BaseEntity::getSequenceNbr, JgChangeRegistrationTransfer::getApplyNo));
        String registrationTransferCertKey = "registrationList";
        changeRegistrationTransfers.forEach(changeRegistrationTransfer -> {
            JSONObject jsonObject = commonService.queryHistoryData(changeRegistrationTransfer.getApplyNo());
            if (jsonObject != null) {
                if (jsonObject.containsKey(registrationTransferCertKey)) {
                    List<JSONObject> certs = JSONArray.parseArray(jsonObject.get(registrationTransferCertKey).toString(), JSONObject.class);
                    certs.forEach(c -> {
                        JgUseRegistrationManage manage = certSeqEnteyMap.computeIfAbsent(c.getString("sequenceNbr"), jgUseRegistrationManageService::getById);
                        if (manage != null) {
                            c.put("receiveCompanyCode", manage.getReceiveCompanyCode());
                            c.put("receiveOrgName", manage.getReceiveOrgName());
                        }
                    });
                    jsonObject.put(registrationTransferCertKey, certs);
                    dealNum.getAndSet(dealNum.get() + 1);
                    commonService.saveOrUpdateHistory(null, jsonObject, null, changeRegistrationTransfer.getApplyNo());
                }
            }
        });
        watch.stop();
        watch.start("单位变更登记由移装变更登记到行政审批");
        // 单位变更登记
        List<JgChangeRegistrationUnit> registrationUnits = changeRegistrationUnitService.lambdaQuery().in(JgChangeRegistrationUnit::getStatus, Arrays.asList("已完成", "已作废")).select(BaseEntity::getSequenceNbr, JgChangeRegistrationUnit::getApplyNo, JgChangeRegistrationUnit::getEquCategoryCode).list();
        registrationUnits.forEach(registrationUnit -> {
            JSONArray registrationList = commonService.queryHistoryDataObj(registrationUnit.getApplyNo());
            if (!CylinderTypeEnum.CYLINDER.getCode().equals(registrationUnit.getEquCategoryCode())) {
                if (!ValidationUtil.isEmpty(registrationList)) {
                    registrationList.stream().map(obj -> (JSONObject) obj).forEach(c -> {
                        JgUseRegistrationManage manage = certSeqEnteyMap.computeIfAbsent(c.getString("sequenceNbr"), jgUseRegistrationManageService::getById);
                        if (manage != null) {
                            c.put("receiveCompanyCode", manage.getReceiveCompanyCode());
                            c.put("receiveOrgName", manage.getReceiveOrgName());
                        }
                    });
                    dealNum.getAndSet(dealNum.get() + 1);
                    commonService.saveOrUpdateHistory(null, registrationList, null, registrationUnit.getApplyNo());
                }
            }
        });
        watch.stop();
        watch.start("更名变更登记由移装变更登记到行政审批");
        // 更名变更登记
        List<JgChangeRegistrationName> registrationNames = changeRegistrationNameService.lambdaQuery().in(JgChangeRegistrationName::getAuditStatus, Arrays.asList("已完成", "已作废")).select(BaseEntity::getSequenceNbr, JgChangeRegistrationName::getApplyNo).list();
        registrationNames.forEach(registrationName -> {
            JSONObject historyData = commonService.queryHistoryData(registrationName.getSequenceNbr());
            if (historyData != null) {
                JSONObject jgRegistrationInfo = JSONObject.parseObject(historyData.get("jgRegistrationInfo").toString());
                JSONArray certs = jgRegistrationInfo.getJSONArray("dataList");
                certs.stream().map(c -> (JSONObject) c).forEach(c -> {
                    JgUseRegistrationManage manage = certSeqEnteyMap.computeIfAbsent(c.getString("sequenceNbr"), jgUseRegistrationManageService::getById);
                    if (manage != null) {
                        c.put("receiveCompanyCode", manage.getReceiveCompanyCode());
                        c.put("receiveOrgName", manage.getReceiveOrgName());
                    }
                });
                historyData.put("jgRegistrationInfo", jgRegistrationInfo);
                dealNum.getAndSet(dealNum.get() + 1);
                commonService.saveOrUpdateHistory(null, historyData, null, registrationName.getSequenceNbr().toString());
            }
        });
        watch.stop();
        log.info("由移装变更登记到行政审批耗时：{}", watch.prettyPrint(TimeUnit.SECONDS));
        return dealNum.get();
    }
}
