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 presets de layout / cenários base disponíveis para a categoria/template atual.
    /// Permite aplicar preset ao projeto e restaurar composição padrão.
    /// Usa referências explícitas a containers (sem Find por nome).
    /// </summary>
    public class LayoutPresetView : MonoBehaviour
    {
        private const string Title = "Presets de Layout / Cenários Base";
        private const string NenhumProjeto = "Nenhum projeto iniciado. Inicie um projeto para aplicar presets.";
        private const string Aplicar = "Aplicar";
        private const string Padrao = " (padrão)";
        private const string RestaurarPadrao = "Restaurar composição padrão";

        private AppSession _session;
        private ILayoutPresetService _presetService;
        private Transform _presetsRoot;
        private Font _font;

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

            _presetsRoot = new GameObject("PresetsRoot").transform;
            _presetsRoot.SetParent(transform, false);
            var presetsLE = _presetsRoot.gameObject.AddComponent<LayoutElement>();
            presetsLE.preferredHeight = 180;
            var presetsVlg = _presetsRoot.gameObject.AddComponent<VerticalLayoutGroup>();
            presetsVlg.spacing = 6;
            presetsVlg.childForceExpandHeight = false;
            presetsVlg.childForceExpandWidth = true;

            var restoreGo = new GameObject("RestoreButton");
            restoreGo.transform.SetParent(transform, false);
            restoreGo.AddComponent<RectTransform>().sizeDelta = new Vector2(220, 26);
            var restoreLE = restoreGo.AddComponent<LayoutElement>();
            restoreLE.preferredWidth = 220;
            restoreLE.preferredHeight = 26;
            var restoreBtn = restoreGo.AddComponent<Button>();
            restoreGo.AddComponent<Image>().color = new Color(0.9f, 0.85f, 0.7f, 1f);
            var restoreTextGo = new GameObject("Text");
            restoreTextGo.transform.SetParent(restoreGo.transform, false);
            var restoreTextRt = restoreTextGo.AddComponent<RectTransform>();
            restoreTextRt.anchorMin = Vector2.zero;
            restoreTextRt.anchorMax = Vector2.one;
            restoreTextRt.offsetMin = Vector2.zero;
            restoreTextRt.offsetMax = Vector2.zero;
            var restoreText = restoreTextGo.AddComponent<Text>();
            restoreText.text = RestaurarPadrao;
            restoreText.font = _font;
            restoreText.fontSize = 12;
            restoreText.alignment = TextAnchor.MiddleCenter;
            restoreBtn.onClick.AddListener(OnRestoreClicked);
        }

        private void OnRestoreClicked()
        {
            _session?.RestoreDefaultComposition();
        }

        private void UpdateContent()
        {
            ClearChildren(_presetsRoot);

            if (_presetService == null) return;

            var project = _session?.CurrentProject;
            IReadOnlyList<EventLayoutPreset> presets;
            if (project != null)
                presets = _presetService.GetAvailableForProject(project);
            else
            {
                var templateId = _session?.SelectedTemplateId;
                var categoryId = _session?.SelectedCategoryId;
                if (!string.IsNullOrEmpty(templateId))
                    presets = _presetService.GetByTemplateId(templateId);
                else if (!string.IsNullOrEmpty(categoryId))
                    presets = _presetService.GetByCategoryId(categoryId);
                else
                    presets = new List<EventLayoutPreset>();
            }

            if (project == null && presets.Count == 0)
            {
                AppendText(_presetsRoot, NenhumProjeto);
                return;
            }

            if (project == null)
            {
                AppendText(_presetsRoot, NenhumProjeto);
                foreach (var p in presets)
                    AppendPresetRow(_presetsRoot, p, null);
                return;
            }

            foreach (var preset in presets)
                AppendPresetRow(_presetsRoot, preset, preset.Id);
        }

        private void AppendPresetRow(Transform parent, EventLayoutPreset preset, string presetIdForApply)
        {
            var row = new GameObject($"Preset_{preset.Id}");
            row.transform.SetParent(parent, false);
            var rowRt = row.AddComponent<RectTransform>();
            rowRt.sizeDelta = new Vector2(0, 0);
            var rowVlg = row.AddComponent<VerticalLayoutGroup>();
            rowVlg.spacing = 4;
            rowVlg.padding = new RectOffset(6, 4, 4, 4);
            rowVlg.childForceExpandHeight = false;
            rowVlg.childForceExpandWidth = true;
            row.AddComponent<Image>().color = new Color(1f, 1f, 1f, 0.5f);

            var line1 = new GameObject("Line1");
            line1.transform.SetParent(row.transform, false);
            var line1Hlg = line1.AddComponent<HorizontalLayoutGroup>();
            line1Hlg.spacing = 8;
            line1Hlg.childForceExpandWidth = false;
            line1Hlg.childForceExpandHeight = true;
            line1.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 20);

            var nameGo = new GameObject("Name");
            nameGo.transform.SetParent(line1.transform, false);
            nameGo.AddComponent<RectTransform>().sizeDelta = new Vector2(200, 18);
            var nameLE = nameGo.AddComponent<LayoutElement>();
            nameLE.preferredWidth = 200;
            nameLE.flexibleWidth = 1;
            var nameText = nameGo.AddComponent<Text>();
            nameText.text = preset.Name + (preset.IsDefault ? Padrao : "");
            nameText.font = _font;
            nameText.fontSize = 14;
            nameText.fontStyle = FontStyle.Bold;

            if (!string.IsNullOrEmpty(presetIdForApply))
            {
                var btnGo = new GameObject("ApplyBtn");
                btnGo.transform.SetParent(line1.transform, false);
                btnGo.AddComponent<RectTransform>().sizeDelta = new Vector2(70, 22);
                var btnLE = btnGo.AddComponent<LayoutElement>();
                btnLE.preferredWidth = 70;
                btnLE.preferredHeight = 22;
                var btn = btnGo.AddComponent<Button>();
                btnGo.AddComponent<Image>().color = new Color(0.35f, 0.6f, 0.4f, 1f);
                var btnTextGo = new GameObject("Text");
                btnTextGo.transform.SetParent(btnGo.transform, false);
                var btnTextRt = btnTextGo.AddComponent<RectTransform>();
                btnTextRt.anchorMin = Vector2.zero;
                btnTextRt.anchorMax = Vector2.one;
                btnTextRt.offsetMin = Vector2.zero;
                btnTextRt.offsetMax = Vector2.zero;
                var btnText = btnTextGo.AddComponent<Text>();
                btnText.text = Aplicar;
                btnText.font = _font;
                btnText.fontSize = 12;
                btnText.alignment = TextAnchor.MiddleCenter;
                var idCapture = preset.Id;
                btn.onClick.AddListener(() => _session?.ApplyPreset(idCapture));
            }

            if (!string.IsNullOrEmpty(preset.Description))
            {
                var descGo = new GameObject("Description");
                descGo.transform.SetParent(row.transform, false);
                descGo.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
                var descText = descGo.AddComponent<Text>();
                descText.text = preset.Description;
                descText.font = _font;
                descText.fontSize = 11;
                descText.color = new Color(0.35f, 0.35f, 0.35f, 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, 18);
            var t = go.AddComponent<Text>();
            t.text = text;
            t.font = _font;
            t.fontSize = 13;
        }

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