package com.imdroid.beidou_ehm.task;

import com.imdroid.beidou_ehm.service.WarningService;
import com.imdroid.beidou_ehm.simcard.*;
import com.imdroid.common.util.ThreadManager;
import com.imdroid.secapi.dto.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

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

@Component
@Configuration
@EnableScheduling
public class SimStatusChecker {
    //    SIM 卡流量和状态查询定时任务
    //    1. 每小时任务
    //        a. 通过 CardInfo 检查 iccid 和 sim卡号
    //        b. 通过 QueryCardStatus 检查SIM卡当前的状态
    //    2. 每两小时任务
    //        a. QueryGprs 检查 SIM 流量
    final Logger logger = LoggerFactory.getLogger(SimStatusChecker.class);

    @Autowired
    private GnssStatusMapper gnssStatusMapper;

    @Autowired
    private GnssDeviceMapper deviceMapper;

    @Autowired
    private TrafficCardMapper trafficCardMapper;

    @Autowired
    private TrafficRecordMapper trafficRecordMapper;

    @Autowired
    private WarningService warningService;

    @Autowired
    private TrafficCardService trafficCardService;

    @Autowired
    private SimCardQueryServiceImpl simCardQueryServiceImpl;

    // 每小时执行一次状态检查调度
    @Scheduled(cron = "0 0 * * * ?")
    private void scheduleSimCardStatusCheck() {
        List<GnssStatusJoin> onlineDevices = gnssStatusMapper.queryOnline();
        // logger.debug("当前在线设备数量: {}", onlineDevices.size());
        for (GnssStatusJoin onlineDevice : onlineDevices) {
            int delay = Math.abs(onlineDevice.getDeviceid().hashCode() % 3600 );
            //logger.debug("- 设备: {}, SIM状态查询，延迟执行: {}秒", onlineDevice.getDeviceid(), delay);

            ThreadManager.getScheduledThreadPool().schedule(
                    () -> checkDeviceSimCardStatus(onlineDevice),
                    delay,
                    TimeUnit.SECONDS
            );
        }
    }

    // 每两小时执行一次流量检查调度
    @Scheduled(cron = "0 0 0/2 * * ?")
    private void scheduleSimCardTrafficCheck() {
        List<GnssStatusJoin> onlineDevices = gnssStatusMapper.queryOnline();
        logger.debug("当前在线设备数量: {}", onlineDevices.size());

        for (GnssStatusJoin onlineDevice : onlineDevices) {
            int delay = Math.abs(onlineDevice.getDeviceid().hashCode() % 7200);
            //logger.debug("- 设备: {}, SIM流量查询，延迟执行: {}秒", onlineDevice.getDeviceid(), delay);

            ThreadManager.getScheduledThreadPool().schedule(
                    () -> checkDeviceSimCardTraffic(onlineDevice),
                    delay,
                    TimeUnit.SECONDS
            );
        }
    }

    private void checkDeviceSimCardStatus(GnssStatusJoin device) {
        try {
            if (!simCardQueryServiceImpl.hasValidIccid(device)) {
                return;
            }
            boolean iccidChanged = trafficCardService.checkAndHandleICCIDChanges(device);
            if (iccidChanged) {
                logger.info("设备 {} ICCID变更已处理: {}", device.getDeviceid(), device.getIccid());
            }

            TrafficCard trafficCard = trafficCardService.getOrCreateTrafficCard(device.getIccid());

            // 如果 MSISDN 为空，说明是首次创建的记录，要先去查询基本信息
            if (trafficCard.getMsisdn() == null || trafficCard.getMsisdn().isEmpty()) {
                updateTrafficCardBasicInfoFromAPI(device, trafficCard);
            }

            // 查询SIM卡状态
            updateTrafficCardStatusFromAPI(device, trafficCard);

        } catch (Exception e) {
            logger.error("设备{}状态查询失败: ", device.getDeviceid(), e);
        }
    }

    private void checkDeviceSimCardTraffic(GnssStatusJoin device) {
        try {
            if (!simCardQueryServiceImpl.hasValidIccid(device)) {
                return;
            }

            TrafficCard trafficCard = trafficCardService.getOrCreateTrafficCard(device.getIccid());

            // 检查查询状态，如果已标记为非当前卡商或查询失败，则跳过
            if (trafficCard.getQuerystatus() != null &&
                    trafficCard.getQuerystatus() != TrafficCard.QUERY_STATUS_NORMAL) {
                logger.debug("设备 {} 的SIM卡 {} 查询状态为 {}，跳过流量查询",
                        device.getDeviceid(),
                        device.getIccid(),
                        trafficCard.getQuerystatus());
                return;
            }

            // 如果该卡状态不是已激活，跳过流量查询
            if(trafficCard.getStatus() != TrafficCard.STATUS_ACTIVATED) {
                logger.debug("设备 {} 的SIM卡 {} 状态为 {}，跳过流量查询",
                        device.getDeviceid(),
                        device.getIccid(),
                        trafficCard.getStatus());
                return;
            }

            // 查询流量信息
            try {
                updateTrafficCardTrafficFromAPI(device, trafficCard);
            } catch (Exception e) {
                // 如果查询失败，标记为查询失败状态
                if (e.getMessage() != null && e.getMessage().contains("不属于当前卡商")) {
                    trafficCardService.markCardAsNotCurrentVendor(device.getIccid());
                } else {
                    trafficCardService.markCardAsQueryFailed(device.getIccid());
                }
                throw e;
            }

        } catch (Exception e) {
            logger.error("设备{}流量查询失败: ", device.getDeviceid(), e);
        }
    }

    private void updateTrafficCardBasicInfoFromAPI(GnssStatusJoin device, TrafficCard trafficCard) {
        try {
            BaseResponse<CardInfoData> response = simCardQueryServiceImpl.queryCardInfo(device);
            if (response == null || response.getStatus() != 1 || response.getData() == null) {
                logger.warn("设备 {} 的SIM卡基本信息查询失败: {}",
                        device.getDeviceid(),
                        response != null ? response.getMessage() : "无响应");
                return;
            }

            CardInfoData info = response.getData();
            trafficCard.setUpdatetime(new Date());
            trafficCard.setMsisdn(info.getMsisdn());
            trafficCardMapper.updateCardInfo(trafficCard);

            logger.debug("更新SIM卡基本信息 - imsi: {}, msisdn: {}, iccid: {}",
                    info.getImsi(), info.getMsisdn(), info.getIccid());
        } catch (Exception e) {
            logger.error("更新设备{}的SIM卡基本信息失败: ", device.getDeviceid(), e);
            throw e;
        }
    }

    private void updateTrafficCardStatusFromAPI(GnssStatusJoin device, TrafficCard trafficCard) {
        try {
            BaseResponse<CardStatusData> response = simCardQueryServiceImpl.queryCardStatus(device);
            if (response == null ||  response.getStatus() != 1 || response.getData() == null) {
                logger.warn("设备 {} 的SIM卡状态查询失败: {}",
                        device.getDeviceid(),
                        response != null ? response.getMessage() : "无响应");
                return;
            }

            CardStatusData status = response.getData();
            trafficCard.setUpdatetime(new Date());
            trafficCard.setStatus(status.getStatusCode());
            trafficCardMapper.updateCardInfo(trafficCard);

            checkTrafficCardStatus(device, trafficCard);

            logger.debug("更新SIM卡状态 - Code: {}, 描述: {}",
                    status.getStatusCode(), status.getStatusDesc());
        } catch (Exception e) {
            logger.error("更新设备{}的SIM卡状态失败: ", device.getDeviceid(), e);
        }
    }

    private void updateTrafficCardTrafficFromAPI(GnssStatusJoin device, TrafficCard trafficCard) {
        try {
            BaseResponse<GprsData> response = simCardQueryServiceImpl.queryGprs(device);
            if (response == null || response.getStatus() != 1 || response.getData() == null) {
                logger.warn("设备 {} 的SIM卡流量查询失败: {}",
                        device.getDeviceid(),
                        response != null ? response.getMessage() : "无响应");
                return;
            }

            GprsData gprsData = response.getData();
            GprsData.GprsUsage usage = gprsData.getFirstGprsUsage();
            if (usage == null) {
                logger.warn("无可用流量数据查询, deviceId: {}", device.getDeviceid());
                return;
            }

            trafficCard.setUpdatetime(new Date());
            // 将浮点数转换为整数存储（MB值×1000）
            trafficCard.setRemaining((int)(usage.getLeft() * 1000));
            trafficCard.setUsed((int)(usage.getUsed() * 1000));
            trafficCard.setTotal((int)(usage.getTotal() * 1000));

            trafficCardMapper.updateCardTrafficInfo(trafficCard);

            TrafficRecord record = new TrafficRecord();
            record.setIccid(trafficCard.getIccid());
            record.setRecordtime(new Date());
            record.setRemaining(trafficCard.getRemaining());
            record.setTotal(trafficCard.getTotal());
            record.setUsed(trafficCard.getUsed());
            trafficRecordMapper.insert(record);

            checkTrafficCardTraffic(device, trafficCard);

            logger.debug("更新流量信息成功 - deviceId: {}, 剩余: {}MB, 总量: {}MB, 已用: {}MB",
                    device.getIccid(),
                    trafficCard.getRemaining() / 1000.0,
                    trafficCard.getTotal() / 1000.0,
                    trafficCard.getUsed() / 1000.0);

        } catch (Exception e) {
            logger.error("设备{}更新SIM卡流量失败: ", device.getDeviceid(), e);
            throw e;
        }
    }

    public void checkTrafficCardTraffic(GnssStatusJoin device, TrafficCard trafficCard) {
        GnssStatus status = gnssStatusMapper.getByDeviceId(device.getDeviceid());
        if (status == null) return;

        boolean isUpdated = false;

        // 计算流量使用百分比
        int usedPercentage = 0;
        if (trafficCard.getTotal() > 0) {
            usedPercentage = (int)((trafficCard.getUsed() * 100.0) / trafficCard.getTotal());
        }

        // 检查流量使用情况
        if (warningService.check(status, WarningCfg.TYPE_SIM_LOW_TRAFFIC,
                WarningCfg.TYPE_NAME_SIM_LOW_TRAFFIC,
                false,  // 大于等于流量门限值，那么就报警
                usedPercentage,
                null,
                String.format("流量已使用 %d%%", usedPercentage))) {
            isUpdated = true;
        }

        if (isUpdated) {
            status.setWarning(warningService.getWarningLevel(status.getWarningcode()));
            gnssStatusMapper.updateById(status);
        }
    }

    public void checkTrafficCardStatus(GnssStatusJoin device, TrafficCard trafficCard) {
        GnssStatus status = gnssStatusMapper.getByDeviceId(device.getDeviceid());
        if (status == null) return;

        boolean isUpdated = false;

        // 检查SIM卡状态是否异常（停机、注销、失效）
        if (trafficCard.getStatus() == TrafficCard.STATUS_SUSPENDED ||
                trafficCard.getStatus() == TrafficCard.STATUS_CANCELLED ||
                trafficCard.getStatus() == TrafficCard.STATUS_INVALID) {

            String statusDesc;
            switch(trafficCard.getStatus()) {
                case TrafficCard.STATUS_SUSPENDED:
                    statusDesc = "停机";
                    break;
                case TrafficCard.STATUS_CANCELLED:
                    statusDesc = "注销";
                    break;
                case TrafficCard.STATUS_INVALID:
                    statusDesc = "失效";
                    break;
                default:
                    statusDesc = "未知状态";
            }

            if (warningService.check(status, WarningCfg.TYPE_SIM_STATUS_ABNORMAL,
                    WarningCfg.TYPE_NAME_SIM_STATUS_ABNORMAL, false,
                    trafficCard.getStatus(),
                    null,
                    "SIM卡状态异常: " + statusDesc)) {
                isUpdated = true;
            }
        } else {
            // 清除状态异常告警
            if ((status.getWarningcode() & WarningCfg.TYPE_SIM_STATUS_ABNORMAL) != 0) {
                warningService.clearWarning(status, WarningCfg.TYPE_SIM_STATUS_ABNORMAL);
                isUpdated = true;
            }
        }

        if (isUpdated) {
            status.setWarning(warningService.getWarningLevel(status.getWarningcode()));
            gnssStatusMapper.updateById(status);
        }
    }
}