package com.huimv.employment.service.conversation;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huimv.employment.service.conversation.dto.ParsedAssistantReply;
import org.springframework.util.StringUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 从 Agent assistant 纯文本中解析结构化卡片（支持 {@code ```fe-card```}/{@code ```json```} 代码块或整段 JSON）。
 */
public final class AssistantReplyParser {

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

    private AssistantReplyParser() {
    }

    public static ParsedAssistantReply parse(String rawText, ObjectMapper objectMapper) {
        if (!StringUtils.hasText(rawText)) {
            return ParsedAssistantReply.textOnly("");
        }
        String trimmed = rawText.trim();
        Matcher matcher = FENCED_BLOCK.matcher(trimmed);
        while (matcher.find()) {
            ParsedAssistantReply fromBlock = tryParseJsonBlock(
                    trimmed.substring(0, matcher.start()).trim(),
                    matcher.group(1).trim(),
                    objectMapper);
            if (fromBlock != null) {
                return fromBlock;
            }
        }
        if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
            ParsedAssistantReply whole = tryParseJsonBlock("", trimmed, objectMapper);
            if (whole != null) {
                return whole;
            }
        }
        return ParsedAssistantReply.textOnly(trimmed);
    }

    private static ParsedAssistantReply tryParseJsonBlock(String prefixText,
                                                          String jsonPayload,
                                                          ObjectMapper objectMapper) {
        if (!StringUtils.hasText(jsonPayload)) {
            return null;
        }
        try {
            JsonNode root = objectMapper.readTree(jsonPayload);
            if (!looksLikeCard(root)) {
                return null;
            }
            String contentType = resolveContentType(root);
            if (!StringUtils.hasText(contentType)
                    || MessageCardConstants.CONTENT_TYPE_TEXT.equals(contentType)) {
                return null;
            }
            String nextAction = textOrNull(root, "next_action");
            String cardPayload = resolveCardPayloadJson(root, objectMapper);
            Long relatedDraftId = resolveRelatedDraftId(root);
            String displayText = resolveDisplayText(prefixText, root);
            return new ParsedAssistantReply(displayText, contentType, cardPayload, nextAction, relatedDraftId);
        } catch (Exception ignored) {
            return null;
        }
    }

    private static boolean looksLikeCard(JsonNode root) {
        if (root == null || !root.isObject()) {
            return false;
        }
        return root.has("content_type")
                || root.has("card_type")
                || root.has("card_payload")
                || root.has("next_action");
    }

    private static String resolveContentType(JsonNode root) {
        String contentType = textOrNull(root, "content_type");
        if (StringUtils.hasText(contentType)) {
            return contentType.trim();
        }
        String cardType = textOrNull(root, "card_type");
        if (!StringUtils.hasText(cardType)) {
            return MessageCardConstants.CONTENT_TYPE_TEXT;
        }
        switch (cardType.trim()) {
            case "cost_calculation_result":
                return MessageCardConstants.CONTENT_TYPE_CARD_COST;
            case "employment_draft":
            case "draft_card":
                return MessageCardConstants.CONTENT_TYPE_CARD_DRAFT;
            case "process_action":
            case "order_progress":
                return MessageCardConstants.CONTENT_TYPE_CARD_ORDER;
            default:
                return MessageCardConstants.CONTENT_TYPE_TEXT;
        }
    }

    private static String resolveCardPayloadJson(JsonNode root, ObjectMapper objectMapper) throws Exception {
        JsonNode payload = root.get("card_payload");
        if (payload != null && !payload.isNull()) {
            return objectMapper.writeValueAsString(payload);
        }
        JsonNode data = root.get("data");
        if (data != null && !data.isNull()) {
            return objectMapper.writeValueAsString(data);
        }
        return null;
    }

    private static Long resolveRelatedDraftId(JsonNode root) {
        JsonNode payload = root.get("card_payload");
        if (payload != null && payload.has("draft_id")) {
            return payload.get("draft_id").asLong(0L) > 0 ? payload.get("draft_id").asLong() : null;
        }
        JsonNode data = root.get("data");
        if (data != null && data.has("draft_id")) {
            return data.get("draft_id").asLong(0L) > 0 ? data.get("draft_id").asLong() : null;
        }
        if (root.has("draft_id")) {
            return root.get("draft_id").asLong(0L) > 0 ? root.get("draft_id").asLong() : null;
        }
        return null;
    }

    private static String resolveDisplayText(String prefixText, JsonNode root) {
        String fromJson = textOrNull(root, "content");
        if (!StringUtils.hasText(fromJson)) {
            fromJson = textOrNull(root, "reply_text");
        }
        if (StringUtils.hasText(fromJson)) {
            return fromJson.trim();
        }
        return StringUtils.hasText(prefixText) ? prefixText.trim() : "请查看卡片详情";
    }

    private static String textOrNull(JsonNode root, String field) {
        if (root == null || !root.has(field) || root.get(field).isNull()) {
            return null;
        }
        String text = root.get(field).asText("");
        return text.isEmpty() ? null : text;
    }
}
