using TMPro;
using UnityEngine;
using UnityEngine.UI;

namespace Jovian.PopupSystem {
    /// <summary>
    /// Fluent API struct for building popup content. Operates on the generic element cache
    /// inside a <see cref="PopupView"/>. Received in the build callback passed to
    /// <see cref="IPopupSystem.Show"/>. Use <see cref="Add"/> for fully custom elements,
    /// or convenience methods for common types.
    /// </summary>
    public readonly struct PopupContentBuilder {
        private readonly PopupView view;

        /// <summary>
        /// Creates a builder targeting the given popup view.
        /// </summary>
        public PopupContentBuilder(PopupView view) {
            this.view = view;
        }

        /// <summary>
        /// Returns a cached or newly instantiated element by its registered type.
        /// Use this for fully custom or game-specific element types.
        /// </summary>
        public GameObject Add(PopupElementType elementType) {
            return view.GetElement(elementType);
        }

        /// <summary>
        /// Adds a text element using the given element type and sets its TMP_Text content.
        /// </summary>
        public PopupContentBuilder AddText(string text, PopupElementType elementType) {
            var go = view.GetElement(elementType);
            if(!go) {
                return this;
            }
            var tmp = go.GetComponentInChildren<TMP_Text>();
            if(tmp) {
                tmp.text = text;
            }
            return this;
        }

        /// <summary>
        /// Adds a colored text element using the given element type.
        /// Hex color can be with or without the # prefix.
        /// </summary>
        public PopupContentBuilder AddText(string text, string hexColor, PopupElementType elementType) {
            var go = view.GetElement(elementType);
            if(!go) {
                return this;
            }
            var tmp = go.GetComponentInChildren<TMP_Text>();
            if(!tmp) {
                return this;
            }
            var prefix = hexColor.Length > 0 && hexColor[0] == '#' ? "" : "#";
            tmp.text = $"<color={prefix}{hexColor}>{text}</color>";
            return this;
        }

        /// <summary>
        /// Adds a name/value row using the given element type. The prefab must have
        /// exactly two TMP_Text children (label first, value second).
        /// </summary>
        public PopupContentBuilder AddNameValue(string label, int value, PopupElementType elementType) {
            return AddNameValueInternal(elementType, label, value.ToString());
        }

        /// <summary>
        /// Adds a name/value row using the given element type. The prefab must have
        /// exactly two TMP_Text children (label first, value second).
        /// </summary>
        public PopupContentBuilder AddNameValue(string label, string value, PopupElementType elementType) {
            return AddNameValueInternal(elementType, label, value);
        }

        private PopupContentBuilder AddNameValueInternal(PopupElementType elementType, string label, string value) {
            var go = view.GetElement(elementType);
            if(go != null) {
                var children = go.GetComponentsInChildren<TMP_Text>(true);
                if(children.Length >= 2) {
                    children[0].text = label;
                    children[1].text = value;
                }
            }
            return this;
        }

        /// <summary>
        /// Adds an image element with the given sprite and optional height.
        /// </summary>
        public PopupContentBuilder AddImage(Sprite sprite, PopupElementType elementType, float height = 64f) {
            var go = view.GetElement(elementType);
            if(go != null) {
                var image = go.GetComponentInChildren<Image>();
                if(image != null) {
                    image.sprite = sprite;
                    var rt = (RectTransform)image.transform;
                    rt.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, height);
                }
            }
            return this;
        }

        /// <summary>
        /// Adds a separator element using the given element type.
        /// </summary>
        public PopupContentBuilder AddSeparator(PopupElementType elementType) {
            view.GetElement(elementType);
            return this;
        }
    }
}
