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

namespace EventsAppQuest.Web.Application
{
    /// <summary>
    /// Filtros executivos da carteira e recortes por risco, prioridade, fechamento e operação. Agregador: aplica filtros sobre EventCyclePortfolioPriorityState.
    /// </summary>
    public static class EventCyclePortfolioFilterController
    {
        public const string FilterAtRisk = "AtRisk";
        public const string FilterBlocked = "Blocked";
        public const string FilterHighPriority = "HighPriority";
        public const string FilterClosingSoon = "ClosingSoon";
        public const string FilterRecoveryOpportunity = "RecoveryOpportunity";
        public const string FilterCompletedWithIssues = "CompletedWithIssues";
        public const string FilterExecutionActive = "ExecutionActive";
        public const string FilterNone = "None";

        /// <summary>Obtém os filtros disponíveis (presets).</summary>
        public static List<EventCyclePortfolioFilter> GetAvailableFilters()
        {
            return new List<EventCyclePortfolioFilter>
            {
                new EventCyclePortfolioFilter { FilterId = FilterAtRisk, Name = "Somente em risco", RiskLevelFilter = "AtRisk", IncludeBlockedOnly = false, IncludeClosingSoonOnly = false, IncludeRecoveryOpportunitiesOnly = false, IncludeCompletedWithIssuesOnly = false, IncludeExecutionActiveOnly = false, Notes = "Ciclos em risco ou com alertas críticos." },
                new EventCyclePortfolioFilter { FilterId = FilterBlocked, Name = "Somente bloqueados", RiskLevelFilter = "Blocked", IncludeBlockedOnly = true, IncludeClosingSoonOnly = false, IncludeRecoveryOpportunitiesOnly = false, IncludeCompletedWithIssuesOnly = false, IncludeExecutionActiveOnly = false, Notes = "Ciclos bloqueados." },
                new EventCyclePortfolioFilter { FilterId = FilterHighPriority, Name = "Somente alta prioridade", PriorityLevelFilter = "High", IncludeBlockedOnly = false, IncludeClosingSoonOnly = false, IncludeRecoveryOpportunitiesOnly = false, IncludeCompletedWithIssuesOnly = false, IncludeExecutionActiveOnly = false, Notes = "Score de prioridade ≥ 70." },
                new EventCyclePortfolioFilter { FilterId = FilterClosingSoon, Name = "Somente perto de fechar", ClosureStatusFilter = "Closing", IncludeBlockedOnly = false, IncludeClosingSoonOnly = true, IncludeRecoveryOpportunitiesOnly = false, IncludeCompletedWithIssuesOnly = false, IncludeExecutionActiveOnly = false, Notes = "Casos próximos do aceite final." },
                new EventCyclePortfolioFilter { FilterId = FilterRecoveryOpportunity, Name = "Somente recuperação promissora", IncludeBlockedOnly = false, IncludeClosingSoonOnly = false, IncludeRecoveryOpportunitiesOnly = true, IncludeCompletedWithIssuesOnly = false, IncludeExecutionActiveOnly = false, Notes = "Com plano de recuperação e ganho simulado." },
                new EventCyclePortfolioFilter { FilterId = FilterCompletedWithIssues, Name = "Somente concluídos com issues", ClosureStatusFilter = "Closed", IncludeBlockedOnly = false, IncludeClosingSoonOnly = false, IncludeRecoveryOpportunitiesOnly = false, IncludeCompletedWithIssuesOnly = true, IncludeExecutionActiveOnly = false, Notes = "Concluídos com performance baixa ou pendências." },
                new EventCyclePortfolioFilter { FilterId = FilterExecutionActive, Name = "Somente execução ativa", ProducerStatusFilter = "ExecutionActive", IncludeBlockedOnly = false, IncludeClosingSoonOnly = false, IncludeRecoveryOpportunitiesOnly = false, IncludeCompletedWithIssuesOnly = false, IncludeExecutionActiveOnly = true, Notes = "Em andamento operacional (não concluídos, não bloqueados)." }
            };
        }

        /// <summary>Aplica um filtro à priorização da carteira e devolve a vista filtrada.</summary>
        public static EventCyclePortfolioFilteredViewState ApplyFilter(
            EventCyclePortfolioPriorityState priorityState,
            EventCyclePortfolioFilter filter,
            DateTime? filteredAt = null)
        {
            var now = filteredAt ?? DateTime.UtcNow;
            var items = priorityState?.Items ?? new List<EventCyclePortfolioItem>();
            if (filter == null || filter.FilterId == FilterNone)
            {
                return new EventCyclePortfolioFilteredViewState
                {
                    ActiveFilter = null,
                    FilteredItems = new List<EventCyclePortfolioItem>(items),
                    FilteredCount = items.Count,
                    FilterSummary = $"Sem filtro. {items.Count} item(ns).",
                    HighestPriorityFilteredItem = items.FirstOrDefault(),
                    LastFilteredAt = now
                };
            }

            var filtered = items.Where(i => MatchesFilter(i, filter)).ToList();
            var top = filtered.OrderByDescending(i => i.PriorityScore).FirstOrDefault();
            var summary = $"{filter.Name}: {filtered.Count} de {items.Count} item(ns).";

            return new EventCyclePortfolioFilteredViewState
            {
                ActiveFilter = filter,
                FilteredItems = filtered,
                FilteredCount = filtered.Count,
                FilterSummary = summary,
                HighestPriorityFilteredItem = top,
                LastFilteredAt = now
            };
        }

        /// <summary>Aplica o filtro atualmente selecionado no store (se existir).</summary>
        public static EventCyclePortfolioFilteredViewState ApplyActiveFilterOrNone(EventCyclePortfolioPriorityState priorityState, DateTime? filteredAt = null)
        {
            var filterId = ActivePortfolioFilterStore.GetActiveFilterId();
            if (string.IsNullOrEmpty(filterId))
                return ApplyFilter(priorityState, null, filteredAt);
            var filter = GetAvailableFilters().FirstOrDefault(f => f.FilterId == filterId);
            return ApplyFilter(priorityState, filter, filteredAt);
        }

        private static bool MatchesFilter(EventCyclePortfolioItem item, EventCyclePortfolioFilter filter)
        {
            if (filter.IncludeBlockedOnly)
                if (!(item.RiskLevelLabel ?? "").Contains("Bloqueado")) return false;
            if (filter.IncludeClosingSoonOnly)
            {
                var soon = (item.PriorityReason ?? "").Contains("Perto de fechamento") || (item.ClosureStatus ?? "").Contains("Aceite") || (item.CommercialStageLabel ?? "").ToLowerInvariant().Contains("final");
                if (!soon) return false;
            }
            if (filter.IncludeRecoveryOpportunitiesOnly)
                if (string.IsNullOrEmpty(item.TopRecoveryAction) || string.IsNullOrEmpty(item.SimulatedBestScenarioDelta)) return false;
            if (filter.IncludeCompletedWithIssuesOnly)
            {
                var closure = item.ClosureStatus ?? "";
                var closed = closure.Contains("Concluído") || closure.Contains("Encerrado") || closure.ToLowerInvariant().Contains("closed");
                if (!closed || item.OverallCyclePerformanceScore >= 70) return false;
            }
            if (filter.IncludeExecutionActiveOnly)
            {
                var closure = item.ClosureStatus ?? "";
                var closed = closure.Contains("Concluído") || closure.Contains("Encerrado") || closure.ToLowerInvariant().Contains("closed");
                var blocked = (item.RiskLevelLabel ?? "").Contains("Bloqueado");
                if (closed || blocked) return false;
            }
            if (!string.IsNullOrEmpty(filter.RiskLevelFilter))
            {
                if (filter.RiskLevelFilter == "AtRisk")
                {
                    var r = item.RiskLevelLabel ?? "";
                    if (!r.Contains("Em risco") && !r.Contains("Crítico") && !r.Contains("Alertas bloqueantes")) return false;
                }
                else if (filter.RiskLevelFilter == "Blocked" && !(item.RiskLevelLabel ?? "").Contains("Bloqueado"))
                    return false;
            }
            if (!string.IsNullOrEmpty(filter.PriorityLevelFilter) && filter.PriorityLevelFilter == "High")
                if (item.PriorityScore < 70) return false;
            return true;
        }

        /// <summary>Define o filtro ativo (para uso pela UI).</summary>
        public static void SetActiveFilter(string filterId) => ActivePortfolioFilterStore.SetActiveFilter(filterId);

        /// <summary>Limpa o filtro ativo.</summary>
        public static void ClearActiveFilter() => ActivePortfolioFilterStore.ClearFilter();
    }
}
