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

namespace EventsAppQuest.Presentation
{
    /// <summary>
    /// Exibe o resultado da validação da composição da proposta (itens x slots).
    /// Status geral, avisos e inconsistências de forma simples e legível.
    /// Usa referências explícitas a containers (sem Find por nome).
    /// </summary>
    public class CompositionValidationView : MonoBehaviour
    {
        private const string Title = "Validação da composição";
        private const string ValidarComposicao = "Validar composição";
        private const string NenhumProjeto = "Nenhum projeto iniciado.";
        private const string ExecuteValidacao = "Clique em \"Validar composição\" para verificar a proposta.";
        private const string StatusOk = "Composição válida.";
        private const string StatusAvisos = "Composição com avisos.";
        private const string StatusInvalida = "Composição com inconsistências.";
        private const string Avisos = "Avisos";
        private const string Inconsistencias = "Inconsistências";

        private AppSession _session;
        private Transform _statusRoot;
        private Transform _warningsRoot;
        private Transform _inconsistenciesRoot;
        private Font _font;

        private void Start()
        {
            _session = ServiceRegistry.Instance.Get<AppSession>();
            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 = 8;
                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;

            var buttonGo = new GameObject("ValidateButton");
            buttonGo.transform.SetParent(transform, false);
            buttonGo.AddComponent<RectTransform>().sizeDelta = new Vector2(160, 28);
            var buttonLE = buttonGo.AddComponent<LayoutElement>();
            buttonLE.preferredWidth = 160;
            buttonLE.preferredHeight = 28;
            var button = buttonGo.AddComponent<Button>();
            buttonGo.AddComponent<Image>().color = new Color(0.4f, 0.65f, 0.4f, 1f);
            var buttonTextGo = new GameObject("Text");
            buttonTextGo.transform.SetParent(buttonGo.transform, false);
            var buttonTextRt = buttonTextGo.AddComponent<RectTransform>();
            buttonTextRt.anchorMin = Vector2.zero;
            buttonTextRt.anchorMax = Vector2.one;
            buttonTextRt.offsetMin = Vector2.zero;
            buttonTextRt.offsetMax = Vector2.zero;
            var buttonText = buttonTextGo.AddComponent<Text>();
            buttonText.text = ValidarComposicao;
            buttonText.font = _font;
            buttonText.fontSize = 13;
            buttonText.alignment = TextAnchor.MiddleCenter;
            button.onClick.AddListener(OnValidateClicked);

            _statusRoot = new GameObject("StatusRoot").transform;
            _statusRoot.SetParent(transform, false);
            var statusLE = _statusRoot.gameObject.AddComponent<LayoutElement>();
            statusLE.preferredHeight = 22;
            var statusVlg = _statusRoot.gameObject.AddComponent<VerticalLayoutGroup>();
            statusVlg.childForceExpandHeight = false;
            statusVlg.childForceExpandWidth = true;

            var warningsLabel = new GameObject("WarningsLabel");
            warningsLabel.transform.SetParent(transform, false);
            warningsLabel.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 18);
            var warningsLabelText = warningsLabel.AddComponent<Text>();
            warningsLabelText.text = Avisos;
            warningsLabelText.font = _font;
            warningsLabelText.fontSize = 13;
            warningsLabelText.fontStyle = FontStyle.Bold;

            _warningsRoot = new GameObject("WarningsRoot").transform;
            _warningsRoot.SetParent(transform, false);
            var warnLE = _warningsRoot.gameObject.AddComponent<LayoutElement>();
            warnLE.preferredHeight = 50;
            var warnVlg = _warningsRoot.gameObject.AddComponent<VerticalLayoutGroup>();
            warnVlg.spacing = 2;
            warnVlg.childForceExpandHeight = false;
            warnVlg.childForceExpandWidth = true;

            var inconsistenciesLabel = new GameObject("InconsistenciesLabel");
            inconsistenciesLabel.transform.SetParent(transform, false);
            inconsistenciesLabel.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 18);
            var incLabelText = inconsistenciesLabel.AddComponent<Text>();
            incLabelText.text = Inconsistencias;
            incLabelText.font = _font;
            incLabelText.fontSize = 13;
            incLabelText.fontStyle = FontStyle.Bold;

            _inconsistenciesRoot = new GameObject("InconsistenciesRoot").transform;
            _inconsistenciesRoot.SetParent(transform, false);
            var incLE = _inconsistenciesRoot.gameObject.AddComponent<LayoutElement>();
            incLE.preferredHeight = 60;
            var incVlg = _inconsistenciesRoot.gameObject.AddComponent<VerticalLayoutGroup>();
            incVlg.spacing = 2;
            incVlg.childForceExpandHeight = false;
            incVlg.childForceExpandWidth = true;
        }

        private void OnValidateClicked()
        {
            _session?.ValidateComposition();
        }

        private void UpdateContent()
        {
            ClearChildren(_statusRoot);
            ClearChildren(_warningsRoot);
            ClearChildren(_inconsistenciesRoot);

            var project = _session?.CurrentProject;
            if (project == null)
            {
                AppendText(_statusRoot, NenhumProjeto);
                return;
            }

            var result = project.LastCompositionValidation;
            if (result == null)
            {
                AppendText(_statusRoot, ExecuteValidacao);
                return;
            }

            switch (result.Status)
            {
                case CompositionValidationStatus.Valid:
                    AppendText(_statusRoot, StatusOk);
                    break;
                case CompositionValidationStatus.HasWarnings:
                    AppendText(_statusRoot, StatusAvisos);
                    break;
                case CompositionValidationStatus.Invalid:
                    AppendText(_statusRoot, StatusInvalida);
                    break;
                default:
                    AppendText(_statusRoot, result.Status.ToString());
                    break;
            }

            foreach (var w in result.Warnings ?? new List<ValidationMessage>())
                AppendMessage(_warningsRoot, w.Message, false);
            foreach (var i in result.Inconsistencies ?? new List<ValidationMessage>())
                AppendMessage(_inconsistenciesRoot, i.Message, true);
        }

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

        private void AppendMessage(Transform parent, string message, bool isError)
        {
            var go = new GameObject("Msg");
            go.transform.SetParent(parent, false);
            go.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
            var t = go.AddComponent<Text>();
            t.text = "• " + message;
            t.font = _font;
            t.fontSize = 12;
            t.color = isError ? new Color(0.7f, 0.2f, 0.2f, 1f) : new Color(0.4f, 0.35f, 0.1f, 1f);
        }

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