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>
    /// Gera e gere o checklist operacional de preparação a partir do pedido, readiness e escopo; marca conclusões e confirmação final (mock).
    /// </summary>
    public static class ProducerPreparationChecklistController
    {
        /// <summary>Garante que o pedido tem um checklist (gera base se não existir). Devolve o estado actual.</summary>
        public static ProducerPreparationChecklistState EnsureChecklist(string orderId)
        {
            if (string.IsNullOrEmpty(orderId)) return null;
            var existing = PreparationChecklistStore.GetItems(orderId);
            if (existing.Count == 0)
                GenerateBaseChecklist(orderId);
            return GetChecklistState(orderId);
        }

        /// <summary>Gera checklist base a partir do pedido, readiness e escopo.</summary>
        public static void GenerateBaseChecklist(string orderId)
        {
            if (string.IsNullOrEmpty(orderId)) return;
            var order = HandoffStore.GetOrderById(orderId);
            if (order == null) return;
            var readiness = ProducerExecutionReadinessController.Evaluate(orderId);
            var scopeState = ScopeRevisionStore.GetConfirmationState(orderId);

            var items = new List<ProducerPreparationChecklistItem>();
            var id = 0;

            var itemAcceptance = CreateItem(orderId, ++id, "Pedido aceite pelo produtor", "O produtor aceitou o pedido.", ProducerPreparationChecklistCategory.Approval, true);
            if (readiness != null && readiness.IsProducerAccepted) MarkItemCompletedInternal(itemAcceptance, "Sistema");
            items.Add(itemAcceptance);

            var itemScope = CreateItem(orderId, ++id, "Escopo confirmado", "Escopo confirmado por hotel e produtor.", ProducerPreparationChecklistCategory.Scope, true);
            if (scopeState != null && scopeState.Status == ProducerScopeConfirmationStatus.Confirmed) MarkItemCompletedInternal(itemScope, "Sistema");
            items.Add(itemScope);

            var itemClarification = CreateItem(orderId, ++id, "Sem pendências de esclarecimento", "Não há dúvidas ou pedidos de esclarecimento em aberto.", ProducerPreparationChecklistCategory.Communication, true);
            if (readiness != null && !readiness.HasPendingClarifications) MarkItemCompletedInternal(itemClarification, "Sistema");
            items.Add(itemClarification);

            items.Add(CreateItem(orderId, ++id, "Logística verificada", "Datas, local e acesso confirmados.", ProducerPreparationChecklistCategory.Logistics, false));
            items.Add(CreateItem(orderId, ++id, "Materiais confirmados", "Materiais e equipamento previstos.", ProducerPreparationChecklistCategory.Materials, false));
            items.Add(CreateItem(orderId, ++id, "Equipa alocada", "Equipa atribuída ao evento.", ProducerPreparationChecklistCategory.Team, false));

            PreparationChecklistStore.SetItems(orderId, items);
        }

        public static ProducerPreparationChecklistState GetChecklistState(string orderId)
        {
            if (string.IsNullOrEmpty(orderId)) return null;
            var items = PreparationChecklistStore.GetItems(orderId).ToList();
            var state = new ProducerPreparationChecklistState
            {
                ProducerOrderId = orderId,
                Items = items,
                TotalItems = items.Count,
                CompletedItems = items.Count(i => i.IsCompleted),
                RequiredItems = items.Count(i => i.IsRequired),
                CompletedRequiredItems = items.Count(i => i.IsRequired && i.IsCompleted),
                IsPreparationConfirmed = PreparationChecklistStore.IsPreparationConfirmed(orderId),
                PreparationConfirmedAt = PreparationChecklistStore.GetPreparationConfirmedAt(orderId),
                PreparationSummary = PreparationChecklistStore.GetPreparationSummary(orderId)
            };
            return state;
        }

        /// <summary>Marca item como concluído.</summary>
        public static void MarkItemCompleted(string orderId, string itemId, string completedByRole)
        {
            var item = PreparationChecklistStore.GetItem(itemId);
            if (item == null || item.ProducerOrderId != orderId) return;
            MarkItemCompletedInternal(item, completedByRole ?? "Producer");
            PreparationChecklistStore.AddOrUpdateItem(item);
        }

        /// <summary>Marca item como não concluído.</summary>
        public static void MarkItemIncomplete(string orderId, string itemId)
        {
            var item = PreparationChecklistStore.GetItem(itemId);
            if (item == null || item.ProducerOrderId != orderId) return;
            item.IsCompleted = false;
            item.CompletedByRole = null;
            item.CompletedAt = null;
            PreparationChecklistStore.AddOrUpdateItem(item);
        }

        /// <summary>Confirma preparação final. Só permite quando existe checklist com todos os obrigatórios concluídos.</summary>
        public static bool ConfirmPreparation(string orderId, string summary)
        {
            if (string.IsNullOrEmpty(orderId)) return false;
            var state = GetChecklistState(orderId);
            if (state == null) return false;
            if (state.RequiredItems == 0 || state.CompletedRequiredItems < state.RequiredItems)
                return false;
            PreparationChecklistStore.SetPreparationConfirmed(orderId, summary ?? "Preparação confirmada pelo produtor.");
            return true;
        }

        /// <summary>Indica se ainda há pendências obrigatórias (required items não concluídos).</summary>
        public static bool HasRequiredPending(string orderId)
        {
            var state = GetChecklistState(orderId);
            return state != null && state.CompletedRequiredItems < state.RequiredItems;
        }

        private static ProducerPreparationChecklistItem CreateItem(string orderId, int seq, string title, string summary, ProducerPreparationChecklistCategory category, bool isRequired)
        {
            return new ProducerPreparationChecklistItem
            {
                ItemId = "chk-" + orderId + "-" + seq,
                ProducerOrderId = orderId,
                Title = title,
                Summary = summary,
                Category = category,
                IsRequired = isRequired,
                IsCompleted = false,
                CompletedByRole = null,
                CompletedAt = null,
                Notes = null
            };
        }

        private static void MarkItemCompletedInternal(ProducerPreparationChecklistItem item, string role)
        {
            item.IsCompleted = true;
            item.CompletedByRole = role;
            item.CompletedAt = DateTime.UtcNow;
        }
    }
}
