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

namespace EventsAppQuest.Presentation
{
    /// <summary>
    /// Exibe estados visuais da cena por fase: ordem, fase, nome, descrição, itens ativos, zonas, hotspots principais e resumo da transição.
    /// </summary>
    public class ProposalSceneStateView : MonoBehaviour
    {
        private const string Title = "Estados da Cena / Evolução Visual do Evento";
        private const string NenhumProjeto = "Nenhum projeto ou proposta ativa.";
        private const string NenhumEstado = "Nenhum estado de cena. Preencha os momentos do evento para gerar a evolução visual.";
        private const string Ordem = "Ordem: ";
        private const string Fase = "Fase: ";
        private const string ItensAtivos = "Itens ativos: ";
        private const string ZonasAtivas = "Zonas: ";
        private const string HotspotsPrincipais = "Hotspots: ";
        private const string Transicao = "Transição: ";
        private const string Mood = "Mood: ";

        private AppSession _session;
        private IProposalSceneStateService _sceneStateService;
        private IShowroomService _showroomService;
        private Transform _contentRoot;
        private Font _font;

        private void Start()
        {
            _session = ServiceRegistry.Instance.Get<AppSession>();
            _sceneStateService = ServiceRegistry.Instance.Get<IProposalSceneStateService>();
            _showroomService = ServiceRegistry.Instance.Get<IShowroomService>();
            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 = 360;
            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;
            }

            var list = _sceneStateService?.GenerateSceneStates(project, active);
            if (list == null || list.Count == 0)
            {
                AppendText(_contentRoot, NenhumEstado);
                return;
            }

            active.SceneStates = new List<ProposalSceneState>(list);

            foreach (var state in list.OrderBy(s => s.DisplayOrder))
            {
                var card = new GameObject("SceneStateCard");
                card.transform.SetParent(_contentRoot, false);
                card.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 88);
                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.95f, 0.98f, 1f);

                var headerLine = new GameObject("Header");
                headerLine.transform.SetParent(card.transform, false);
                headerLine.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
                var headerText = headerLine.AddComponent<Text>();
                headerText.text = Ordem + (state.DisplayOrder + 1) + " — " + (state.Name ?? state.RelatedPhaseId) + " (" + Fase + (state.RelatedPhaseId ?? "—") + ")";
                headerText.font = _font;
                headerText.fontSize = 13;
                headerText.fontStyle = FontStyle.Bold;

                if (!string.IsNullOrEmpty(state.Description))
                {
                    var descLine = new GameObject("Desc");
                    descLine.transform.SetParent(card.transform, false);
                    descLine.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 14);
                    var descText = descLine.AddComponent<Text>();
                    descText.text = state.Description;
                    descText.font = _font;
                    descText.fontSize = 11;
                    descText.color = new Color(0.35f, 0.35f, 0.4f, 1f);
                }

                var parts = new List<string>();
                if (state.ActiveShowroomItemIds != null && state.ActiveShowroomItemIds.Count > 0)
                {
                    var names = state.ActiveShowroomItemIds
                        .Select(id => _showroomService?.GetById(id)?.Name)
                        .Where(n => !string.IsNullOrEmpty(n))
                        .Take(3);
                    parts.Add(ItensAtivos + string.Join(", ", names) + (state.ActiveShowroomItemIds.Count > 3 ? "…" : ""));
                }
                if (state.ActiveZoneTypes != null && state.ActiveZoneTypes.Count > 0)
                    parts.Add(ZonasAtivas + string.Join(", ", state.ActiveZoneTypes));
                if (state.PrimaryHotspotIds != null && state.PrimaryHotspotIds.Count > 0)
                    parts.Add(HotspotsPrincipais + state.PrimaryHotspotIds.Count + " destaque(s)");
                if (!string.IsNullOrEmpty(state.VisualMood) && state.VisualMood != "—")
                    parts.Add(Mood + state.VisualMood);
                if (!string.IsNullOrEmpty(state.TransitionFromPreviousSummary))
                    parts.Add(Transicao + state.TransitionFromPreviousSummary);

                if (parts.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(" | ", parts);
                    detailText.font = _font;
                    detailText.fontSize = 10;
                    detailText.color = new Color(0.4f, 0.45f, 0.5f, 1f);
                }
            }
        }

        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);
        }
    }
}
