namespace AxCopilot.Services.Agent;

/// <summary>
/// Phase 18-A1: 코디네이터 에이전트 모드.
/// LLM이 계획을 수립하고 서브에이전트들에게 태스크를 위임합니다.
/// </summary>
public partial class AgentLoopService
{
    /// <summary>
    /// 코디네이터 모드 실행.
    /// 성공하면 최종 합성 결과를 반환, 실패 시 null 반환 (일반 에이전트 루프로 fallback).
    /// </summary>
    internal async Task<string?> RunCoordinatorModeAsync(
        string userRequest,
        string workFolder,
        CancellationToken ct)
    {
        try
        {
            var coordService = new CoordinatorAgentService(_llm);

            // 1단계: 계획 수립
            var reqPreview = userRequest.Length > 60 ? userRequest[..57] + "…" : userRequest;
            EmitEvent(AgentEventType.Planning, "coordinator",
                $"코디네이터 모드: 요청 분석 중... [{reqPreview}]");

            var plan = await coordService.PlanAsync(userRequest, ct);

            if (plan.Tasks.Count == 0)
                return null; // 계획 실패 → 일반 루프 fallback

            // 계획 요약 이벤트
            var planSummary = string.Join(", ", plan.Tasks.Select(t => $"{t.AgentType}:{t.Id}"));
            EmitEvent(AgentEventType.Planning, "coordinator",
                $"계획 수립 완료 ({plan.Tasks.Count}개 태스크): {planSummary}");

            // 2단계: 사용자 승인 (UserDecisionCallback이 있는 경우)
            if (UserDecisionCallback != null)
            {
                var planText = FormatCoordinatorPlan(plan);
                var options = new List<string> { "실행", "취소" };
                var answer = await UserDecisionCallback(planText, options);

                if (answer == null || answer.Contains("취소", StringComparison.OrdinalIgnoreCase))
                {
                    EmitEvent(AgentEventType.Complete, "coordinator", "사용자가 코디네이터 계획을 취소했습니다.");
                    return "코디네이터 계획이 취소되었습니다.";
                }
            }

            // 3단계: 각 서브태스크 실행
            var result = await coordService.ExecuteAsync(
                plan,
                workFolder,
                RunSubAgentAsync,
                onTaskStarted: (id, desc) =>
                    EmitEvent(AgentEventType.ToolCall, $"coordinator/{id}",
                        $"[{id}] {desc}"),
                onTaskCompleted: (id, res) =>
                    EmitEvent(AgentEventType.ToolResult, $"coordinator/{id}",
                        $"[{id}] 완료: {(res.Length > 100 ? res[..97] + "…" : res)}"),
                ct);

            EmitEvent(AgentEventType.Complete, "coordinator", "코디네이터 모드 완료");
            return result;
        }
        catch (OperationCanceledException)
        {
            EmitEvent(AgentEventType.Complete, "coordinator", "취소됨");
            return "코디네이터 모드가 취소되었습니다.";
        }
        catch (Exception ex)
        {
            LogService.Warn($"[Coordinator] 오류: {ex.Message}. 일반 에이전트 루프로 fallback.");
            EmitEvent(AgentEventType.Error, "coordinator", $"코디네이터 오류: {ex.Message} — 일반 모드로 전환");
            return null; // fallback to normal loop
        }
    }

    /// <summary>코디네이터 계획을 사용자에게 보여줄 텍스트로 포맷합니다.</summary>
    private static string FormatCoordinatorPlan(CoordinatorPlan plan)
    {
        var sb = new System.Text.StringBuilder();
        sb.AppendLine($"📋 코디네이터 계획 ({plan.Tasks.Count}개 태스크)");
        sb.AppendLine($"요청: {plan.OriginalRequest}");
        sb.AppendLine();

        foreach (var task in plan.Tasks)
        {
            var deps = task.Dependencies.Count > 0
                ? $" (선행: {string.Join(", ", task.Dependencies)})"
                : "";
            sb.AppendLine($"  [{task.Id}] {task.AgentType}{deps}");
            sb.AppendLine($"      {task.Description}");
        }

        sb.AppendLine("\n이 계획을 실행할까요?");
        return sb.ToString();
    }
}
