package com.huimv.employment.service.conversation;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huimv.employment.dao.entity.FeEmploymentDraft;
import com.huimv.employment.dao.mapper.FeEmploymentDraftMapper;
import com.huimv.employment.service.conversation.dto.ParsedAssistantReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * SSE 最后消息时，由服务端根据会话 pending 且 missingFields 为空的草稿注入卡片字段（不依赖智能体）。
 */
@Component
public class ConversationDraftCardEnricher {

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

    private static final String DB_STATUS_PENDING = "pending";

    private static final Pattern FENCED_CARD_BLOCK = Pattern.compile(
            "```(?:fe-card|json)?\\s*[\\s\\S]*?```",
            Pattern.CASE_INSENSITIVE);

    private final FeEmploymentDraftMapper feEmploymentDraftMapper;
    private final ObjectMapper objectMapper;

    public ConversationDraftCardEnricher(FeEmploymentDraftMapper feEmploymentDraftMapper,
                                         ObjectMapper objectMapper) {
        this.feEmploymentDraftMapper = feEmploymentDraftMapper;
        this.objectMapper = objectMapper;
    }

    /**
     * 会话有 pending 草稿且 missingFields 为空时追加 card_draft。
     */
    public ParsedAssistantReply attachCardOnComplete(Long conversationId, String assistantText) {
        String displayText = sanitizeDisplayText(assistantText);
        ParsedAssistantReply parsed = ParsedAssistantReply.textOnly(displayText);
        if (conversationId == null) {
            log.warn("SSE 注入卡片跳过：conversationId 为空");
            return parsed;
        }
        FeEmploymentDraft draft = findPendingDraft(conversationId);
        if (draft == null) {
            log.info("SSE 注入卡片跳过：会话 {} 无 pending 草稿", conversationId);
            return parsed;
        }
        List<String> missing = parseMissingFields(draft.getMissingFields());
        if (!missing.isEmpty()) {
            log.info("SSE 注入卡片跳过：会话 {} 草稿 {} missingFields 非空 {}",
                    conversationId, draft.getId(), missing);
            return parsed;
        }
        try {
            Map<String, Object> payload = buildDraftCardPayload(draft);
            String cardPayload = objectMapper.writeValueAsString(payload);
            log.info("SSE 注入卡片 conversationId={} draftId={}", conversationId, draft.getId());
            return parsed.withCard(
                    MessageCardConstants.CONTENT_TYPE_CARD_DRAFT,
                    MessageCardConstants.NEXT_ACTION_SHOW_EMPLOYMENT_DRAFT,
                    cardPayload,
                    draft.getId());
        } catch (Exception ex) {
            log.warn("会话 {} 草稿卡片注入失败: {}", conversationId, ex.getMessage(), ex);
            return parsed;
        }
    }

    private String sanitizeDisplayText(String raw) {
        if (!StringUtils.hasText(raw)) {
            return "";
        }
        String cleaned = FENCED_CARD_BLOCK.matcher(raw).replaceAll("").trim();
        return StringUtils.hasText(cleaned) ? cleaned : raw.trim();
    }

    private FeEmploymentDraft findPendingDraft(Long conversationId) {
        return feEmploymentDraftMapper.selectOne(new LambdaQueryWrapper<FeEmploymentDraft>()
                .eq(FeEmploymentDraft::getConversationId, conversationId)
                .eq(FeEmploymentDraft::getStatus, DB_STATUS_PENDING)
                .orderByDesc(FeEmploymentDraft::getCreateTime)
                .last("LIMIT 1"));
    }

    private List<String> parseMissingFields(String json) {
        if (!StringUtils.hasText(json)) {
            return Collections.emptyList();
        }
        try {
            List<String> parsed = objectMapper.readValue(json.trim(), new TypeReference<List<String>>() {
            });
            return parsed != null ? parsed : Collections.emptyList();
        } catch (Exception ex) {
            log.warn("解析 missing_fields 失败，视为非空，跳过注入: {}", ex.getMessage());
            // 解析失败时保守处理：不注入，避免误推未就绪草稿
            return Collections.singletonList("_parse_error");
        }
    }

    private Map<String, Object> buildDraftCardPayload(FeEmploymentDraft draft) {
        Map<String, Object> payload = new LinkedHashMap<>();
        payload.put("draft_id", draft.getId());
        payload.put("draft_no", draft.getDraftNo());
        payload.put("title", draft.getTitle());
        payload.put("worker_count", draft.getWorkerCount());
        payload.put("work_days", draft.getWorkDays());
        payload.put("work_type", draft.getWorkType());
        payload.put("work_location", draft.getWorkLocation());
        payload.put("settlement_mode", draft.getSettlementMode());
        payload.put("total_amount", draft.getEstimatedTotal());
        payload.put("status", "ready");
        payload.put("missing_fields", Collections.emptyList());
        return payload;
    }
}
