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 comparação temporal entre duas propostas: evolução ao longo da jornada, resumo, melhores/melhores momentos, continuidade e impacto comercial.
    /// </summary>
    public class ProposalTemporalComparisonView : MonoBehaviour
    {
        private const string Title = "Comparação Temporal / Evolução das Propostas";
        private const string NenhumProjeto = "Nenhum projeto.";
        private const string DuasPropostas = "Duas ou mais propostas necessárias para comparar a evolução.";
        private const string BaseVs = "Base vs Comparada: ";
        private const string ResumoGeral = "Resumo: ";
        private const string MelhoresBase = "Base mais forte em: ";
        private const string MelhoresComparada = "Comparada mais forte em: ";
        private const string MelhorVisual = "Melhor jornada visual: ";
        private const string MelhorOperacional = "Melhor continuidade operacional: ";
        private const string MelhorComercial = "Melhor impacto comercial: ";
        private const string PorFase = "Por fase: ";
        private const string FaseLabel = "Fase: ";
        private const string BaseLabel = "Base: ";
        private const string ComparadaLabel = "Comparada: ";
        private const string Diferencas = "Diferenças: ";
        private const string MelhorOpcao = "Melhor: ";

        private AppSession _session;
        private IProposalTemporalComparisonService _temporalService;
        private Transform _contentRoot;
        private Font _font;

        private void Start()
        {
            _session = ServiceRegistry.Instance.Get<AppSession>();
            _temporalService = ServiceRegistry.Instance.Get<IProposalTemporalComparisonService>();
            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 = 420;
            var vlg = _contentRoot.gameObject.AddComponent<VerticalLayoutGroup>();
            vlg.spacing = 6;
            vlg.childForceExpandHeight = false;
            vlg.childForceExpandWidth = true;
        }

        private void UpdateContent()
        {
            ClearChildren(_contentRoot);

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

            var proposals = project.Proposals;
            if (proposals.Count < 2)
            {
                AppendText(_contentRoot, DuasPropostas);
                project.LastTemporalComparison = null;
                return;
            }

            var active = project.GetActiveProposal();
            var baseP = active ?? proposals[0];
            var comparedP = proposals.FirstOrDefault(p => p.Id != baseP.Id);
            if (comparedP == null)
            {
                AppendText(_contentRoot, DuasPropostas);
                project.LastTemporalComparison = null;
                return;
            }

            var comparison = _temporalService?.Compare(project, baseP.Id, comparedP.Id);
            if (comparison == null)
            {
                AppendText(_contentRoot, "Não foi possível gerar a comparação temporal.");
                return;
            }

            project.LastTemporalComparison = comparison;

            var baseName = baseP.Name ?? "Base";
            var comparedName = comparedP.Name ?? "Comparada";
            AppendText(_contentRoot, BaseVs + baseName + " × " + comparedName);

            if (!string.IsNullOrEmpty(comparison.OverallExperienceDifferenceSummary))
                AppendText(_contentRoot, ResumoGeral + comparison.OverallExperienceDifferenceSummary);

            if (comparison.StrongerMoments != null && comparison.StrongerMoments.Count > 0)
                AppendText(_contentRoot, MelhoresBase + string.Join(", ", comparison.StrongerMoments));
            if (comparison.WeakerMoments != null && comparison.WeakerMoments.Count > 0)
                AppendText(_contentRoot, MelhoresComparada + string.Join(", ", comparison.WeakerMoments));

            var baseLabel = ResolveProposalName(project, comparison.BetterVisualContinuity);
            var opLabel = ResolveProposalName(project, comparison.BetterOperationalContinuity);
            var salesLabel = ResolveProposalName(project, comparison.BetterSalesImpact);
            if (!string.IsNullOrEmpty(comparison.BetterVisualContinuity))
                AppendText(_contentRoot, MelhorVisual + baseLabel);
            if (!string.IsNullOrEmpty(comparison.BetterOperationalContinuity))
                AppendText(_contentRoot, MelhorOperacional + opLabel);
            if (!string.IsNullOrEmpty(comparison.BetterSalesImpact))
                AppendText(_contentRoot, MelhorComercial + salesLabel);

            if (comparison.PhaseComparisons != null && comparison.PhaseComparisons.Count > 0)
            {
                AppendText(_contentRoot, PorFase);
                foreach (var pc in comparison.PhaseComparisons.OrderBy(p => p.PhaseId))
                {
                    var card = new GameObject("PhaseComparisonCard");
                    card.transform.SetParent(_contentRoot, false);
                    card.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 72);
                    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.96f, 0.98f, 1f);

                    var headerLine = new GameObject("Header");
                    headerLine.transform.SetParent(card.transform, false);
                    headerLine.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 14);
                    var headerText = headerLine.AddComponent<Text>();
                    headerText.text = FaseLabel + (pc.PhaseId ?? "—") + (string.IsNullOrEmpty(pc.BetterOption) ? "" : " — " + MelhorOpcao + (pc.BetterOption == "Base" ? baseName : comparedName));
                    headerText.font = _font;
                    headerText.fontSize = 12;
                    headerText.fontStyle = FontStyle.Bold;

                    var baseLine = new GameObject("Base");
                    baseLine.transform.SetParent(card.transform, false);
                    baseLine.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
                    var baseText = baseLine.AddComponent<Text>();
                    baseText.text = BaseLabel + (pc.BaseSceneStateSummary ?? "—");
                    baseText.font = _font;
                    baseText.fontSize = 10;
                    baseText.color = new Color(0.3f, 0.4f, 0.5f, 1f);

                    var compLine = new GameObject("Compared");
                    compLine.transform.SetParent(card.transform, false);
                    compLine.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
                    var compText = compLine.AddComponent<Text>();
                    compText.text = ComparadaLabel + (pc.ComparedSceneStateSummary ?? "—");
                    compText.font = _font;
                    compText.fontSize = 10;
                    compText.color = new Color(0.35f, 0.45f, 0.55f, 1f);

                    if (pc.KeyDifferences != null && pc.KeyDifferences.Count > 0)
                    {
                        var diffLine = new GameObject("Diffs");
                        diffLine.transform.SetParent(card.transform, false);
                        diffLine.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
                        var diffText = diffLine.AddComponent<Text>();
                        diffText.text = Diferencas + string.Join("; ", pc.KeyDifferences);
                        diffText.font = _font;
                        diffText.fontSize = 9;
                        diffText.color = new Color(0.4f, 0.4f, 0.45f, 1f);
                    }
                }
            }
        }

        private string ResolveProposalName(EventProject project, string proposalId)
        {
            if (string.IsNullOrEmpty(proposalId) || project?.Proposals == null) return "—";
            var p = project.Proposals.FirstOrDefault(x => x.Id == proposalId);
            return p?.Name ?? proposalId;
        }

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