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

namespace EventsAppQuest.Web.Application
{
    /// <summary>
    /// Snapshots executivos do caso: captura checkpoints resumidos e permite listar/remover/comparar. Agregador/manual.
    /// </summary>
    public static class EventCycleExecutiveSnapshotsController
    {
        /// <summary>
        /// Captura um snapshot do ciclo a partir dos estados agregados atuais.
        /// </summary>
        public static EventCycleExecutiveSnapshot CaptureSnapshot(
            string cycleId,
            EventCycleExecutiveSummary executiveSummary,
            EventCycleClosureState closureState,
            EventCyclePortfolioItem portfolioItem,
            EventCycleBottleneckState bottleneckState,
            EventCycleActionPlanState actionPlanState,
            EventCycleRecoveryPlanState recoveryPlanState,
            EventCycleManagerNotesState managerNotesState,
            DateTime? capturedAt = null)
        {
            if (string.IsNullOrEmpty(cycleId)) return null;
            var now = capturedAt ?? DateTime.UtcNow;

            var title = executiveSummary?.ExecutiveTitle ?? portfolioItem?.Title ?? ("Checkpoint " + cycleId);
            var risk = portfolioItem?.RiskLevelLabel
                       ?? (closureState?.IsCycleBlocked == true ? "Bloqueado" : (closureState?.IsCycleAtRisk == true ? "Em risco" : "Normal"));
            var mainBottleneck = bottleneckState?.TopPriorityBottleneck != null ? bottleneckState.TopPriorityBottleneck.Title : "—";
            var mainRecAction = executiveSummary?.TopRecommendedAction?.Title
                                ?? actionPlanState?.TopPriorityAction?.Title
                                ?? portfolioItem?.TopRecommendedAction
                                ?? "—";
            var mainRecovery = recoveryPlanState?.PrimaryRecoveryAction?.Title ?? portfolioItem?.TopRecoveryAction ?? "—";
            var notesSummary = managerNotesState?.NotesSummary ?? "—";

            var summary = $"Closure: {closureState?.ClosureStatus ?? portfolioItem?.ClosureStatus ?? "—"} | Risco: {risk} | Gargalo: {mainBottleneck} | Ação: {mainRecAction}";

            var snapshot = new EventCycleExecutiveSnapshot
            {
                CycleId = cycleId,
                Title = title,
                Summary = summary,
                ClosureStatus = closureState?.ClosureStatus ?? portfolioItem?.ClosureStatus,
                PriorityScore = portfolioItem?.PriorityScore ?? 0,
                RiskLabel = risk,
                MainBottleneck = mainBottleneck,
                MainRecommendedAction = mainRecAction,
                MainRecoveryAction = mainRecovery,
                NotesSummary = notesSummary,
                CapturedAt = now
            };

            ExecutiveSnapshotsStore.AddSnapshot(snapshot);
            return snapshot;
        }

        /// <summary>
        /// Captura snapshots automaticamente para todos os ciclos atuais do dashboard.
        /// </summary>
        public static List<EventCycleExecutiveSnapshot> CaptureSnapshotsForAllCycles(
            IReadOnlyList<ProducerOrder> orders,
            IReadOnlyList<SalesOpportunity> opportunities,
            IReadOnlyList<ProposalRecord> proposals,
            IReadOnlyList<SessionRecord> sessions,
            IReadOnlyList<FollowUpTask> followUpTasks)
        {
            var portfolioState = EventCyclePortfolioPriorityController.BuildPortfolioPriority(orders, opportunities, proposals, sessions, followUpTasks);
            var summaries = EventCycleExecutiveSummaryController.GenerateSummaries(orders, opportunities, proposals, sessions, followUpTasks);
            var closures = EventCycleClosureController.EvaluateClosure(orders, opportunities, proposals, sessions, followUpTasks);
            var bottlenecks = EventCycleBottleneckController.EvaluateBottlenecks(orders, opportunities, proposals, sessions, followUpTasks);
            var actionPlans = EventCycleActionPlanController.GenerateActionPlans(orders, opportunities, proposals, sessions, followUpTasks);
            var recoveryPlans = EventCycleRecoveryPlanController.GenerateRecoveryPlans(orders, opportunities, proposals, sessions, followUpTasks);

            var list = new List<EventCycleExecutiveSnapshot>();
            var now = DateTime.UtcNow;

            foreach (var item in portfolioState?.Items ?? new List<EventCyclePortfolioItem>())
            {
                var cycleId = item.CycleId;
                var snap = CaptureSnapshot(
                    cycleId,
                    summaries?.FirstOrDefault(s => s.CycleId == cycleId),
                    closures?.FirstOrDefault(c => c.CycleId == cycleId),
                    item,
                    bottlenecks?.FirstOrDefault(b => b.CycleId == cycleId),
                    actionPlans?.FirstOrDefault(a => a.CycleId == cycleId),
                    recoveryPlans?.FirstOrDefault(r => r.CycleId == cycleId),
                    EventCycleManagerNotesController.GetNotesState(cycleId),
                    now);
                if (snap != null) list.Add(snap);
            }

            return list;
        }

        public static EventCycleExecutiveSnapshotsState GetSnapshotsState(string cycleId)
        {
            var snaps = ExecutiveSnapshotsStore.GetSnapshots(cycleId);
            var latest = snaps.FirstOrDefault();
            var summary = snaps.Count == 0
                ? "Nenhum snapshot."
                : $"{snaps.Count} snapshot(s). Último: {(latest != null ? latest.Title : "—")}.";

            return new EventCycleExecutiveSnapshotsState
            {
                CycleId = cycleId,
                Snapshots = snaps,
                LatestSnapshot = latest,
                TotalSnapshots = snaps.Count,
                LastCapturedAt = latest?.CapturedAt,
                SnapshotSummary = summary
            };
        }

        public static EventCycleExecutiveSnapshotsState GetGlobalSnapshotsState()
        {
            var all = ExecutiveSnapshotsStore.GetAllSnapshots();
            var latest = all.FirstOrDefault();
            var summary = all.Count == 0
                ? "Nenhum snapshot executivo."
                : $"{all.Count} snapshot(s) em {all.Select(s => s.CycleId).Distinct().Count()} ciclo(s). Último: {(latest != null ? latest.Title : "—")}.";

            return new EventCycleExecutiveSnapshotsState
            {
                CycleId = null,
                Snapshots = all,
                LatestSnapshot = latest,
                TotalSnapshots = all.Count,
                LastCapturedAt = latest?.CapturedAt,
                SnapshotSummary = summary
            };
        }

        public static void RemoveSnapshot(string cycleId, string snapshotId) => ExecutiveSnapshotsStore.RemoveSnapshot(cycleId, snapshotId);

        /// <summary>
        /// Comparação textual simples entre snapshots (atual vs anterior).
        /// </summary>
        public static string CompareSnapshots(EventCycleExecutiveSnapshot current, EventCycleExecutiveSnapshot previous)
        {
            if (current == null) return "Sem snapshot atual.";
            if (previous == null) return "Sem snapshot anterior para comparar.";

            var deltas = new List<string>();
            if ((previous.ClosureStatus ?? "") != (current.ClosureStatus ?? ""))
                deltas.Add($"Closure {previous.ClosureStatus ?? "—"}→{current.ClosureStatus ?? "—"}");
            if ((previous.RiskLabel ?? "") != (current.RiskLabel ?? ""))
                deltas.Add($"Risco {previous.RiskLabel ?? "—"}→{current.RiskLabel ?? "—"}");
            if (previous.PriorityScore != current.PriorityScore)
                deltas.Add($"Prioridade {previous.PriorityScore}→{current.PriorityScore}");
            if ((previous.MainBottleneck ?? "") != (current.MainBottleneck ?? ""))
                deltas.Add($"Gargalo {previous.MainBottleneck ?? "—"}→{current.MainBottleneck ?? "—"}");
            if ((previous.MainRecommendedAction ?? "") != (current.MainRecommendedAction ?? ""))
                deltas.Add($"Ação {previous.MainRecommendedAction ?? "—"}→{current.MainRecommendedAction ?? "—"}");

            return deltas.Count == 0 ? "Sem mudanças relevantes." : string.Join(" | ", deltas);
        }
    }
}

