package com.engine.secret.instance;

import cn.hutool.core.convert.Convert;
import com.engine.secret.entity.autonumber.AcceptanceNumber;
import com.engine.secret.exception.CustomizeRunTimeException;
import com.engine.secret.util.ModeUtil;
import weaver.common.DateUtil;
import weaver.conn.RecordSetTrans;
import weaver.formmode.IgnoreCaseHashMap;
import weaver.general.Util;
import weaver.hrm.User;

import java.time.LocalDate;
import java.util.Map;
import java.util.UUID;

/**
 * @author:dxfeng
 * @createTime: 2025/04/16
 * @version: 1.0
 */
public class AutoGenerateNumberInstance {
    private static final String TABLE_NAME = "uf_sldh";
    private static final String RECORD_TABLE_NAME = "uf_sldh_dt1";

    private static final AutoGenerateNumberInstance INSTANCE = new AutoGenerateNumberInstance();

    private AutoGenerateNumberInstance() {
        // 私有化构造方法
    }

    public static AutoGenerateNumberInstance getInstance() {
        return INSTANCE;
    }

    /**
     * 集成、印制受理编号
     *
     * @param param
     * @return
     */
    public synchronized String getAcceptanceNumber(User user, Map<String, Object> param) {
        RecordSetTrans rs = new RecordSetTrans();
        rs.setAutoCommit(false);
        try {
            Integer secretType = Convert.toInt(param.get("secretType"));
            String requestId = Util.null2String(param.get("requestId"));

            LocalDate now = LocalDate.now();
            int year = now.getYear();
            int currentMonth = now.getMonthValue();


            AcceptanceNumber yearNumber;
            rs.executeQuery("select * from uf_sldh where secret_type= ? and year = ? and month = 0 FOR UPDATE", secretType, year);
            if (rs.next()) {
                yearNumber = getSelectNum(rs);
            } else {
                yearNumber = buildNewNum(year, 0, secretType);
            }
            yearNumber.setGlobalSerial(yearNumber.getGlobalSerial() + 1);
            // 更新年度流水号
            saveNum(rs, yearNumber);

            AcceptanceNumber monthNumber;
            rs.executeQuery("select * from uf_sldh where secret_type= ? and year = ? and month = ? FOR UPDATE", secretType, year, currentMonth);
            if (rs.next()) {
                monthNumber = getSelectNum(rs);
            } else {
                monthNumber = buildNewNum(year, currentMonth, secretType);
            }
            monthNumber.setMonthlySerial(monthNumber.getMonthlySerial() + 1);
            // 更新月度、流水号
            saveNum(rs, monthNumber);

            // 生成编号
            String formattedYear = String.format("%04d", year);
            String formattedMonth = String.format("%02d", monthNumber.getMonth());
            String formattedMonthlySerial = String.format("%02d", monthNumber.getMonthlySerial());
            String formattedGlobalSerial = String.format("%03d", yearNumber.getGlobalSerial());

            String num = formattedYear + formattedMonth + formattedMonthlySerial + formattedGlobalSerial;
            rs.writeLog("requestId===" + requestId + ",secretType===" + secretType + ",num===" + num);
            insertGenerateRecord(rs, requestId, num, user.getUID());
            // 插入编号生成记录
            rs.commit();
            return num;
        } catch (Exception e) {
            rs.rollback();
            rs.writeLog(e);
            throw new CustomizeRunTimeException(e.getMessage());
        }
    }

    /**
     * 军工受理单号
     *
     * @param param
     * @return
     */
    public synchronized String getWarIndustryAcceptanceNumber(User user, Map<String, Object> param) {
        RecordSetTrans rs = new RecordSetTrans();
        rs.setAutoCommit(false);
        try {
            Integer secretType = Convert.toInt(param.get("secretType"));
            String requestId = Util.null2String(param.get("requestId"));

            LocalDate now = LocalDate.now();
            int year = now.getYear();


            AcceptanceNumber yearNumber;
            rs.executeQuery("select * from uf_sldh where secret_type= ? and year = ? and month = 0 FOR UPDATE", secretType, year);
            if (rs.next()) {
                yearNumber = getSelectNum(rs);
            } else {
                yearNumber = buildNewNum(year, 0, secretType);
            }
            yearNumber.setGlobalSerial(yearNumber.getGlobalSerial() + 1);
            // 更新年度流水号
            saveNum(rs, yearNumber);

            // 生成编号
            String formattedYear = String.format("%04d", year);
            String formattedGlobalSerial = String.format("%03d", yearNumber.getGlobalSerial());

            String num = "JS" + formattedYear + formattedGlobalSerial;
            rs.writeLog("requestId===" + requestId + ",secretType===" + secretType + ",num===" + num);
            insertGenerateRecord(rs, requestId, num, user.getUID());
            rs.commit();
            return num;
        } catch (Exception e) {
            rs.rollback();
            rs.writeLog(e);
            throw new CustomizeRunTimeException(e.getMessage());
        }
    }

    /**
     * 构建查询对象
     *
     * @param rs
     * @return
     */
    private AcceptanceNumber getSelectNum(RecordSetTrans rs) {
        return AcceptanceNumber.builder()
                .id(rs.getInt("id"))
                .year(rs.getInt("year"))
                .month(rs.getInt("month"))
                .monthlySerial(rs.getInt("monthly_serial"))
                .globalSerial(rs.getInt("global_serial"))
                .secretType(rs.getInt("secret_type"))
                .build();
    }

    /**
     * 构建新对象
     *
     * @param year
     * @param currentMonth
     * @param secretType
     * @return
     */
    private AcceptanceNumber buildNewNum(Integer year, Integer currentMonth, Integer secretType) {
        return AcceptanceNumber.builder()
                .year(year)
                .month(currentMonth)
                .monthlySerial(0)
                .globalSerial(0)
                .secretType(secretType)
                .build();
    }

    /**
     * 保存编号数据
     *
     * @param rs
     * @param number
     * @throws Exception
     */
    private void saveNum(RecordSetTrans rs, AcceptanceNumber number) throws Exception {
        if (null == number.getId()) {
            Map<String, Object> insertMap = buildSaveMap(number);
            String uuid = UUID.randomUUID().toString();
            insertMap.put("modeuuid", uuid);
            int formModeId = ModeUtil.getModeIdByTableName(TABLE_NAME);
            insertMap.put("formmodeid", formModeId);
            ModeUtil.buildModeInsertFields(insertMap, 1);
            ModeUtil.insertData(rs, insertMap, TABLE_NAME);
            ModeUtil.refreshRight(uuid, TABLE_NAME, formModeId, 1);
        } else {
            Map<String, Object> updateMap = buildSaveMap(number);
            ModeUtil.buildModeUpdateFields(updateMap, 1);
            ModeUtil.updateDataById(rs, updateMap, TABLE_NAME);
        }

    }

    /**
     * 构建数据库映射关系
     *
     * @param number
     * @return
     */
    private IgnoreCaseHashMap<String, Object> buildSaveMap(AcceptanceNumber number) {
        IgnoreCaseHashMap<String, Object> dataMap = new IgnoreCaseHashMap<>();
        if (null != number.getId()) {
            dataMap.put("id", number.getId());
        }
        dataMap.put("year", number.getYear());
        dataMap.put("month", number.getMonth());
        dataMap.put("monthly_serial", number.getMonthlySerial());
        dataMap.put("global_serial", number.getGlobalSerial());
        dataMap.put("secret_type", number.getSecretType());
        return dataMap;
    }

    /**
     * 插入编号生成记录
     *
     * @param requestId
     * @param num
     * @param userId
     */
    private void insertGenerateRecord(RecordSetTrans rs, String requestId, String num, int userId) throws Exception {
        IgnoreCaseHashMap<String, Object> dataMap = new IgnoreCaseHashMap<>();
        dataMap.put("request_id", requestId);
        dataMap.put("num", num);
        dataMap.put("operate_user", userId);
        dataMap.put("operate_time", DateUtil.getFullDate());
        ModeUtil.insertData(rs, dataMap, RECORD_TABLE_NAME);

    }
}
