package com.hdkj.lt.bf.listener;

import com.alibaba.fastjson.JSONObject;
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 com.hdkj.lt.feign.IReconApiClient;
import com.hdkj.lt.modle.vo.recon.ReconstructionParam;
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 客户端 IReconApiClient 调用 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 IReconApiClient reconApiClient;
    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_RUNNING   = 1;
    private static final int RECON_COMPLETED = 2;
    private static final int RECON_NO_PLAN   = 3;
    private static final int RECON_FAILED    = -1;

    @Async
    @EventListener
    public void onReconTrigger(ReconTriggerEvent event) {
        updateReconStatus(event.getEventId(), event.getAlarmType(), RECON_RUNNING);

        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);

        ReconstructionParam param = new ReconstructionParam();
        param.setEventId(String.valueOf(event.getEventId()));
        param.setParams(params);

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

        try {
            String resp = reconApiClient.triggerReconfiguration(param);
            log.info("重构接口调用成功: eventId={}, response={}", event.getEventId(), resp);

            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(String response) {
        if (response == null || response.isEmpty()) return RECON_FAILED;
        try {
            JSONObject root = com.alibaba.fastjson.JSON.parseObject(response);
            String status = root.getString("status");
            if ("200".equals(status) || "success".equalsIgnoreCase(status)) {
                Object data = root.get("data");
                if (data instanceof JSONObject) {
                    Boolean success = ((JSONObject) data).getBoolean("success");
                    return Boolean.TRUE.equals(success) ? RECON_COMPLETED : RECON_NO_PLAN;
                }
            }
        } catch (Exception e) {
            log.warn("解析重构接口响应失败: {}", e.getMessage());
        }
        return RECON_COMPLETED;
    }

    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());
        }
    }
}
