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

import dev.sonpx.loyalty.agent.core.classifier.Intent;
import dev.sonpx.loyalty.agent.core.classifier.IntentClassifier;
import dev.sonpx.loyalty.agent.core.executor.SimpleAgentExecutor;
import dev.sonpx.loyalty.agent.core.workflow.WorkflowExecutor;
import dev.sonpx.loyalty.agent.domain.ChatRequest;
import dev.sonpx.loyalty.agent.service.AgentEventPublisher;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * Central orchestrator routing user requests to the appropriate execution path.
 *
 * 3 execution paths:
 * 1. DirectChat — conversations, greetings (no tools loaded)
 * 2. SimpleAgent — data queries using ReAct pattern (with tools)
 * 3. ConversationWorkflow — multi-turn guided creation (campaign/rule)
 *
 * Key improvements:
 * - IntentClassifier (rule-based, zero LLM) replaces old AgentPlanner
 * - Active workflows take priority over intent classification
 * - Exceptions always send error events to user (no more silent failures)
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AgentOrchestrator {

    private final IntentClassifier intentClassifier;
    private final SimpleAgentExecutor simpleAgent;
    private final WorkflowExecutor workflowExecutor;
    private final AgentEventPublisher eventPublisher;

    public void process(ChatRequest request, String connectionSessionId, String conversationKey) {
        try {
            // Priority 1: Continue active workflow (if user is mid-conversation for creation)
            if (workflowExecutor.hasActiveWorkflow(conversationKey)) {
                if (workflowExecutor.isSideQuery(request.prompt())) {
                    log.info("Routing side-query while preserving active workflow for conversation: {}", conversationKey);
                    Intent intent = intentClassifier.classify(request.prompt());
                    simpleAgent.executeWithTools(request, connectionSessionId, conversationKey, intent);
                } else {
                    log.info("Continuing active workflow for conversation: {}", conversationKey);
                    workflowExecutor.continueWorkflow(request, connectionSessionId, conversationKey);
                }
                return;
            }

            // Priority 2: Classify intent and route
            Intent intent = intentClassifier.classify(request.prompt());
            log.info("Classified intent: {} for conversation: {}, connection: {}", intent, conversationKey, connectionSessionId);

            switch (intent) {
                case CONVERSATION -> {
                    log.info("Routing to DirectChat (no tools)");
                    simpleAgent.executeDirectChat(request, connectionSessionId, conversationKey);
                }
                case CAMPAIGN_CREATE, RULE_CREATE -> {
                    log.info("Starting ConversationWorkflow for: {}", intent);
                    workflowExecutor.startWorkflow(intent, request, connectionSessionId, conversationKey);
                }
                case CAMPAIGN_QUERY, RULE_QUERY, UNKNOWN -> {
                    log.info("Routing to SimpleAgent with tools");
                    simpleAgent.executeWithTools(request, connectionSessionId, conversationKey, intent);
                }
            }
        } catch (Exception e) {
            log.error("Error processing request for conversation: {}, connection: {}", conversationKey, connectionSessionId, e);
            // Always notify user of errors — never swallow exceptions silently
            eventPublisher.error(connectionSessionId, request.messageId(),
                    "Xin lỗi, đã xảy ra lỗi khi xử lý yêu cầu. Vui lòng thử lại.");
        }
    }
}
