using System;
using EventsAppQuest.Web.Producer.Core;
using EventsAppQuest.Web.Producer.Domain;

namespace EventsAppQuest.Web.Producer.Application
{
    /// <summary>
    /// Aceite final do hotel: abrir revisão, aceitar/rejeitar/solicitar ajuste, encerrar ciclo (mock).
    /// </summary>
    public static class HotelFinalAcceptanceController
    {
        /// <summary>Indica se o hotel pode fazer revisão final (existe relatório do produtor concluído operacionalmente).</summary>
        public static bool CanHotelReviewFinal(string orderId)
        {
            var report = FinalReportStore.GetReport(orderId);
            return report != null && report.ClosedByProducerAt.HasValue;
        }

        /// <summary>Obtém ou cria o estado de aceite final. Revisão considera-se "aberta" quando o produtor já concluiu e o hotel ainda não decidiu.</summary>
        public static HotelFinalAcceptanceState GetOrCreateState(string orderId)
        {
            if (string.IsNullOrEmpty(orderId)) return null;
            return HotelFinalAcceptanceStore.GetOrCreate(orderId);
        }

        public static HotelFinalAcceptanceState GetState(string orderId) => HotelFinalAcceptanceStore.GetState(orderId);

        /// <summary>Aceitar entrega final. Só quando existe relatório e revisão ainda aberta.</summary>
        public static bool AcceptFinalDelivery(string orderId, string summary = null, string notes = null)
        {
            if (string.IsNullOrEmpty(orderId)) return false;
            if (!CanHotelReviewFinal(orderId)) return false;
            var state = HotelFinalAcceptanceStore.GetOrCreate(orderId);
            if (state.AcceptanceStatus != HotelFinalAcceptanceStatus.PendingReview && state.AcceptanceStatus != HotelFinalAcceptanceStatus.NeedsAdjustment)
                return false;
            state.AcceptanceStatus = HotelFinalAcceptanceStatus.Accepted;
            state.AcceptedAt = DateTime.UtcNow;
            state.RejectedAt = null;
            state.IsHotelAcceptanceOpen = false;
            state.FinalAcceptanceSummary = summary ?? "Entrega aceite pelo hotel.";
            state.HotelAcceptanceNotes = notes;
            state.NeedsFinalAdjustment = false;
            HotelFinalAcceptanceStore.SetState(state);
            ProducerExecutionFinalReportController.SetHotelAcknowledged(orderId);
            return true;
        }

        /// <summary>Rejeitar entrega final.</summary>
        public static bool RejectFinalDelivery(string orderId, string summary = null, string notes = null)
        {
            if (string.IsNullOrEmpty(orderId)) return false;
            if (!CanHotelReviewFinal(orderId)) return false;
            var state = HotelFinalAcceptanceStore.GetOrCreate(orderId);
            if (state.AcceptanceStatus != HotelFinalAcceptanceStatus.PendingReview && state.AcceptanceStatus != HotelFinalAcceptanceStatus.NeedsAdjustment)
                return false;
            state.AcceptanceStatus = HotelFinalAcceptanceStatus.Rejected;
            state.RejectedAt = DateTime.UtcNow;
            state.AcceptedAt = null;
            state.IsHotelAcceptanceOpen = false;
            state.FinalAcceptanceSummary = summary ?? "Entrega rejeitada.";
            state.HotelAcceptanceNotes = notes;
            state.NeedsFinalAdjustment = false;
            HotelFinalAcceptanceStore.SetState(state);
            return true;
        }

        /// <summary>Solicitar ajuste final (sem aceitar nem rejeitar definitivamente).</summary>
        public static bool RequestFinalAdjustment(string orderId, string summary = null, string notes = null)
        {
            if (string.IsNullOrEmpty(orderId)) return false;
            if (!CanHotelReviewFinal(orderId)) return false;
            var state = HotelFinalAcceptanceStore.GetOrCreate(orderId);
            state.AcceptanceStatus = HotelFinalAcceptanceStatus.NeedsAdjustment;
            state.NeedsFinalAdjustment = true;
            state.IsHotelAcceptanceOpen = true;
            state.FinalAcceptanceSummary = summary ?? "Ajuste final solicitado.";
            state.HotelAcceptanceNotes = notes;
            HotelFinalAcceptanceStore.SetState(state);
            return true;
        }

        /// <summary>Encerrar formalmente o ciclo do pedido. Apenas quando o hotel já aceitou ou rejeitou.</summary>
        public static bool CloseOrderCycle(string orderId, string notes = null)
        {
            if (string.IsNullOrEmpty(orderId)) return false;
            var state = HotelFinalAcceptanceStore.GetOrCreate(orderId);
            if (state.AcceptanceStatus != HotelFinalAcceptanceStatus.Accepted && state.AcceptanceStatus != HotelFinalAcceptanceStatus.Rejected)
                return false;
            state.IsOrderCycleClosed = true;
            state.ClosedAt = DateTime.UtcNow;
            state.AcceptanceStatus = HotelFinalAcceptanceStatus.Closed;
            if (!string.IsNullOrEmpty(notes))
                state.HotelAcceptanceNotes = (state.HotelAcceptanceNotes ?? "") + "\n[Encerramento] " + notes;
            HotelFinalAcceptanceStore.SetState(state);
            return true;
        }

        public static bool IsOrderCycleClosed(string orderId) => HotelFinalAcceptanceStore.IsOrderCycleClosed(orderId);
    }
}
