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 score de aderência da proposta ativa ao briefing (score geral, sub-scores, destaques, lacunas, recomendações).
    /// </summary>
    public class ProposalFitScoreView : MonoBehaviour
    {
        private const string Title = "Score de Aderência / Qualidade da Proposta";
        private const string NenhumProjeto = "Nenhum projeto ou proposta ativa.";
        private const string ScoreGeral = "Score geral: ";
        private const string Orcamento = "Orçamento: ";
        private const string Mood = "Mood: ";
        private const string Capacidade = "Capacidade: ";
        private const string Obrigatorios = "Obrigatórios: ";
        private const string Risco = "Risco: ";
        private const string Destaques = "Destaques";
        private const string Lacunas = "Lacunas";
        private const string Recomendacoes = "Recomendações";

        private AppSession _session;
        private IProposalFitScoringService _scoringService;
        private Transform _scoresRoot;
        private Transform _highlightsRoot;
        private Transform _gapsRoot;
        private Transform _recommendationsRoot;
        private Font _font;

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

            _scoresRoot = new GameObject("ScoresRoot").transform;
            _scoresRoot.SetParent(transform, false);
            _scoresRoot.gameObject.AddComponent<LayoutElement>().preferredHeight = 100;
            var scoresVlg = _scoresRoot.gameObject.AddComponent<VerticalLayoutGroup>();
            scoresVlg.spacing = 2;
            scoresVlg.childForceExpandHeight = false;
            scoresVlg.childForceExpandWidth = true;

            _highlightsRoot = new GameObject("HighlightsRoot").transform;
            _highlightsRoot.SetParent(transform, false);
            _highlightsRoot.gameObject.AddComponent<LayoutElement>().preferredHeight = 50;
            AddSectionLabel(_highlightsRoot, Destaques);

            _gapsRoot = new GameObject("GapsRoot").transform;
            _gapsRoot.SetParent(transform, false);
            _gapsRoot.gameObject.AddComponent<LayoutElement>().preferredHeight = 50;
            AddSectionLabel(_gapsRoot, Lacunas);

            _recommendationsRoot = new GameObject("RecommendationsRoot").transform;
            _recommendationsRoot.SetParent(transform, false);
            _recommendationsRoot.gameObject.AddComponent<LayoutElement>().preferredHeight = 50;
            AddSectionLabel(_recommendationsRoot, Recomendacoes);
        }

        private void AddSectionLabel(Transform parent, string label)
        {
            var go = new GameObject("SectionLabel");
            go.transform.SetParent(parent, false);
            go.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
            var t = go.AddComponent<Text>();
            t.text = label;
            t.font = _font;
            t.fontSize = 12;
            t.fontStyle = FontStyle.Bold;
        }

        private void UpdateContent()
        {
            ClearChildren(_scoresRoot);
            ClearChildren(_highlightsRoot);
            ClearChildren(_gapsRoot);
            ClearChildren(_recommendationsRoot);

            var project = _session?.CurrentProject;
            var active = project?.GetActiveProposal();
            if (project == null || active == null)
            {
                AppendText(_scoresRoot, NenhumProjeto);
                return;
            }

            var fit = active.FitScore;
            if (fit == null && _scoringService != null)
            {
                fit = _scoringService.CalculateScore(project, active);
                active.FitScore = fit;
            }
            if (fit == null)
            {
                AppendText(_scoresRoot, "Score não disponível.");
                return;
            }

            AppendText(_scoresRoot, ScoreGeral + fit.OverallScore + "/100 — " + FitStatusLabel(fit.OverallScore));
            AppendText(_scoresRoot, Orcamento + fit.BudgetFitScore + " | " + Mood + fit.MoodFitScore + " | " + Capacidade + fit.CapacityFitScore + " | " + Obrigatorios + fit.MustHaveFitScore + " | " + Risco + fit.RiskScore);
            AddSectionLabel(_highlightsRoot, Destaques);
            AppendList(_highlightsRoot, fit.Highlights, new Color(0.2f, 0.5f, 0.2f, 1f));
            AddSectionLabel(_gapsRoot, Lacunas);
            AppendList(_gapsRoot, fit.Gaps, new Color(0.5f, 0.3f, 0.2f, 1f));
            AddSectionLabel(_recommendationsRoot, Recomendacoes);
            AppendList(_recommendationsRoot, fit.Recommendations, new Color(0.2f, 0.4f, 0.6f, 1f));
        }

        private static string FitStatusLabel(int overallScore)
        {
            if (overallScore >= 75) return "Alta aderência";
            if (overallScore >= 50) return "Aderência média";
            return "Baixa aderência";
        }

        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 void AppendList(Transform parent, List<string> items, Color color)
        {
            if (items == null) return;
            foreach (var item in items)
            {
                if (string.IsNullOrEmpty(item)) continue;
                var go = new GameObject("Item");
                go.transform.SetParent(parent, false);
                go.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 14);
                var t = go.AddComponent<Text>();
                t.text = "• " + item;
                t.font = _font;
                t.fontSize = 11;
                t.color = color;
            }
        }

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