using System;
using System.Collections.Generic;
using Jovian.PopupSystem.UI;
using UnityEngine;

namespace Jovian.PopupSystem {
    /// <summary>
    /// Core interface for the popup system. Created per game state, not as a singleton.
    /// Manages category registration, trigger discovery, popup display, and lifecycle.
    /// </summary>
    public interface IPopupSystem {
        /// <summary>
        /// Scans all <see cref="PopupTrigger"/> components under the given parent and binds them
        /// to this system. Each trigger receives a <see cref="PopupTriggerView"/> for behavior.
        /// </summary>
        void ScanTriggers(Transform parent);

        /// <summary>
        /// Scans all <see cref="PopupTrigger"/> components under the given parent, binds them,
        /// and invokes the configure callback with both the trigger (for hierarchy queries) and
        /// its view (for setting content).
        /// </summary>
        void InitializeTriggersInChildren(Transform parent, Action<PopupTrigger, PopupTriggerView> configureTrigger);

        /// <summary>
        /// Returns the <see cref="PopupTriggerView"/> for the first registered trigger whose
        /// GameObject name matches. Returns null if not found.
        /// </summary>
        PopupTriggerView GetTriggerHandler(string gameObjectName);

        /// <summary>
        /// Returns all <see cref="PopupTriggerView"/> instances registered under the given category.
        /// </summary>
        IReadOnlyList<PopupTriggerView> GetTriggerHandlers(PopupCategory category);

        /// <summary>
        /// Registers a popup category. Each category gets its own <see cref="PopupReference"/> instance
        /// (lazily created on first show) and its own <see cref="IPopupAnimator"/>.
        /// </summary>
        /// <param name="category">The category to register.</param>
        /// <param name="priority">Fallback priority if not defined in <see cref="PopupSettings"/>. Higher dismisses lower.</param>
        void RegisterCategory(PopupCategory category, int priority = 0);

        /// <summary>
        /// Shows a popup for the given category after the configured delay. The build callback
        /// populates content via <see cref="PopupContentBuilder"/>. Optionally anchors to a
        /// RectTransform or follows the mouse if no anchor is provided.
        /// </summary>
        void Show(PopupCategory category, Action<PopupContentBuilder> buildContent,
                  RectTransform anchor = null, AnchorSide? anchorSide = null);

        /// <summary>
        /// Shows a popup for the given category at a fixed screen position.
        /// </summary>
        void ShowAtPosition(PopupCategory category, Action<PopupContentBuilder> buildContent,
                            Vector2 screenPosition);

        /// <summary>
        /// Hides the popup for the given category with a fade-out animation.
        /// </summary>
        void Hide(PopupCategory category);

        /// <summary>
        /// Hides all visible popups across all categories.
        /// </summary>
        void HideAll();

        /// <summary>
        /// Drives delay timers, animations, and follow-mouse positioning. Call every frame.
        /// </summary>
        void Tick(float deltaTime);

        /// <summary>
        /// Destroys all popup view GameObjects and clears registered categories.
        /// Call when the owning game state exits.
        /// </summary>
        void Dispose();
    }
}
