package com.steerinfo.abnormalHandler.service;

import com.steerinfo.abnormalHandler.mapper.StatusSyncMapper;
import com.steerinfo.meterwork.meterworkcaractualfirst.mapper.MeterWorkCarActualFirstMapper;
import com.steerinfo.meterwork.meterworkcaractualfirst.model.MeterWorkCarActualFirst;
import com.steerinfo.meterwork.meterworkrailwayactfirst.mapper.MeterWorkRailwayActFirstMapper;
import com.steerinfo.meterwork.meterworkrailwayactfirst.model.MeterWorkRailwayActFirst;
import com.steerinfo.pretrack.prerailwayscale.mapper.PreRailwayScaleMapper;
import com.steerinfo.pretrack.prerailwayscale.model.PreRailwayScale;
import com.steerinfo.pretrack.pretrackscale.mapper.PreTrackScaleMapper;
import com.steerinfo.pretrack.pretrackscale.model.PreTrackScale;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
@Slf4j
public class StatusSyncService {

    @Autowired
    private StatusSyncMapper mapper;

    @Autowired
    private MeterWorkCarActualFirstMapper meterWorkCarActualFirstMapper;

    @Autowired
    private PreTrackScaleMapper preTrackScaleMapper;

    @Autowired
    private MeterWorkRailwayActFirstMapper meterWorkRailwayActFirstMapper;

    @Autowired
    private PreRailwayScaleMapper preRailwayScaleMapper;

    public void doSync() {
        long startTime = System.currentTimeMillis();
        log.info("========== 开始执行状态同步 ==========");

        // 1. 汽运分别查询四条规则的数据
        // 首先是一次表状态不对，已经洁净了,但是一次表还是有效,返回的是一次实绩编号
        List<String> carRule1List  = meterWorkCarActualFirstMapper.selectRule1PredictionNos();
        // 其次是预报表状态不对，已经结束使用了,但是预报表还是正使用,返回的是预报编号
        List<String> carRule2List  = meterWorkCarActualFirstMapper.selectRule2PredictionNos();
        // 再次是预报表状态不对，已经正使用了,但是预报表还是未使用,返回的是预报编号
        List<String> carRule3List  = meterWorkCarActualFirstMapper.selectRule3PredictionNos();
        // 最后是预报表状态不对，已经未使用了,但是预报表还是正使用或者已使用,返回的是预报编号
//        List<String> carRule4List  = meterWorkCarActualFirstMapper.selectRule4PredictionNos();
        // 最后后是一次表状态不对，应该是 有效，但是一次表还是已结净,返回的是一次实绩编号
//        List<String> carRule5List  = meterWorkCarActualFirstMapper.selectRule5PredictionNos();

        // 1. 火运分别查询四条规则的数据
        // 首先是一次表状态不对，已经洁净了,但是一次表还是有效,返回的是一次实绩编号
        List<String> trainRule1List  = meterWorkRailwayActFirstMapper.selectRule1PredictionNos();
        // 其次是预报表状态不对，已经结束使用了,但是预报表还是正使用,返回的是预报编号
        List<String> trainRule2List  = meterWorkRailwayActFirstMapper.selectRule2PredictionNos();
        // 再次是预报表状态不对，已经正使用了,但是预报表还是未使用,返回的是预报编号
        List<String> trainRule3List  = meterWorkRailwayActFirstMapper.selectRule3PredictionNos();
        // 最后是预报表状态不对，已经未使用了,但是预报表还是正使用或者已使用,返回的是预报编号
//        List<String> trainRule4List  = meterWorkRailwayActFirstMapper.selectRule4PredictionNos();


        // 2. 日志记录每条规则查到多少条
        // ============================================================
        log.info("【汽运】规则1(一次表 有效→已结净) 查到 {} 条", carRule1List.size());
        log.info("【汽运】规则2(预报表 正使用→已使用) 查到 {} 条", carRule2List.size());
        log.info("【汽运】规则3(预报表 未使用→正使用) 查到 {} 条", carRule3List.size());
//        log.info("【汽运】规则4(预报表 已使用/正使用→未使用) 查到 {} 条", carRule4List.size());
//        log.info("【汽运】规则5(一次表 已结净→有效回退) 查到 {} 条", carRule5List.size());

        log.info("【火运】规则1(一次表 有效→已结净) 查到 {} 条", trainRule1List.size());
        log.info("【火运】规则2(预报表 正使用→已使用) 查到 {} 条", trainRule2List.size());
        log.info("【火运】规则3(预报表 未使用→正使用) 查到 {} 条", trainRule3List.size());
//        log.info("【火运】规则4(预报表 已使用/正使用→未使用) 查到 {} 条", trainRule4List.size());

        // ============================================================
        // 4. 执行更新（每条规则独立处理，互不影响）
        //    - 每个更新方法内部自带 WHERE VALUE_FLAG = '旧值' 校验
        //    - 若状态已被人工修改，影响行数=0，自动跳过
        // ============================================================
        int totalSuccess = 0;
        int totalFail = 0;
        // ---- 汽运规则1：一次表 '有效(1)' → '已结净(2)' ----
        if (!carRule1List.isEmpty()) {
            int[] result = executeUpdates(carRule1List,
                    id -> meterWorkCarActualFirstMapper.updateFirstByRule1(id),
                    "汽运规则1", "一次表 有效→已结净");
            totalSuccess += result[0];
            totalFail += result[1];
        } else {
            log.info("【汽运规则1】无待处理数据，跳过");
        }

        // ---- 汽运规则2：预报表 '正使用(1)' → '已使用(2)' ----
        if (!carRule2List.isEmpty()) {
            int[] result = executeUpdates(carRule2List,
                    id -> meterWorkCarActualFirstMapper.updatePredictionByRule2(id),
                    "汽运规则2", "预报表 正使用→已使用");
            totalSuccess += result[0];
            totalFail += result[1];
        } else {
            log.info("【汽运规则2】无待处理数据，跳过");
        }

        // ---- 汽运规则3：预报表 '未使用(4)' → '正使用(1)' ----
        if (!carRule3List.isEmpty()) {
            int[] result = executeUpdates(carRule3List,
                    id -> meterWorkCarActualFirstMapper.updatePredictionByRule3(id),
                    "汽运规则3", "预报表 未使用→正使用");
            totalSuccess += result[0];
            totalFail += result[1];
        } else {
            log.info("【汽运规则3】无待处理数据，跳过");
        }

//        // ---- 汽运规则4：预报表 '正使用(1)/已使用(2)' → '未使用(4)' ----
//        if (!carRule4List.isEmpty()) {
//            int[] result = executeUpdates(carRule4List,
//                    id -> meterWorkCarActualFirstMapper.updatePredictionByRule4(id),
//                    "汽运规则4", "预报表 已使用/正使用→未使用");
//            totalSuccess += result[0];
//            totalFail += result[1];
//        } else {
//            log.info("【汽运规则4】无待处理数据，跳过");
//        }

        // ---- 汽运规则5：一次表 '已结净(2)' → '有效(1)'（回退） ----
//        if (!carRule5List.isEmpty()) {
//            int[] result = executeUpdates(carRule5List,
//                    id -> meterWorkCarActualFirstMapper.updateFirstByRule5(id),
//                    "汽运规则5", "一次表 已结净→有效(回退)");
//            totalSuccess += result[0];
//            totalFail += result[1];
//        } else {
//            log.info("【汽运规则5】无待处理数据，跳过");
//        }

        // ---- 火运规则1 ----
        if (!trainRule1List.isEmpty()) {
            int[] result = executeUpdates(trainRule1List,
                    id -> meterWorkRailwayActFirstMapper.updateFirstByRule1(id),
                    "火运规则1", "一次表 有效→已结净");
            totalSuccess += result[0];
            totalFail += result[1];
        } else {
            log.info("【火运规则1】无待处理数据，跳过");
        }

        // ---- 火运规则2 ----
        if (!trainRule2List.isEmpty()) {
            int[] result = executeUpdates(trainRule2List,
                    id -> meterWorkRailwayActFirstMapper.updatePredictionByRule2(id),
                    "火运规则2", "预报表 正使用→已使用");
            totalSuccess += result[0];
            totalFail += result[1];
        } else {
            log.info("【火运规则2】无待处理数据，跳过");
        }

        // ---- 火运规则3 ----
        if (!trainRule3List.isEmpty()) {
            int[] result = executeUpdates(trainRule3List,
                    id -> meterWorkRailwayActFirstMapper.updatePredictionByRule3(id),
                    "火运规则3", "预报表 未使用→正使用");
            totalSuccess += result[0];
            totalFail += result[1];
        } else {
            log.info("【火运规则3】无待处理数据，跳过");
        }

        // ---- 火运规则4 ----
//        if (!trainRule4List.isEmpty()) {
//            int[] result = executeUpdates(trainRule4List,
//                    id -> meterWorkRailwayActFirstMapper.updatePredictionByRule4(id),
//                    "火运规则4", "预报表 已使用/正使用→未使用");
//            totalSuccess += result[0];
//            totalFail += result[1];
//        } else {
//            log.info("【火运规则4】无待处理数据，跳过");
//        }

        log.info("========== 状态同步完成，成功 {} 条，失败 {} 条，耗时 {}ms ==========",
                totalSuccess, totalFail, System.currentTimeMillis() - startTime);
    }

    private int[] executeUpdates(List<String> idList, UpdateFunction updateFunc,
                                 String ruleName, String actionDesc) {
        int success = 0;
        int fail = 0;

        for (String id : idList) {
            try {
                int rows = doUpdate(id, updateFunc);
                if (rows > 0) {
                    success++;
                    log.info("[{}生效] ID: {}, {}，影响 {} 行", ruleName, id, actionDesc, rows);
                } else {
                    log.debug("[{}跳过] ID: {}, 状态已变更或条件不满足", ruleName, id);
                }
            } catch (Exception e) {
                fail++;
                log.error("[{}失败] ID: {}, 异常: {}", ruleName, id, e.getMessage(), e);
            }
        }

        log.info("【{}】处理完成: 成功={}, 失败={}", ruleName, success, fail);
        return new int[]{success, fail};
    }

    /**
     * 单条更新（独立事务，超时10秒）
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, timeout = 10)
    public int doUpdate(String id, UpdateFunction updateFunc) {
        return updateFunc.apply(id);
    }

    /**
     * 函数式接口
     */
    @FunctionalInterface
    private interface UpdateFunction {
        int apply(String id);
    }
}
