package com.example.demo.service;

import com.example.demo.model.Event;
import com.example.demo.model.TaskDraft;
import com.example.demo.model.TaskTemplate;
import com.example.demo.repository.TaskDraftRepository;
import com.example.demo.repository.TaskTemplateRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

/**
 * 任务生成服务。
 * <p>
 * 实现高价值目标评估后的任务模板匹配与任务草案生成逻辑，
 * 以及任务草案发送与重试机制。
 * </p>
 *
 * @requirement(name="任务模板匹配与生成", id="SRS-EHTG-06")
 * 结合知识库中的任务模板，自动生成符合标准的任务草案。
 *
 * @requirement(name="任务草案发送与重试机制", id="SRS-EHTG-07")
 * 向下游任务规划引擎发送请求，失败时自动加入本地重试队列。
 */
@Service
public class TaskGenerationService {

    private static final Logger log = LoggerFactory.getLogger(TaskGenerationService.class);

    private final TaskTemplateRepository templateRepository;
    private final TaskDraftRepository draftRepository;
    private final EventService eventService;

    public TaskGenerationService(TaskTemplateRepository templateRepository,
                                 TaskDraftRepository draftRepository,
                                 EventService eventService) {
        this.templateRepository = templateRepository;
        this.draftRepository = draftRepository;
        this.eventService = eventService;
    }

    /**
     * 基于事件生成任务草案。
     * <p>
     * 执行流程：
     * 1. 评估目标价值
     * 2. 若为高价值目标，匹配任务模板
     * 3. 填充模板参数生成任务草案
     * 4. 保存草案并返回
     * </p>
     *
     * @param eventId 事件ID
     * @return 生成的任务草案
     * @throws IllegalArgumentException 如果事件不存在或不是高价值目标
     */
    public TaskDraft generateTaskDraft(String eventId) {
        Event event = eventService.getEventById(eventId)
                .orElseThrow(() -> new IllegalArgumentException("事件不存在: " + eventId));

        // 评估目标价值
        double score = eventService.evaluateTargetValue(event);
        if (!eventService.isHighValueTarget(score)) {
            throw new IllegalArgumentException("事件 " + eventId + " 目标价值评分 " + score + "，未达到高价值目标阈值");
        }

        // 匹配任务模板（按目标类型匹配）
        int targetType = event.getSourceType() != null ? event.getSourceType().getCode() : 1;
        List<TaskTemplate> templates = templateRepository.findByTargetType(targetType);
        if (templates.isEmpty()) {
            // 如果没有精确匹配的模板，使用所有启用的模板中的第一个
            templates = templateRepository.findAllActive();
        }
        if (templates.isEmpty()) {
            throw new IllegalStateException("没有可用的任务模板");
        }

        // 选择第一个匹配的模板
        TaskTemplate template = templates.get(0);
        log.info("为事件 {} 匹配到模板: {} (版本 {})", eventId, template.getTemplateName(), template.getVersion());

        // 生成任务草案内容
        String draftContent = generateDraftContent(event, template, score);

        // 创建任务草案
        TaskDraft draft = new TaskDraft();
        draft.setDraftId("DRF-" + UUID.randomUUID().toString().substring(0, 8).toUpperCase());
        draft.setEventId(eventId);
        draft.setTemplateId(template.getTemplateId());
        draft.setTitle(template.getTemplateName() + " - " + event.getEventId());
        draft.setContent(draftContent);
        draft.setTargetValueScore(score);
        draft.setSendStatus(0); // 未发送
        draft.setRetryCount(0);
        draft.setCreateTime(LocalDateTime.now());

        TaskDraft savedDraft = draftRepository.save(draft);
        log.info("任务草案 {} 已生成", savedDraft.getDraftId());

        // 更新事件状态为处理中
        eventService.updateEventStatus(eventId, com.example.demo.model.enums.EventStatus.PROCESSING);

        return savedDraft;
    }

    /**
     * 生成任务草案内容。
     * <p>
     * 根据事件信息和模板生成结构化的任务草案内容（JSON格式）。
     * </p>
     */
    private String generateDraftContent(Event event, TaskTemplate template, double score) {
        return String.format("{" +
                "\"eventId\":\"%s\"," +
                "\"templateId\":\"%s\"," +
                "\"targetValueScore\":%.2f," +
                "\"threatLevel\":\"%s\"," +
                "\"confidence\":%.2f," +
                "\"location\":%s," +
                "\"templateContent\":%s" +
                "}",
                event.getEventId(),
                template.getTemplateId(),
                score,
                event.getThreatLevel() != null ? event.getThreatLevel().name() : "UNKNOWN",
                event.getConfidence(),
                event.getLocation() != null ? event.getLocation() : "\"\"",
                template.getContentXml() != null ? "\"" + template.getContentXml().replace("\"", "\\\"") + "\"" : "\"\"");
    }

    /**
     * 发送任务草案到下游任务规划引擎。
     * <p>
     * 模拟发送过程：随机成功/失败，失败时记录重试。
     * 后续对接真实下游引擎时替换此方法。
     * </p>
     *
     * @param draftId 草案ID
     * @return 发送是否成功
     */
    public boolean sendTaskDraft(String draftId) {
        Optional<TaskDraft> draftOpt = draftRepository.findById(draftId);
        if (draftOpt.isEmpty()) {
            log.warn("任务草案 {} 不存在，无法发送", draftId);
            return false;
        }

        TaskDraft draft = draftOpt.get();
        log.info("发送任务草案 {} 到下游任务规划引擎...", draftId);

        try {
            // 模拟发送过程（当前阶段返回发送成功）
            boolean sendSuccess = simulateSendToEngine(draft);

            if (sendSuccess) {
                draftRepository.updateSendStatus(draftId, 1, draft.getRetryCount());
                log.info("任务草案 {} 发送成功", draftId);

                // 更新事件状态为已完成
                eventService.updateEventStatus(draft.getEventId(), com.example.demo.model.enums.EventStatus.COMPLETED);
                return true;
            } else {
                int newRetry = draft.getRetryCount() + 1;
                draftRepository.updateSendStatus(draftId, 2, newRetry);
                log.warn("任务草案 {} 发送失败，重试次数: {}", draftId, newRetry);
                return false;
            }
        } catch (Exception e) {
            int newRetry = draft.getRetryCount() + 1;
            draftRepository.updateSendStatus(draftId, 2, newRetry);
            log.error("任务草案 {} 发送异常: {}", draftId, e.getMessage());
            return false;
        }
    }

    /**
     * 模拟向下游引擎发送消息。
     * <p>
     * 当前实现模拟成功，后续对接真实引擎时替换。
     * </p>
     */
    private boolean simulateSendToEngine(TaskDraft draft) {
        // 模拟：前两次重试随机失败，之后成功
        if (draft.getRetryCount() < 2) {
            return true;
        }
        return true;
    }

    /**
     * 重试发送失败的任务草案。
     *
     * @param draftId 草案ID
     * @return 重试结果
     */
    public boolean retrySendDraft(String draftId) {
        Optional<TaskDraft> draftOpt = draftRepository.findById(draftId);
        if (draftOpt.isEmpty()) {
            return false;
        }
        TaskDraft draft = draftOpt.get();
        if (draft.getSendStatus() != 2) {
            log.info("任务草案 {} 当前状态不是发送失败，无需重试", draftId);
            return false;
        }
        return sendTaskDraft(draftId);
    }

    /**
     * 查询所有发送失败的任务草案。
     *
     * @return 失败的草案列表
     */
    public List<TaskDraft> getFailedDrafts() {
        return draftRepository.findAllFailed();
    }

    /**
     * 查询任务草案列表。
     *
     * @return 所有草案
     */
    public List<TaskDraft> getAllDrafts() {
        return draftRepository.findAll();
    }

    /**
     * 根据ID查询任务草案。
     *
     * @param draftId 草案ID
     * @return 草案
     */
    public Optional<TaskDraft> getDraftById(String draftId) {
        return draftRepository.findById(draftId);
    }
}
