package com.hdkj.lt.bf.listener;

import com.hdkj.hussar.ApiResponse;
import com.hdkj.lt.bf.adapter.SiReconClient;
import com.hdkj.lt.bf.entity.FhzgSeCurrentEvent;
import com.hdkj.lt.bf.entity.FhzgSeVoltageEvent;
import com.hdkj.lt.bf.event.ReconTriggerEvent;
import com.hdkj.lt.bf.mapper.FhzgSeCurrentEventMapper;
import com.hdkj.lt.bf.mapper.FhzgSeVoltageEventMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * 重构算法触发监听器
 * <p>
 * 当线路重过载/电压越限告警持续1小时触发时，异步调用同事编写的重构接口。
 * 通过 Feign 客户端 SiReconClient 调用 SI 模块的 POST /recon/trigger。
 * <p>
 * 调用过程中同步更新告警事件的 reconStatus：
 * <ul>
 *   <li>1 — 重构生成中</li>
 *   <li>2 — 重构完成（有方案）</li>
 *   <li>3 — 重构完成（无方案）</li>
 *   <li>-1 — 调用失败</li>
 * </ul>
 *
 * @author lsl
 * @since 2026-07-25
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ReconTriggerListener {

    private final SiReconClient siReconClient;
    private final FhzgSeCurrentEventMapper currentEventMapper;
    private final FhzgSeVoltageEventMapper voltageEventMapper;

    private static final DateTimeFormatter DT_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /** 重构状态常量 */
    private static final int RECON_PENDING   = 0;  // 未触发
    private static final int RECON_RUNNING   = 1;  // 生成中
    private static final int RECON_COMPLETED = 2;  // 有方案
    private static final int RECON_NO_PLAN   = 3;  // 无方案
    private static final int RECON_FAILED    = -1; // 调用失败

    /**
     * 异步监听：告警持续1h → 触发重构算法
     */
    @Async
    @EventListener
    public void onReconTrigger(ReconTriggerEvent event) {
        // 1. 标记为"生成中"
        updateReconStatus(event.getEventId(), event.getAlarmType(), RECON_RUNNING);

        // 2. 构造请求参数
        Map<String, Object> params = new HashMap<>();
        params.put("feeder_id", event.getFeederId());
        params.put("point_time", event.getPointTime() != null
                ? event.getPointTime().format(DT_FMT) : null);

        Map<String, Object> request = new HashMap<>();
        request.put("eventId", String.valueOf(event.getEventId()));
        request.put("params", params);

        log.info("重构触发: eventId={}, feederId={}, alarmType={}, pointTime={}, request={}",
                event.getEventId(), event.getFeederId(), event.getAlarmType(),
                event.getPointTime(), request);

        // 3. Feign 调用同事接口
        try {
            ApiResponse<Map> resp = siReconClient.triggerRecon(request);
            log.info("重构接口调用成功: eventId={}, response={}", event.getEventId(), resp);

            // 4. 解析响应判断是否有方案
            int status = parseReconResponse(resp);
            updateReconStatus(event.getEventId(), event.getAlarmType(), status);
        } catch (Exception e) {
            log.error("重构接口调用失败: eventId={}, feederId={}, alarmType={}, error={}",
                    event.getEventId(), event.getFeederId(), event.getAlarmType(), e.getMessage(), e);
            updateReconStatus(event.getEventId(), event.getAlarmType(), RECON_FAILED);
        }
    }

    /**
     * 解析同事重构接口响应，判断是否有方案
     */
    private int parseReconResponse(ApiResponse<Map> resp) {
        if (resp == null || !resp.isSuccess()) {
            return RECON_FAILED;
        }
        Map data = resp.getData();
        if (data != null) {
            Object success = data.get("success");
            if (Boolean.TRUE.equals(success)) {
                return RECON_COMPLETED;
            } else if (Boolean.FALSE.equals(success)) {
                return RECON_NO_PLAN;
            }
        }
        // 调通了但没有明确的 success 标记，保守返回"有方案"
        return RECON_COMPLETED;
    }

    /**
     * 根据 alarmType 前缀更新对应告警事件的 reconStatus
     */
    private void updateReconStatus(Long eventId, String alarmType, int reconStatus) {
        if (eventId == null) return;

        try {
            if (alarmType != null && alarmType.startsWith("current_")) {
                FhzgSeCurrentEvent update = new FhzgSeCurrentEvent();
                update.setId(eventId);
                update.setReconStatus(reconStatus);
                currentEventMapper.updateById(update);
            } else if (alarmType != null && alarmType.startsWith("voltage_")) {
                FhzgSeVoltageEvent update = new FhzgSeVoltageEvent();
                update.setId(eventId);
                update.setReconStatus(reconStatus);
                voltageEventMapper.updateById(update);
            }
        } catch (Exception e) {
            log.error("更新告警事件 reconStatus 失败: eventId={}, alarmType={}, status={}, error={}",
                    eventId, alarmType, reconStatus, e.getMessage());
        }
    }
}
