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

namespace EventsAppQuest.Web.Producer.Application
{
    /// <summary>
    /// Armazenamento em memória de revisões de escopo e estados de confirmação (mock).
    /// Partilhado entre web do hotel e web do produtor.
    /// </summary>
    public static class ScopeRevisionStore
    {
        private static readonly List<ProducerOrderScopeRevision> Revisions = new List<ProducerOrderScopeRevision>();
        private static readonly List<ProducerScopeConfirmationState> ConfirmationStates = new List<ProducerScopeConfirmationState>();
        private static readonly object Lock = new object();

        public static ProducerOrderScopeRevision AddRevision(ProducerOrderScopeRevision revision)
        {
            if (revision == null) return null;
            lock (Lock)
            {
                Revisions.Add(revision);
                EnsureConfirmationState(revision.ProducerOrderId);
                return revision;
            }
        }

        public static void UpdateRevision(ProducerOrderScopeRevision revision)
        {
            if (revision == null) return;
            lock (Lock)
            {
                var idx = Revisions.FindIndex(r => r.RevisionId == revision.RevisionId);
                if (idx >= 0) Revisions[idx] = revision;
            }
        }

        public static IReadOnlyList<ProducerOrderScopeRevision> GetRevisionsForOrder(string orderId)
        {
            if (string.IsNullOrEmpty(orderId)) return new List<ProducerOrderScopeRevision>();
            lock (Lock)
                return Revisions.Where(r => r.ProducerOrderId == orderId).OrderByDescending(r => r.CreatedAt).ToList();
        }

        public static ProducerOrderScopeRevision GetRevisionById(string revisionId)
        {
            if (string.IsNullOrEmpty(revisionId)) return null;
            lock (Lock)
                return Revisions.FirstOrDefault(r => r.RevisionId == revisionId);
        }

        public static ProducerOrderScopeRevision GetCurrentActiveRevision(string orderId)
        {
            if (string.IsNullOrEmpty(orderId)) return null;
            lock (Lock)
                return Revisions.FirstOrDefault(r => r.ProducerOrderId == orderId && r.IsCurrentActiveRevision);
        }

        public static ProducerScopeConfirmationState GetConfirmationState(string orderId)
        {
            if (string.IsNullOrEmpty(orderId)) return null;
            lock (Lock)
            {
                var state = ConfirmationStates.FirstOrDefault(s => s.OrderId == orderId);
                if (state == null)
                {
                    state = new ProducerScopeConfirmationState { OrderId = orderId, Status = ProducerScopeConfirmationStatus.Draft, ConfirmedRevisionId = null, LastUpdatedAt = null };
                    ConfirmationStates.Add(state);
                }
                return state;
            }
        }

        public static void SetConfirmationState(ProducerScopeConfirmationState state)
        {
            if (state == null) return;
            lock (Lock)
            {
                state.LastUpdatedAt = DateTime.UtcNow;
                var idx = ConfirmationStates.FindIndex(s => s.OrderId == state.OrderId);
                if (idx >= 0)
                    ConfirmationStates[idx] = state;
                else
                    ConfirmationStates.Add(state);
            }
        }

        /// <summary>Marca uma revisão como activa e desmarca as outras do mesmo pedido.</summary>
        public static void SetCurrentActiveRevision(string orderId, string revisionId)
        {
            if (string.IsNullOrEmpty(orderId)) return;
            lock (Lock)
            {
                foreach (var r in Revisions.Where(r => r.ProducerOrderId == orderId))
                {
                    r.IsCurrentActiveRevision = r.RevisionId == revisionId;
                }
            }
        }

        private static void EnsureConfirmationState(string orderId)
        {
            if (string.IsNullOrEmpty(orderId)) return;
            lock (Lock)
            {
                if (ConfirmationStates.Any(s => s.OrderId == orderId)) return;
                ConfirmationStates.Add(new ProducerScopeConfirmationState { OrderId = orderId, Status = ProducerScopeConfirmationStatus.Draft, ConfirmedRevisionId = null, LastUpdatedAt = null });
            }
        }
    }
}
