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

namespace EventsAppQuest.Web.Application
{
    /// <summary>
    /// Consolida resumo executivo do ciclo a partir do dashboard, alertas e plano de ações. Apenas síntese; não substitui módulos.
    /// </summary>
    public static class EventCycleExecutiveSummaryController
    {
        private const int MaxTopRisks = 5;
        private const int MaxTopProgressPoints = 5;

        /// <summary>Gera resumos executivos para todos os ciclos.</summary>
        public static List<EventCycleExecutiveSummary> GenerateSummaries(
            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 list = new List<EventCycleExecutiveSummary>();
            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 = BuildSummaryForCycle(state, alertState, actionPlan, now);
                if (summary != null)
                    list.Add(summary);
            }

            return list;
        }

        /// <summary>Gera resumo executivo para um ciclo a partir do estado do dashboard, alertas e plano.</summary>
        public static EventCycleExecutiveSummary BuildSummaryForCycle(
            EventCycleDashboardState dashboardState,
            EventCycleAlertState alertState,
            EventCycleActionPlanState actionPlanState,
            DateTime? generatedAt = null)
        {
            if (dashboardState == null) return null;
            var cycleId = dashboardState.ProducerOrderId ?? dashboardState.CycleId;
            var now = generatedAt ?? DateTime.UtcNow;

            var commercialSection = dashboardState.Sections?.FirstOrDefault(s => s.SectionKey == EventCycleDashboardController.SectionComercial);
            var questSection = dashboardState.Sections?.FirstOrDefault(s => s.SectionKey == EventCycleDashboardController.SectionSessaoQuest);
            var handoffSection = dashboardState.Sections?.FirstOrDefault(s => s.SectionKey == EventCycleDashboardController.SectionHandoff);
            var produtorSection = dashboardState.Sections?.FirstOrDefault(s => s.SectionKey == EventCycleDashboardController.SectionProdutor);
            var execucaoSection = dashboardState.Sections?.FirstOrDefault(s => s.SectionKey == EventCycleDashboardController.SectionExecucao);
            var aceiteSection = dashboardState.Sections?.FirstOrDefault(s => s.SectionKey == EventCycleDashboardController.SectionAceiteFinal);

            var summary = new EventCycleExecutiveSummary
            {
                CycleId = cycleId,
                ExecutiveTitle = "Ciclo " + cycleId,
                OverallStatusLabel = dashboardState.OverallCycleStatus ?? dashboardState.OperationalStageLabel ?? "—",
                CommercialSummary = commercialSection != null ? (commercialSection.StatusLabel + ": " + commercialSection.Summary) : "—",
                QuestSessionSummary = questSection != null ? (questSection.StatusLabel + " — " + questSection.Summary) : "—",
                HandoffSummary = handoffSection != null ? (handoffSection.StatusLabel + " — " + (handoffSection.Summary ?? "—")) : "—",
                ProducerSummary = produtorSection != null ? (produtorSection.StatusLabel + " — " + (produtorSection.Summary ?? "—")) : "—",
                ExecutionSummary = execucaoSection != null ? (execucaoSection.StatusLabel + " — " + (execucaoSection.Summary ?? "—")) : "—",
                FinalAcceptanceSummary = aceiteSection != null ? (aceiteSection.StatusLabel + " — " + (aceiteSection.Summary ?? "—")) : "—",
                TopRisks = new List<EventCycleExecutivePoint>(),
                TopProgressPoints = new List<EventCycleExecutivePoint>(),
                ManagementNotes = null,
                GeneratedAt = now
            };

            if (alertState?.Alerts != null)
            {
                foreach (var a in alertState.Alerts.OrderByDescending(x => x.Severity).ThenBy(x => x.Title).Take(MaxTopRisks))
                {
                    summary.TopRisks.Add(new EventCycleExecutivePoint
                    {
                        Title = a.Title,
                        Summary = a.Summary ?? a.SuggestedAction,
                        SeverityOrImportance = a.Severity.ToString(),
                        RelatedSectionKey = a.RelatedSectionKey,
                        Notes = a.SuggestedAction
                    });
                }
            }

            if (dashboardState.Sections != null)
            {
                if (dashboardState.IsProducerAccepted)
                    summary.TopProgressPoints.Add(MakePoint("Pedido aceite pelo produtor", "Aceite confirmado.", "Ok", EventCycleDashboardController.SectionHandoff));
                if (dashboardState.IsScopeConfirmed)
                    summary.TopProgressPoints.Add(MakePoint("Escopo confirmado", "Escopo alinhado entre hotel e produtor.", "Ok", EventCycleDashboardController.SectionProdutor));
                if (dashboardState.IsPreparationConfirmed)
                    summary.TopProgressPoints.Add(MakePoint("Preparação confirmada", "Checklist concluído e preparação confirmada.", "Ok", EventCycleDashboardController.SectionProdutor));
                if (dashboardState.IsExecutionStarted)
                    summary.TopProgressPoints.Add(MakePoint("Execução iniciada", "Execução operacional em curso.", "Ok", EventCycleDashboardController.SectionExecucao));
                if (dashboardState.IsExecutionCompleted)
                    summary.TopProgressPoints.Add(MakePoint("Execução concluída", "Execução finalizada.", "Concluído", EventCycleDashboardController.SectionExecucao));
                if (dashboardState.IsFinalAcceptanceDone)
                    summary.TopProgressPoints.Add(MakePoint("Aceite final", "Decisão do hotel registada.", "Concluído", EventCycleDashboardController.SectionAceiteFinal));
                summary.TopProgressPoints = summary.TopProgressPoints.Take(MaxTopProgressPoints).ToList();
            }

            if (actionPlanState?.TopPriorityAction != null)
            {
                var top = actionPlanState.TopPriorityAction;
                summary.TopRecommendedAction = new EventCycleExecutivePoint
                {
                    Title = top.Title,
                    Summary = top.SuggestedReason ?? top.Summary,
                    SeverityOrImportance = top.Priority.ToString(),
                    RelatedSectionKey = top.RelatedSectionKey,
                    Notes = top.ResponsibleRole.ToString()
                };
            }

            return summary;
        }

        private static EventCycleExecutivePoint MakePoint(string title, string summary, string importance, string sectionKey)
        {
            return new EventCycleExecutivePoint
            {
                Title = title,
                Summary = summary,
                SeverityOrImportance = importance,
                RelatedSectionKey = sectionKey,
                Notes = null
            };
        }

        /// <summary>Obtém o principal risco (primeiro da lista de TopRisks) e a principal ação (TopRecommendedAction) para strip/HUD.</summary>
        public static void GetMainRiskAndAction(EventCycleExecutiveSummary summary, out EventCycleExecutivePoint mainRisk, out EventCycleExecutivePoint mainAction)
        {
            mainRisk = null;
            mainAction = null;
            if (summary == null) return;
            mainRisk = summary.TopRisks?.FirstOrDefault();
            mainAction = summary.TopRecommendedAction;
        }
    }
}
