using System;
using System.Collections.Generic;
using System.Linq;
using EventsAppQuest.Web.Core;
using EventsAppQuest.Web.Domain;
using EventsAppQuest.Web.Producer.Domain;

namespace EventsAppQuest.Web.Application
{
    /// <summary>
    /// Consolida o estado final de encerramento do ciclo a partir do dashboard, alertas, plano de ações e resumo executivo. Apenas leitura agregada; não substitui módulos.
    /// </summary>
    public static class EventCycleClosureController
    {
        /// <summary>Avalia o estado de encerramento para todos os ciclos.</summary>
        public static List<EventCycleClosureState> EvaluateClosure(
            IReadOnlyList<ProducerOrder> orders,
            IReadOnlyList<SalesOpportunity> opportunities,
            IReadOnlyList<ProposalRecord> proposals,
            IReadOnlyList<SessionRecord> sessions,
            IReadOnlyList<FollowUpTask> followUpTasks)
        {
            var dashboardStates = EventCycleDashboardController.BuildDashboard(orders, opportunities, proposals, sessions);
            var alertStates = EventCycleAlertController.EvaluateAllAlerts(orders, opportunities, proposals, sessions, followUpTasks);
            var actionPlans = EventCycleActionPlanController.GenerateActionPlans(orders, opportunities, proposals, sessions, followUpTasks);
            var summaries = EventCycleExecutiveSummaryController.GenerateSummaries(orders, opportunities, proposals, sessions, followUpTasks);
            var list = new List<EventCycleClosureState>();
            var now = DateTime.UtcNow;

            foreach (var state in dashboardStates)
            {
                var cycleId = state.ProducerOrderId ?? state.CycleId;
                var alertState = alertStates?.FirstOrDefault(a => a.CycleId == cycleId);
                var actionPlan = actionPlans?.FirstOrDefault(p => p.CycleId == cycleId);
                var summary = summaries?.FirstOrDefault(s => s.CycleId == cycleId);
                var closure = EvaluateClosureForCycle(state, alertState, actionPlan, summary, now);
                if (closure != null)
                    list.Add(closure);
            }

            return list;
        }

        /// <summary>Avalia o estado de encerramento para um ciclo.</summary>
        public static EventCycleClosureState EvaluateClosureForCycle(
            EventCycleDashboardState dashboardState,
            EventCycleAlertState alertState,
            EventCycleActionPlanState actionPlanState,
            EventCycleExecutiveSummary executiveSummary,
            DateTime? evaluatedAt = null)
        {
            if (dashboardState == null) return null;
            var cycleId = dashboardState.ProducerOrderId ?? dashboardState.CycleId;
            var now = evaluatedAt ?? DateTime.UtcNow;

            var blockingAlerts = alertState?.BlockingAlerts ?? 0;
            var highSeverityCount = alertState?.HighSeverityAlerts ?? 0;
            var firstBlockingAlert = alertState?.Alerts?.FirstOrDefault(a => a.IsBlocking);
            var topAction = actionPlanState?.TopPriorityAction;
            var topActionIsCriticalBlocking = topAction != null && topAction.Priority == EventCycleActionPriority.Critical && topAction.IsBlockingResolution;

            EventCycleClosureStatus status;
            if (dashboardState.IsFinalAcceptanceDone && blockingAlerts == 0)
            {
                var hasRemainingAlerts = (alertState?.TotalAlerts ?? 0) > 0;
                status = hasRemainingAlerts ? EventCycleClosureStatus.CompletedWithIssues : EventCycleClosureStatus.Completed;
            }
            else if (blockingAlerts > 0 || topActionIsCriticalBlocking)
            {
                status = EventCycleClosureStatus.Blocked;
            }
            else if (highSeverityCount >= 2 || (topAction != null && topAction.Priority == EventCycleActionPriority.Critical))
            {
                status = EventCycleClosureStatus.AtRisk;
            }
            else
            {
                status = EventCycleClosureStatus.InProgress;
            }

            var isCompleted = status == EventCycleClosureStatus.Completed || status == EventCycleClosureStatus.CompletedWithIssues;
            var isBlocked = status == EventCycleClosureStatus.Blocked;
            var isAtRisk = status == EventCycleClosureStatus.AtRisk;
            var isHealthy = status == EventCycleClosureStatus.Completed && (alertState?.TotalAlerts ?? 0) == 0;

            var mainBlocking = firstBlockingAlert?.Title ?? (topActionIsCriticalBlocking ? topAction.Title : null) ?? (actionPlanState?.BlockingActions > 0 ? topAction?.Title : null);
            var mainProgress = GetMainProgressReason(dashboardState, executiveSummary);

            var closureSummary = BuildClosureSummary(status, dashboardState, blockingAlerts, highSeverityCount);
            var recommendation = BuildClosingRecommendation(status, mainBlocking, mainProgress);

            return new EventCycleClosureState
            {
                CycleId = cycleId,
                ClosureStatus = status.ToString(),
                IsCycleCompleted = isCompleted,
                IsCycleHealthy = isHealthy,
                IsCycleAtRisk = isAtRisk,
                IsCycleBlocked = isBlocked,
                ClosureSummary = closureSummary,
                ClosingRecommendation = recommendation,
                MainBlockingReason = mainBlocking ?? "—",
                MainProgressReason = mainProgress ?? "—",
                FinalManagementNote = null,
                EvaluatedAt = now
            };
        }

        private static string GetMainProgressReason(EventCycleDashboardState dashboard, EventCycleExecutiveSummary summary)
        {
            if (dashboard.IsFinalAcceptanceDone) return "Aceite final do hotel registado.";
            if (dashboard.IsExecutionCompleted) return "Execução concluída.";
            if (dashboard.IsExecutionStarted) return "Execução em curso.";
            if (dashboard.IsPreparationConfirmed) return "Preparação confirmada.";
            if (dashboard.IsScopeConfirmed) return "Escopo confirmado.";
            if (dashboard.IsProducerAccepted) return "Pedido aceite pelo produtor.";
            if (dashboard.IsHandoffGenerated) return "Handoff gerado.";
            if (summary?.TopProgressPoints != null && summary.TopProgressPoints.Count > 0)
                return summary.TopProgressPoints.Last().Title + ": " + summary.TopProgressPoints.Last().Summary;
            return "Ciclo em andamento.";
        }

        private static string BuildClosureSummary(EventCycleClosureStatus status, EventCycleDashboardState dashboard, int blockingAlerts, int highSeverityCount)
        {
            switch (status)
            {
                case EventCycleClosureStatus.Completed:
                    return "Ciclo concluído. Aceite final registado; sem bloqueios.";
                case EventCycleClosureStatus.CompletedWithIssues:
                    return "Ciclo concluído com ressalvas. Aceite final registado; existem alertas ou issues registados.";
                case EventCycleClosureStatus.Blocked:
                    return $"Ciclo bloqueado. {blockingAlerts} alerta(s) bloqueante(s) ou ação crítica bloqueante pendente.";
                case EventCycleClosureStatus.AtRisk:
                    return $"Ciclo em risco. {highSeverityCount} alerta(s) de alta severidade ou próxima ação crítica não resolvida.";
                case EventCycleClosureStatus.InProgress:
                default:
                    return "Ciclo em andamento. Handoff, execução ou aceite final pendentes.";
            }
        }

        private static string BuildClosingRecommendation(EventCycleClosureStatus status, string mainBlocking, string mainProgress)
        {
            switch (status)
            {
                case EventCycleClosureStatus.Completed:
                case EventCycleClosureStatus.CompletedWithIssues:
                    return "Nenhuma ação urgente. Ciclo encerrado ou com ressalvas.";
                case EventCycleClosureStatus.Blocked:
                    return string.IsNullOrEmpty(mainBlocking) ? "Resolver bloqueios indicados nos alertas e na próxima ação." : "Resolver: " + mainBlocking;
                case EventCycleClosureStatus.AtRisk:
                    return "Priorizar próxima ação recomendada e reduzir alertas de alta severidade.";
                case EventCycleClosureStatus.InProgress:
                default:
                    return "Acompanhar próximo passo recomendado. " + (string.IsNullOrEmpty(mainProgress) ? "" : "Progresso: " + mainProgress);
            }
        }
    }
}
