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

namespace EventsAppQuest.Presentation
{
    /// <summary>
    /// Exibe capacidade do espaço e adequação operacional da proposta (convidados do briefing, capacidade estimada, faixa recomendada, status, riscos).
    /// </summary>
    public class SpaceCapacityView : MonoBehaviour
    {
        private const string Title = "Capacidade do Espaço / Adequação Operacional";
        private const string NenhumProjeto = "Nenhum projeto ou proposta ativa.";
        private const string ConvidadosBriefing = "Convidados (briefing): ";
        private const string CapacidadeEstimada = "Capacidade estimada da proposta: ";
        private const string FaixaRecomendada = "Faixa recomendada: ";
        private const string StatusOperacional = "Status: ";
        private const string Confortavel = "Confortável";
        private const string NoLimite = "No limite";
        private const string AcimaCapacidade = "Acima da capacidade";
        private const string Indefinido = "—";
        private const string Riscos = "Riscos / Avisos";

        private AppSession _session;
        private ISpaceCapacityEvaluationService _capacityService;
        private Transform _contentRoot;
        private Font _font;

        private void Start()
        {
            _session = ServiceRegistry.Instance.Get<AppSession>();
            _capacityService = ServiceRegistry.Instance.Get<ISpaceCapacityEvaluationService>();
            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 = 140;
            var vlg = _contentRoot.gameObject.AddComponent<VerticalLayoutGroup>();
            vlg.spacing = 4;
            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 cap = _capacityService?.Evaluate(project, active);
            if (cap == null)
            {
                AppendText(_contentRoot, "Avaliação de capacidade não disponível.");
                return;
            }

            AppendText(_contentRoot, ConvidadosBriefing + (cap.GuestCountFromBrief > 0 ? cap.GuestCountFromBrief.ToString() : Indefinido));
            AppendText(_contentRoot, CapacidadeEstimada + cap.EstimatedCapacityMin + "–" + cap.EstimatedCapacityMax);
            AppendText(_contentRoot, FaixaRecomendada + (cap.RecommendedRangeText ?? Indefinido));
            AppendText(_contentRoot, StatusOperacional + StatusText(cap.Status));
            if (cap.OperationalRisks != null && cap.OperationalRisks.Count > 0)
            {
                var riskGo = new GameObject("RisksLabel");
                riskGo.transform.SetParent(_contentRoot, false);
                riskGo.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
                var riskLabel = riskGo.AddComponent<Text>();
                riskLabel.text = Riscos + ":";
                riskLabel.font = _font;
                riskLabel.fontSize = 12;
                riskLabel.fontStyle = FontStyle.Bold;
                foreach (var r in cap.OperationalRisks)
                {
                    var line = new GameObject("Risk");
                    line.transform.SetParent(_contentRoot, false);
                    line.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 14);
                    var t = line.AddComponent<Text>();
                    t.text = "• " + r;
                    t.font = _font;
                    t.fontSize = 11;
                    t.color = new Color(0.6f, 0.3f, 0.2f, 1f);
                }
            }
        }

        private static string StatusText(CapacityOperationalStatus s)
        {
            switch (s)
            {
                case CapacityOperationalStatus.Comfortable: return Confortavel;
                case CapacityOperationalStatus.AtLimit: return NoLimite;
                case CapacityOperationalStatus.OverCapacity: return AcimaCapacidade;
                default: return Indefinido;
            }
        }

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