using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using EventsAppQuest.Web.Application;
using EventsAppQuest.Web.Domain;
using EventsAppQuest.Web.Producer.Application;

namespace EventsAppQuest.Web.Presentation
{
    /// <summary>
    /// Painel de snapshots executivos: capturar, listar e comparar checkpoints por ciclo.
    /// </summary>
    public class EventCycleExecutiveSnapshotsPanel : MonoBehaviour, IWebContentRoot
    {
        private Transform _content;

        public void SetContentRoot(Transform contentRoot) => _content = contentRoot;

        private void Start()
        {
            Refresh();
            WebRuntimeContext.OnDataChanged += Refresh;
        }

        private void OnDestroy() => WebRuntimeContext.OnDataChanged -= Refresh;

        public void Refresh()
        {
            if (_content == null) return;
            ClearContent(_content);
            var data = WebRuntimeContext.DataService;
            if (data == null) return;
            var font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");

            var orders = HandoffStore.GetOrders();
            var opportunities = data.GetOpportunities();
            var proposals = data.GetProposals();
            var sessions = data.GetSessions();
            var followUps = data.GetFollowUpTasks();
            var portfolioState = EventCyclePortfolioPriorityController.BuildPortfolioPriority(orders, opportunities, proposals, sessions, followUps);

            var titleRow = new GameObject("TitleRow");
            titleRow.transform.SetParent(_content, false);
            titleRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 26);
            var titleText = titleRow.AddComponent<Text>();
            titleText.text = "Snapshots executivos do caso (checkpoints)";
            titleText.font = font;
            titleText.fontSize = 16;
            titleText.fontStyle = FontStyle.Bold;

            var btnRow = new GameObject("BtnRow");
            btnRow.transform.SetParent(_content, false);
            btnRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 24);
            var hLayout = btnRow.AddComponent<HorizontalLayoutGroup>();
            hLayout.spacing = 6;
            hLayout.childForceExpandWidth = false;
            CreateSmallButton(btnRow.transform, "Capturar (todos)", font, 130, () =>
            {
                EventCycleExecutiveSnapshotsController.CaptureSnapshotsForAllCycles(orders, opportunities, proposals, sessions, followUps);
                Refresh();
            });

            var global = EventCycleExecutiveSnapshotsController.GetGlobalSnapshotsState();
            AddBlock(_content, font, "Resumo", global.SnapshotSummary ?? "—");
            AddBlock(_content, font, "Total snapshots", global.TotalSnapshots.ToString());
            AddBlock(_content, font, "Última captura", global.LastCapturedAt?.ToString("yyyy-MM-dd HH:mm") ?? "—");

            if (portfolioState?.Items == null || portfolioState.Items.Count == 0)
            {
                var empty = new GameObject("Empty");
                empty.transform.SetParent(_content, false);
                var emptyText = empty.AddComponent<Text>();
                emptyText.font = font;
                emptyText.fontSize = 11;
                emptyText.text = "Nenhum ciclo na carteira. Gere pedidos a partir de oportunidades.";
                empty.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 18);
                return;
            }

            foreach (var item in portfolioState.Items)
            {
                var cycleId = item.CycleId;
                var state = EventCycleExecutiveSnapshotsController.GetSnapshotsState(cycleId);

                var block = new GameObject("Cycle_" + cycleId);
                block.transform.SetParent(_content, false);
                var layout = block.AddComponent<VerticalLayoutGroup>();
                layout.spacing = 3;
                layout.childForceExpandHeight = false;
                layout.childForceExpandWidth = true;

                var header = new GameObject("Header");
                header.transform.SetParent(block.transform, false);
                var headerText = header.AddComponent<Text>();
                headerText.font = font;
                headerText.fontSize = 12;
                headerText.fontStyle = FontStyle.Bold;
                headerText.text = $"{item.Title} [{cycleId}] | snapshots: {state.TotalSnapshots} | último: {(state.LastCapturedAt?.ToString("yyyy-MM-dd HH:mm") ?? "—")}";
                header.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 18);

                var btnRow2 = new GameObject("BtnRow");
                btnRow2.transform.SetParent(block.transform, false);
                var h2 = btnRow2.AddComponent<HorizontalLayoutGroup>();
                h2.spacing = 6;
                h2.childForceExpandWidth = false;
                CreateSmallButton(btnRow2.transform, "Capturar", font, 80, () =>
                {
                    var summaries = EventCycleExecutiveSummaryController.GenerateSummaries(orders, opportunities, proposals, sessions, followUps);
                    var closures = EventCycleClosureController.EvaluateClosure(orders, opportunities, proposals, sessions, followUps);
                    var bottlenecks = EventCycleBottleneckController.EvaluateBottlenecks(orders, opportunities, proposals, sessions, followUps);
                    var actions = EventCycleActionPlanController.GenerateActionPlans(orders, opportunities, proposals, sessions, followUps);
                    var recovery = EventCycleRecoveryPlanController.GenerateRecoveryPlans(orders, opportunities, proposals, sessions, followUps);
                    EventCycleExecutiveSnapshotsController.CaptureSnapshot(
                        cycleId,
                        summaries?.Find(s => s.CycleId == cycleId),
                        closures?.Find(c => c.CycleId == cycleId),
                        item,
                        bottlenecks?.Find(b => b.CycleId == cycleId),
                        actions?.Find(a => a.CycleId == cycleId),
                        recovery?.Find(r => r.CycleId == cycleId),
                        EventCycleManagerNotesController.GetNotesState(cycleId));
                    Refresh();
                });
                btnRow2.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 24);

                if (state.LatestSnapshot != null)
                {
                    var latest = state.LatestSnapshot;
                    AddBlock(block.transform, font, "Último snapshot", $"{latest.Summary} | Gargalo: {latest.MainBottleneck} | Ação: {latest.MainRecommendedAction}");
                }

                if (state.Snapshots != null)
                {
                    for (var i = 0; i < state.Snapshots.Count; i++)
                    {
                        var snap = state.Snapshots[i];
                        var prev = (i + 1) < state.Snapshots.Count ? state.Snapshots[i + 1] : null;
                        var compare = EventCycleExecutiveSnapshotsController.CompareSnapshots(snap, prev);

                        var row = new GameObject("Snap_" + snap.SnapshotId);
                        row.transform.SetParent(block.transform, false);
                        var v = row.AddComponent<VerticalLayoutGroup>();
                        v.spacing = 2;
                        v.childForceExpandHeight = false;

                        var l1 = new GameObject("Line1");
                        l1.transform.SetParent(row.transform, false);
                        var t1 = l1.AddComponent<Text>();
                        t1.font = font;
                        t1.fontSize = 10;
                        t1.fontStyle = FontStyle.Bold;
                        t1.text = $"{snap.Title} | {snap.ClosureStatus ?? "—"} | risco {snap.RiskLabel ?? "—"} | prioridade {snap.PriorityScore} | {(snap.CapturedAt?.ToString("yyyy-MM-dd HH:mm") ?? "—")}";
                        l1.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 14);

                        var l2 = new GameObject("Line2");
                        l2.transform.SetParent(row.transform, false);
                        var t2 = l2.AddComponent<Text>();
                        t2.font = font;
                        t2.fontSize = 9;
                        t2.text = snap.Summary ?? "—";
                        l2.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 12);

                        var l3 = new GameObject("Line3");
                        l3.transform.SetParent(row.transform, false);
                        var t3 = l3.AddComponent<Text>();
                        t3.font = font;
                        t3.fontSize = 9;
                        t3.text = "Δ " + compare;
                        l3.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 12);

                        var br = new GameObject("Btns");
                        br.transform.SetParent(row.transform, false);
                        var hb = br.AddComponent<HorizontalLayoutGroup>();
                        hb.spacing = 4;
                        hb.childForceExpandWidth = false;
                        CreateSmallButton(br.transform, "Remover", font, 70, () => { EventCycleExecutiveSnapshotsController.RemoveSnapshot(cycleId, snap.SnapshotId); Refresh(); });
                        br.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 22);

                        row.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 58);
                    }
                }
            }
        }

        private static void AddBlock(Transform parent, Font font, string title, string content)
        {
            var go = new GameObject("Block_" + title);
            go.transform.SetParent(parent, false);
            var text = go.AddComponent<Text>();
            text.font = font;
            text.fontSize = 10;
            text.text = title + ": " + (content ?? "—");
            go.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 14);
        }

        private static GameObject CreateSmallButton(Transform parent, string label, Font font, float width, System.Action onClick)
        {
            var go = new GameObject("Btn_" + label);
            go.transform.SetParent(parent, false);
            var rt = go.AddComponent<RectTransform>();
            rt.sizeDelta = new Vector2(width, 22);
            var le = go.AddComponent<LayoutElement>();
            le.preferredWidth = width;
            le.preferredHeight = 22;
            var img = go.AddComponent<Image>();
            img.color = new Color(0.4f, 0.7f, 0.5f);
            var btn = go.AddComponent<Button>();
            btn.targetGraphic = img;
            btn.onClick.AddListener(() => onClick?.Invoke());
            var tGo = new GameObject("Text");
            tGo.transform.SetParent(go.transform, false);
            var tRt = tGo.AddComponent<RectTransform>();
            tRt.anchorMin = Vector2.zero;
            tRt.anchorMax = Vector2.one;
            tRt.offsetMin = Vector2.zero;
            tRt.offsetMax = Vector2.zero;
            var t = tGo.AddComponent<Text>();
            t.text = label;
            t.font = font;
            t.fontSize = 9;
            t.alignment = TextAnchor.MiddleCenter;
            return go;
        }

        private static void ClearContent(Transform content)
        {
            for (var i = content.childCount - 1; i >= 0; i--)
                Destroy(content.GetChild(i).gameObject);
        }
    }
}

