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>
    /// Controlador de status de execução e acompanhamento operacional pós-preparação (mock).
    /// Iniciar execução, actualizar progresso, registar updates, marcar issue/bloqueio, pausar/retomar, concluir.
    /// </summary>
    public static class ProducerExecutionTrackingController
    {
        /// <summary>Inicia execução. Só permite se a preparação estiver confirmada.</summary>
        public static bool StartExecution(string orderId, string summary = null)
        {
            if (string.IsNullOrEmpty(orderId)) return false;
            if (!PreparationChecklistStore.IsPreparationConfirmed(orderId))
                return false;
            var state = ExecutionTrackingStore.GetOrCreateState(orderId);
            if (state.ExecutionStatus != ProducerExecutionStatus.NotStarted && state.ExecutionStatus != ProducerExecutionStatus.Preparing)
                return false;
            state.ExecutionStatus = ProducerExecutionStatus.InExecution;
            state.StartedAt = state.StartedAt ?? DateTime.UtcNow;
            state.LastUpdatedAt = DateTime.UtcNow;
            state.ProgressPercent = 0;
            state.CurrentExecutionSummary = summary ?? "Execução iniciada.";
            state.IsPaused = false;
            state.IsCompleted = false;
            ExecutionTrackingStore.SetState(state);
            AddUpdateInternal(orderId, ProducerExecutionUpdateType.ProgressUpdate, "Execução iniciada", state.CurrentExecutionSummary, 0, false, false, "Producer");
            return true;
        }

        public static void UpdateProgress(string orderId, int progressPercent, string summary, string createdByRole = "Producer")
        {
            if (string.IsNullOrEmpty(orderId)) return;
            var state = ExecutionTrackingStore.GetOrCreateState(orderId);
            state.ProgressPercent = Math.Max(0, Math.Min(100, progressPercent));
            state.CurrentExecutionSummary = summary ?? state.CurrentExecutionSummary;
            state.LastUpdatedAt = DateTime.UtcNow;
            if (state.ExecutionStatus == ProducerExecutionStatus.NotStarted || state.ExecutionStatus == ProducerExecutionStatus.Preparing)
                state.ExecutionStatus = ProducerExecutionStatus.InExecution;
            ExecutionTrackingStore.SetState(state);
            AddUpdateInternal(orderId, ProducerExecutionUpdateType.ProgressUpdate, "Progresso", summary ?? state.CurrentExecutionSummary, state.ProgressPercent, false, false, createdByRole);
        }

        public static ProducerExecutionUpdate AddUpdate(string orderId, ProducerExecutionUpdateType updateType, string title, string summary, int progressPercent = -1, bool isIssue = false, bool isBlocking = false, string createdByRole = "Producer")
        {
            if (string.IsNullOrEmpty(orderId)) return null;
            var state = ExecutionTrackingStore.GetOrCreateState(orderId);
            if (progressPercent >= 0)
            {
                state.ProgressPercent = Math.Max(0, Math.Min(100, progressPercent));
                state.LastUpdatedAt = DateTime.UtcNow;
            }
            if (isIssue) state.HasIssues = true;
            if (isBlocking) state.ExecutionStatus = ProducerExecutionStatus.Blocked;
            ExecutionTrackingStore.SetState(state);
            return AddUpdateInternal(orderId, updateType, title, summary, progressPercent >= 0 ? progressPercent : state.ProgressPercent, isIssue, isBlocking, createdByRole);
        }

        public static void PauseExecution(string orderId)
        {
            if (string.IsNullOrEmpty(orderId)) return;
            var state = ExecutionTrackingStore.GetOrCreateState(orderId);
            state.ExecutionStatus = ProducerExecutionStatus.Paused;
            state.IsPaused = true;
            state.LastUpdatedAt = DateTime.UtcNow;
            ExecutionTrackingStore.SetState(state);
            AddUpdateInternal(orderId, ProducerExecutionUpdateType.InternalNote, "Execução pausada", "Execução pausada pelo produtor.", state.ProgressPercent, false, false, "Producer");
        }

        public static void ResumeExecution(string orderId)
        {
            if (string.IsNullOrEmpty(orderId)) return;
            var state = ExecutionTrackingStore.GetOrCreateState(orderId);
            state.ExecutionStatus = ProducerExecutionStatus.InExecution;
            state.IsPaused = false;
            state.LastUpdatedAt = DateTime.UtcNow;
            ExecutionTrackingStore.SetState(state);
            AddUpdateInternal(orderId, ProducerExecutionUpdateType.InternalNote, "Execução retomada", "Execução retomada.", state.ProgressPercent, false, false, "Producer");
        }

        public static bool CompleteExecution(string orderId, string completionSummary)
        {
            if (string.IsNullOrEmpty(orderId)) return false;
            var state = ExecutionTrackingStore.GetOrCreateState(orderId);
            state.ExecutionStatus = ProducerExecutionStatus.Completed;
            state.IsCompleted = true;
            state.ProgressPercent = 100;
            state.CompletionSummary = completionSummary ?? "Execução concluída.";
            state.LastUpdatedAt = DateTime.UtcNow;
            ExecutionTrackingStore.SetState(state);
            AddUpdateInternal(orderId, ProducerExecutionUpdateType.Completion, "Execução concluída", state.CompletionSummary, 100, false, false, "Producer");
            return true;
        }

        public static ProducerExecutionStatusState GetState(string orderId) => ExecutionTrackingStore.GetOrCreateState(orderId);
        public static IReadOnlyList<ProducerExecutionUpdate> GetUpdates(string orderId, int maxCount = 20) => ExecutionTrackingStore.GetUpdates(orderId, maxCount);

        private static ProducerExecutionUpdate AddUpdateInternal(string orderId, ProducerExecutionUpdateType updateType, string title, string summary, int progressPercent, bool isIssue, bool isBlocking, string role)
        {
            var update = new ProducerExecutionUpdate
            {
                UpdateId = "upd-" + Guid.NewGuid().ToString("N").Substring(0, 8),
                ProducerOrderId = orderId,
                Title = title,
                Summary = summary ?? "",
                ProgressPercent = progressPercent,
                IsIssue = isIssue,
                IsBlocking = isBlocking,
                CreatedAt = DateTime.UtcNow,
                CreatedByRole = role ?? "Producer",
                UpdateType = updateType
            };
            ExecutionTrackingStore.AddUpdate(update);
            return update;
        }
    }
}
