using System;
using UnityEngine;

namespace Jovian.PopupSystem {
    /// <summary>
    /// Value type identifying a popup element prefab. Compared by string ID using ordinal
    /// comparison. Built-in types cover common popup elements. Define custom types as static
    /// fields or create instances for game-specific elements and variants.
    /// </summary>
    [Serializable]
    public struct PopupElementType : IEquatable<PopupElementType> {
        [SerializeField] private string id;

        /// <summary>The string identifier for this element type.</summary>
        public string Id => id;

        public PopupElementType(string id) {
            this.id = id;
        }

        // --- Built-in types ---

        /// <summary>Bold header text element.</summary>
        public static readonly PopupElementType Header = new("header");

        /// <summary>Body text element.</summary>
        public static readonly PopupElementType Text = new("text");

        /// <summary>Label + value stat row element.</summary>
        public static readonly PopupElementType LabelValueText = new("label_value_text");

        /// <summary>Image/icon element.</summary>
        public static readonly PopupElementType Image = new("image");

        /// <summary>Horizontal separator line.</summary>
        public static readonly PopupElementType Separator = new("separator");

        // --- Variant helper ---

        /// <summary>
        /// Creates a variant of this element type by appending a suffix.
        /// e.g. <c>PopupElementType.Header.Variant("gold")</c> produces <c>"header_gold"</c>.
        /// </summary>
        public PopupElementType Variant(string variant) {
            return new PopupElementType($"{id}_{variant}");
        }

        // --- Equality ---

        public bool Equals(PopupElementType other) {
            return string.Equals(id, other.id, StringComparison.Ordinal);
        }

        public override bool Equals(object obj) {
            return obj is PopupElementType other && Equals(other);
        }

        public override int GetHashCode() {
            return id != null ? id.GetHashCode() : 0;
        }

        public override string ToString() {
            return id ?? string.Empty;
        }

        public static bool operator ==(PopupElementType left, PopupElementType right) {
            return left.Equals(right);
        }

        public static bool operator !=(PopupElementType left, PopupElementType right) {
            return !left.Equals(right);
        }
    }
}
