package dev.sonpx.loyalty.agent.core.workflow;

import dev.sonpx.loyalty.agent.core.classifier.Intent;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

/**
 * Deterministic, low-cost extraction for workflow state.
 *
 * It intentionally stores raw user-provided text as a fallback, because small local
 * models are not reliable enough to be the only source of workflow state.
 */
@Component
public class WorkflowDataExtractor {

    private static final Pattern KEY_VALUE = Pattern.compile("^\\s*(?:[-*]\\s*)?(?:\\d+[.)]\\s*)?([^:：-]{2,40})\\s*[:：-]\\s*(.+)$");
    private static final Pattern CAMPAIGN_ID = Pattern.compile("(?i)\\b(?:campaign|chi[eế]n d[iị]ch|m[aã])(?:\\s*id)?\\s*[:#-]?\\s*([A-Z0-9_-]{3,})\\b");
    private static final Pattern RULE_ID = Pattern.compile("(?i)\\b(?:rule|th[eể] l[eệ]|m[aã])(?:\\s*id)?\\s*[:#-]?\\s*([A-Z0-9_-]{3,})\\b");
    private static final Pattern DATE_RANGE = Pattern.compile("(\\d{1,2}[/-]\\d{1,2}[/-]\\d{2,4}|\\d{4}-\\d{1,2}-\\d{1,2})\\s*(?:đ[eế]n|->|t[oớ]i|-)\\s*(\\d{1,2}[/-]\\d{1,2}[/-]\\d{2,4}|\\d{4}-\\d{1,2}-\\d{1,2})", Pattern.CASE_INSENSITIVE);

    public Map<String, Object> extract(WorkflowState state, String userInput) {
        Map<String, Object> extracted = new LinkedHashMap<>();
        if (!StringUtils.hasText(userInput)) {
            return extracted;
        }

        String phaseKey = switch (state.getCurrentPhase()) {
            case BASIC_INFO -> "Thông tin cơ bản";
            case REWARD_CONFIG -> "Cấu hình thưởng";
            case CONFIRMING -> "Điều chỉnh khi xác nhận";
            default -> "Thông tin bổ sung";
        };
        extracted.put(phaseKey, userInput.trim());
        extractKeyValues(userInput, extracted);
        extractKnownFields(state.getWorkflowType(), userInput, extracted);
        return extracted;
    }

    public boolean hasEnoughForNextPhase(WorkflowState state, String userInput) {
        if (!StringUtils.hasText(userInput)) {
            return false;
        }
        if (state.getWorkflowType() == Intent.RULE_CREATE && state.getCurrentPhase() == WorkflowState.Phase.REWARD_CONFIG) {
            return true;
        }
        return userInput.trim().length() >= 20 || state.getCollectedData().size() >= 3;
    }

    private void extractKeyValues(String userInput, Map<String, Object> extracted) {
        for (String line : userInput.split("\\R")) {
            Matcher matcher = KEY_VALUE.matcher(line);
            if (matcher.matches()) {
                String key = normalizeKey(matcher.group(1));
                String value = matcher.group(2).trim();
                if (StringUtils.hasText(key) && StringUtils.hasText(value)) {
                    extracted.put(key, value);
                }
            }
        }
    }

    private void extractKnownFields(Intent workflowType, String userInput, Map<String, Object> extracted) {
        Matcher dateRange = DATE_RANGE.matcher(userInput);
        if (dateRange.find()) {
            extracted.put("Thời gian hiệu lực", dateRange.group(1) + " -> " + dateRange.group(2));
        }

        String lower = userInput.toLowerCase();
        if (workflowType == Intent.CAMPAIGN_CREATE) {
            if (lower.contains("base")) {
                extracted.put("Loại chiến dịch", "B");
            } else if (lower.contains("tactical")) {
                extracted.put("Loại chiến dịch", "T");
            }
            return;
        }

        Matcher campaignId = CAMPAIGN_ID.matcher(userInput);
        if (campaignId.find()) {
            extracted.put("Campaign ID", campaignId.group(1));
        }

        Matcher ruleId = RULE_ID.matcher(userInput);
        if (ruleId.find()) {
            extracted.put("Rule ID", ruleId.group(1));
        }

        for (String type : new String[] {"AWD", "RED", "IRED", "ADJ", "CEP", "REP", "TEP", "MAWD"}) {
            if (lower.contains(type.toLowerCase())) {
                extracted.put("Loại rule", type);
                break;
            }
        }
    }

    private String normalizeKey(String key) {
        return key.trim()
                .replaceAll("\\s+", " ")
                .replaceAll("^[0-9.)\\s-]+", "");
    }
}
