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

namespace EventsAppQuest.Web.Producer.Presentation
{
    /// <summary>
    /// Vista no painel do produtor: status de execução, iniciar, actualizar progresso, registar update, issue/bloqueio, pausar/retomar, concluir.
    /// </summary>
    public class ProducerExecutionTrackingView : MonoBehaviour, IProducerContentRoot
    {
        private Transform _content;

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

        private void Start() => Refresh();

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

            var label = new GameObject("Label");
            label.transform.SetParent(_content, false);
            var labelRt = label.AddComponent<RectTransform>();
            labelRt.sizeDelta = new Vector2(0, 22);
            var labelText = label.AddComponent<Text>();
            labelText.text = "Execução operacional (pós-preparação)";
            labelText.font = font;
            labelText.fontSize = 14;
            labelText.fontStyle = FontStyle.Bold;

            foreach (var order in service.GetOrders())
            {
                var orderId = order.OrderId;
                var state = ProducerExecutionTrackingController.GetState(orderId);
                var updates = ProducerExecutionTrackingController.GetUpdates(orderId, 10).ToList();
                var prepConfirmed = PreparationChecklistStore.IsPreparationConfirmed(orderId);

                var block = new GameObject("Execution_" + orderId);
                block.transform.SetParent(_content, false);
                var layout = block.AddComponent<VerticalLayoutGroup>();
                layout.spacing = 4;
                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.text = $"{orderId} | {state.ExecutionStatus} | {state.ProgressPercent}% | {(state.IsPaused ? "Pausado" : "")} {(state.IsCompleted ? "Concluído" : "")} {(state.HasIssues ? "Com issues" : "")}";
                header.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 18);

                if (!state.IsCompleted)
                {
                    if (state.ExecutionStatus == ProducerExecutionStatus.NotStarted && prepConfirmed)
                    {
                        var startBtn = CreateButton(block.transform, "Iniciar execução", font, () => { ProducerExecutionTrackingController.StartExecution(orderId); Refresh(); });
                        startBtn.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 24);
                    }
                    if (state.ExecutionStatus == ProducerExecutionStatus.InExecution || state.ExecutionStatus == ProducerExecutionStatus.Paused || state.ExecutionStatus == ProducerExecutionStatus.Blocked)
                    {
                        var progressRow = new GameObject("ProgressRow");
                        progressRow.transform.SetParent(block.transform, false);
                        progressRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 24);
                        var hLayout = progressRow.AddComponent<HorizontalLayoutGroup>();
                        hLayout.spacing = 6;
                        hLayout.childForceExpandWidth = false;
                        hLayout.childForceExpandHeight = true;
                        var progressLabel = new GameObject("ProgressLabel");
                        progressLabel.transform.SetParent(progressRow.transform, false);
                        AddLayout(progressLabel, 80, 24);
                        var plText = progressLabel.AddComponent<Text>();
                        plText.font = font;
                        plText.fontSize = 10;
                        plText.text = "Progresso %:";
                        var progressInput = new GameObject("ProgressInput");
                        progressInput.transform.SetParent(progressRow.transform, false);
                        AddLayout(progressInput, 60, 22);
                        var inputField = progressInput.AddComponent<InputField>();
                        progressInput.AddComponent<Image>().color = Color.white;
                        var inputText = new GameObject("Text");
                        inputText.transform.SetParent(progressInput.transform, false);
                        var itRt = inputText.AddComponent<RectTransform>();
                        itRt.anchorMin = Vector2.zero;
                        itRt.anchorMax = Vector2.one;
                        itRt.offsetMin = new Vector2(4, 2);
                        itRt.offsetMax = new Vector2(-4, -2);
                        var it = inputText.AddComponent<Text>();
                        it.font = font;
                        it.fontSize = 10;
                        inputField.textComponent = it;
                        it.text = state.ProgressPercent.ToString();
                        var oid = orderId;
                        CreateSmallButton(progressRow.transform, "Atualizar", font, 70, () =>
                        {
                            if (int.TryParse(inputField.text, out var p))
                                ProducerExecutionTrackingController.UpdateProgress(oid, p, "Progresso atualizado");
                            Refresh();
                        });
                    }

                    if (state.ExecutionStatus != ProducerExecutionStatus.NotStarted)
                    {
                        var btnRow = new GameObject("BtnRow");
                        btnRow.transform.SetParent(block.transform, false);
                        btnRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 26);
                        var btnHLayout = btnRow.AddComponent<HorizontalLayoutGroup>();
                        btnHLayout.spacing = 4;
                        btnHLayout.childForceExpandWidth = false;
                        btnHLayout.childForceExpandHeight = true;
                        if (state.ExecutionStatus == ProducerExecutionStatus.InExecution)
                            CreateSmallButton(btnRow.transform, "Pausar", font, 56, () => { ProducerExecutionTrackingController.PauseExecution(orderId); Refresh(); });
                        if (state.ExecutionStatus == ProducerExecutionStatus.Paused || state.ExecutionStatus == ProducerExecutionStatus.Blocked)
                            CreateSmallButton(btnRow.transform, "Retomar", font, 56, () => { ProducerExecutionTrackingController.ResumeExecution(orderId); Refresh(); });
                        CreateSmallButton(btnRow.transform, "Reg. update", font, 72, () => { ProducerExecutionTrackingController.AddUpdate(orderId, ProducerExecutionUpdateType.ProgressUpdate, "Update", "Registo de progresso", state.ProgressPercent, false, false); Refresh(); });
                        CreateSmallButton(btnRow.transform, "Issue", font, 48, () => { ProducerExecutionTrackingController.AddUpdate(orderId, ProducerExecutionUpdateType.Issue, "Issue", "Problema reportado", -1, true, false); Refresh(); });
                        CreateSmallButton(btnRow.transform, "Bloqueio", font, 60, () => { ProducerExecutionTrackingController.AddUpdate(orderId, ProducerExecutionUpdateType.Blocker, "Bloqueio", "Execução bloqueada", -1, true, true); Refresh(); });
                        CreateSmallButton(btnRow.transform, "Concluir", font, 64, () => { ProducerExecutionTrackingController.CompleteExecution(orderId, "Execução concluída pelo produtor."); Refresh(); });
                    }
                }

                var summaryRow = new GameObject("Summary");
                summaryRow.transform.SetParent(block.transform, false);
                var sumText = summaryRow.AddComponent<Text>();
                sumText.font = font;
                sumText.fontSize = 10;
                sumText.text = "Resumo: " + (state.CurrentExecutionSummary ?? "—") + (state.IsCompleted ? " | " + (state.CompletionSummary ?? "") : "");
                summaryRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);

                var updatesLabel = new GameObject("UpdatesLabel");
                updatesLabel.transform.SetParent(block.transform, false);
                var ulText = updatesLabel.AddComponent<Text>();
                ulText.font = font;
                ulText.fontSize = 10;
                ulText.text = updates.Count == 0 ? "Sem updates." : string.Join("\n", updates.Select(u => $"[{u.UpdateType}] {u.Title}: {u.Summary} {(u.IsIssue ? "(issue)" : "")} {(u.IsBlocking ? "(bloqueio)" : "")}"));
                updatesLabel.GetComponent<RectTransform>().sizeDelta = new Vector2(0, Mathf.Max(20, updates.Count * 12));
            }
        }

        private static Button CreateButton(Transform parent, string text, Font font, System.Action onClick)
        {
            var go = new GameObject("Btn");
            go.transform.SetParent(parent, false);
            var rt = go.AddComponent<RectTransform>();
            var img = go.AddComponent<Image>();
            img.color = new Color(0.3f, 0.65f, 0.9f);
            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 = text;
            t.font = font;
            t.fontSize = 11;
            t.alignment = TextAnchor.MiddleCenter;
            return btn;
        }

        private static void AddLayout(GameObject go, float width, float height)
        {
            var rt = go.AddComponent<RectTransform>();
            rt.sizeDelta = new Vector2(width, height);
            var le = go.AddComponent<LayoutElement>();
            le.preferredWidth = width;
            le.preferredHeight = height;
        }

        private static Button CreateSmallButton(Transform parent, string text, Font font, float width, System.Action onClick)
        {
            var go = new GameObject("Btn_" + text);
            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 = text;
            t.font = font;
            t.fontSize = 9;
            t.alignment = TextAnchor.MiddleCenter;
            return btn;
        }

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