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

namespace EventsAppQuest.Web.Application
{
    /// <summary>
    /// Armazenamento em memória da trilha de decisões executivas por caso. Mock; sem persistência real.
    /// </summary>
    public static class ExecutiveDecisionTrailStore
    {
        private static readonly Dictionary<string, EventCycleExecutiveDecision> ByDecisionId = new Dictionary<string, EventCycleExecutiveDecision>();
        private static readonly object Lock = new object();
        private static int _counter;

        public static string Add(string cycleId, string title, string summary,
            EventCycleExecutiveDecisionCategory category, EventCycleExecutiveDecisionOutcome outcome,
            string reason, EventCycleExecutiveDecisionRole role,
            string relatedSnapshotId = null, string relatedSectionKey = null, string notes = null)
        {
            if (string.IsNullOrEmpty(cycleId)) return null;
            lock (Lock)
            {
                _counter++;
                var decisionId = "Dec_" + cycleId + "_" + _counter + "_" + DateTime.UtcNow.Ticks;
                var now = DateTime.UtcNow;
                var decision = new EventCycleExecutiveDecision
                {
                    DecisionId = decisionId,
                    CycleId = cycleId,
                    Title = title ?? "Sem título",
                    Summary = summary,
                    DecisionCategory = category,
                    DecisionOutcome = outcome,
                    DecisionReason = reason,
                    DecidedByRole = role,
                    RelatedSnapshotId = relatedSnapshotId,
                    RelatedSectionKey = relatedSectionKey,
                    CreatedAt = now,
                    Notes = notes
                };
                ByDecisionId[decisionId] = decision;
                return decisionId;
            }
        }

        public static void Update(string decisionId, string title, string summary,
            EventCycleExecutiveDecisionCategory? category, EventCycleExecutiveDecisionOutcome? outcome,
            string reason, EventCycleExecutiveDecisionRole? role,
            string relatedSnapshotId, string relatedSectionKey, string notes)
        {
            lock (Lock)
            {
                if (!ByDecisionId.TryGetValue(decisionId, out var d)) return;
                if (title != null) d.Title = title;
                if (summary != null) d.Summary = summary;
                if (category.HasValue) d.DecisionCategory = category.Value;
                if (outcome.HasValue) d.DecisionOutcome = outcome.Value;
                if (reason != null) d.DecisionReason = reason;
                if (role.HasValue) d.DecidedByRole = role.Value;
                if (relatedSnapshotId != null) d.RelatedSnapshotId = relatedSnapshotId;
                if (relatedSectionKey != null) d.RelatedSectionKey = relatedSectionKey;
                if (notes != null) d.Notes = notes;
            }
        }

        public static void Remove(string decisionId)
        {
            if (string.IsNullOrEmpty(decisionId)) return;
            lock (Lock)
                ByDecisionId.Remove(decisionId);
        }

        public static EventCycleExecutiveDecision Get(string decisionId)
        {
            if (string.IsNullOrEmpty(decisionId)) return null;
            lock (Lock)
                return ByDecisionId.TryGetValue(decisionId, out var d) ? d : null;
        }

        public static List<EventCycleExecutiveDecision> GetByCycle(string cycleId)
        {
            if (string.IsNullOrEmpty(cycleId)) return new List<EventCycleExecutiveDecision>();
            lock (Lock)
            {
                return ByDecisionId.Values
                    .Where(d => d != null && d.CycleId == cycleId)
                    .OrderByDescending(d => d.CreatedAt)
                    .ToList();
            }
        }

        public static List<EventCycleExecutiveDecision> GetAll()
        {
            lock (Lock)
                return ByDecisionId.Values.Where(d => d != null).OrderByDescending(d => d.CreatedAt).ToList();
        }

        public static int GetTotalCount()
        {
            lock (Lock) return ByDecisionId.Count;
        }

        public static bool HasTrail(string cycleId)
        {
            if (string.IsNullOrEmpty(cycleId)) return false;
            lock (Lock)
                return ByDecisionId.Values.Any(d => d != null && d.CycleId == cycleId);
        }
    }
}
