using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using EventsAppQuest.Application.Services;
using EventsAppQuest.Core;
using EventsAppQuest.Domain.Enums;
using EventsAppQuest.Domain.Models;

namespace EventsAppQuest.Presentation
{
    /// <summary>
    /// Exibe transições entre fases da jornada: origem, destino, tipo, tempo, reconfiguração, coordenação fornecedor, fluidez e observações.
    /// </summary>
    public class EventMomentTransitionView : MonoBehaviour
    {
        private const string Title = "Transições da Jornada / Continuidade da Experiência";
        private const string NenhumProjeto = "Nenhum projeto ou proposta ativa.";
        private const string Tempo = "Tempo: ";
        private const string Reconfig = "Reconfig. espaço";
        private const string CoordForn = "Coord. fornecedor";
        private const string Fluidez = "Fluidez: ";
        private const string NenhumaTransicao = "Nenhuma transição. Planeje os momentos da jornada primeiro.";

        private AppSession _session;
        private IEventMomentPlanningService _planningService;
        private IEventMomentTransitionService _transitionService;
        private Transform _contentRoot;
        private Font _font;

        private void Start()
        {
            _session = ServiceRegistry.Instance.Get<AppSession>();
            _planningService = ServiceRegistry.Instance.Get<IEventMomentPlanningService>();
            _transitionService = ServiceRegistry.Instance.Get<IEventMomentTransitionService>();
            if (_session != null)
                _session.OnSessionChanged += UpdateContent;

            _font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
            BuildUI();
            UpdateContent();
        }

        private void OnDestroy()
        {
            if (_session != null)
                _session.OnSessionChanged -= UpdateContent;
        }

        private void BuildUI()
        {
            var layout = gameObject.GetComponent<VerticalLayoutGroup>();
            if (layout == null)
            {
                layout = gameObject.AddComponent<VerticalLayoutGroup>();
                layout.spacing = 6;
                layout.padding = new RectOffset(12, 12, 12, 12);
                layout.childForceExpandHeight = false;
                layout.childForceExpandWidth = true;
            }

            var titleGo = new GameObject("Title");
            titleGo.transform.SetParent(transform, false);
            titleGo.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 22);
            var titleText = titleGo.AddComponent<Text>();
            titleText.text = Title;
            titleText.font = _font;
            titleText.fontSize = 16;
            titleText.fontStyle = FontStyle.Bold;

            _contentRoot = new GameObject("ContentRoot").transform;
            _contentRoot.SetParent(transform, false);
            _contentRoot.gameObject.AddComponent<LayoutElement>().preferredHeight = 280;
            var vlg = _contentRoot.gameObject.AddComponent<VerticalLayoutGroup>();
            vlg.spacing = 6;
            vlg.childForceExpandHeight = false;
            vlg.childForceExpandWidth = true;
        }

        private void UpdateContent()
        {
            ClearChildren(_contentRoot);

            var project = _session?.CurrentProject;
            var active = project?.GetActiveProposal();
            if (project == null || active == null)
            {
                AppendText(_contentRoot, NenhumProjeto);
                return;
            }

            if (active.MomentPlans == null || active.MomentPlans.Count < 2)
            {
                var plans = _planningService?.GenerateMomentPlan(project, active);
                if (plans != null) active.MomentPlans = new List<ProposalMomentPlan>(plans);
                if (active.MomentPlans == null || active.MomentPlans.Count < 2)
                {
                    AppendText(_contentRoot, NenhumaTransicao);
                    return;
                }
            }

            var transitions = _transitionService?.GenerateTransitions(project, active);
            if (transitions == null || transitions.Count == 0)
            {
                AppendText(_contentRoot, NenhumaTransicao);
                return;
            }

            active.MomentTransitions = new List<EventMomentTransition>(transitions);

            var phases = (_planningService?.GetAvailablePhases(project.EventTemplateId) ?? new List<EventMomentPhase>())
                .ToDictionary(p => p.Id, p => p.Name);

            foreach (var t in transitions)
            {
                var fromName = phases.TryGetValue(t.FromPhaseId, out var fn) ? fn : t.FromPhaseId;
                var toName = phases.TryGetValue(t.ToPhaseId, out var tn) ? tn : t.ToPhaseId;

                var card = new GameObject("TransitionCard");
                card.transform.SetParent(_contentRoot, false);
                card.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 58);
                var cardVlg = card.AddComponent<VerticalLayoutGroup>();
                cardVlg.spacing = 2;
                cardVlg.padding = new RectOffset(8, 8, 8, 8);
                cardVlg.childForceExpandHeight = false;
                cardVlg.childForceExpandWidth = true;
                card.AddComponent<Image>().color = new Color(0.96f, 0.97f, 0.95f, 1f);

                var nameLine = new GameObject("Name");
                nameLine.transform.SetParent(card.transform, false);
                nameLine.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
                var nameText = nameLine.AddComponent<Text>();
                nameText.text = fromName + " → " + toName + " — " + TransitionTypeText(t.TransitionType) + " | " + Tempo + t.EstimatedTransitionMinutes + " min | " + Fluidez + t.SmoothnessScore;
                nameText.font = _font;
                nameText.fontSize = 13;
                nameText.fontStyle = FontStyle.Bold;

                var detailParts = new List<string>();
                if (t.RequiresSpaceReset) detailParts.Add(Reconfig);
                if (t.RequiresSupplierCoordination) detailParts.Add(CoordForn);
                if (!string.IsNullOrEmpty(t.Notes)) detailParts.Add(t.Notes);
                if (detailParts.Count > 0)
                {
                    var detailLine = new GameObject("Detail");
                    detailLine.transform.SetParent(card.transform, false);
                    detailLine.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 14);
                    var detailText = detailLine.AddComponent<Text>();
                    detailText.text = string.Join(" | ", detailParts);
                    detailText.font = _font;
                    detailText.fontSize = 10;
                    detailText.color = new Color(0.4f, 0.45f, 0.5f, 1f);
                }
            }
        }

        private static string TransitionTypeText(EventMomentTransitionType type)
        {
            switch (type)
            {
                case EventMomentTransitionType.DirectFlow: return "Fluxo direto";
                case EventMomentTransitionType.Reconfiguration: return "Reconfiguração";
                case EventMomentTransitionType.GuestRelocation: return "Relocação";
                case EventMomentTransitionType.ServiceTurnover: return "Troca de serviço";
                case EventMomentTransitionType.ClosingTransition: return "Encerramento";
                default: return "—";
            }
        }

        private void AppendText(Transform parent, string text)
        {
            var go = new GameObject("TextLine");
            go.transform.SetParent(parent, false);
            go.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
            var t = go.AddComponent<Text>();
            t.text = text;
            t.font = _font;
            t.fontSize = 12;
        }

        private static void ClearChildren(Transform root)
        {
            if (root == null) return;
            for (var i = root.childCount - 1; i >= 0; i--)
                Object.Destroy(root.GetChild(i).gameObject);
        }
    }
}
