using System.Threading;
using System.Threading.Tasks;

namespace SquadDash.Screenshots;

/// <summary>
/// Represents a named, programmatically invocable UI action that can be
/// executed, verified, and undone — enabling automated re-capture of
/// transient UI states (open dialogs, expanded menus, voice-dictation overlay, etc.).
/// </summary>
/// <remarks>
/// <para>
/// Implementations are registered at startup in <see cref="UiActionReplayRegistry"/>
/// and may be referenced by <c>ScreenshotManifest.ReplayActionId</c> so that
/// screenshot automation can recreate the exact UI state before re-capturing.
/// </para>
/// <para>
/// Actions that have irreversible side-effects (e.g., sending a message) MUST set
/// <see cref="IsSideEffectFree"/> to <c>false</c>; the automated replay pipeline
/// will exclude them from unattended re-capture runs.
/// </para>
/// </remarks>
public interface IReplayableUiAction
{
    /// <summary>
    /// Stable, kebab-case identifier unique within the registry.
    /// Example: <c>"open-agent-info-dialog"</c>.
    /// Must not change once assigned — it will be persisted in manifest files.
    /// </summary>
    string ActionId { get; }

    /// <summary>
    /// Human-readable description presented in documentation generated by
    /// screenshot tooling (e.g., Mira Quill's manifest catalogue).
    /// </summary>
    string Description { get; }

    /// <summary>
    /// When <c>true</c>, <see cref="UndoAsync"/> can reliably restore pre-action
    /// state and automated replay is safe to run unattended.
    /// When <c>false</c>, the action has side-effects that survive undo (e.g.
    /// sending network requests, writing persistent state) and must be excluded
    /// from automated pipelines unless explicitly opted in.
    /// </summary>
    bool IsSideEffectFree { get; }

    /// <summary>
    /// Drives the UI into the target state (open a dialog, expand a panel, etc.).
    /// Must be called on the WPF dispatcher thread.
    /// </summary>
    Task ExecuteAsync(CancellationToken ct);

    /// <summary>
    /// Returns <c>true</c> when the UI has reached a stable, capturable state:
    /// layout is settled, entry animations have completed, and no pending
    /// dispatcher operations remain.  Callers poll this before triggering capture.
    /// </summary>
    Task<bool> IsReadyAsync();

    /// <summary>
    /// Restores the UI to its pre-action state (closes opened dialogs, collapses
    /// expanded panels, etc.).  Callers are responsible for invoking this after
    /// every successful capture, even if <see cref="ExecuteAsync"/> threw.
    /// Implementations should be idempotent: if the UI is already in the
    /// pre-action state, this should succeed silently.
    /// </summary>
    Task UndoAsync();

    /// <summary>
    /// The default <see cref="ScreenshotFixture"/> carried by this action.
    /// Applied by the capture pipeline when the invoking
    /// <c>ScreenshotManifest</c> does not supply its own fixture override.
    /// </summary>
    /// <remarks>
    /// Returns <see cref="ScreenshotFixture.Empty"/> by default — meaning no
    /// application state is pre-populated before capture.  Override in
    /// implementations that require a specific data state to be in place before
    /// <see cref="ExecuteAsync"/> runs (e.g., an agent-card action that needs a
    /// particular agent to be loaded).
    /// </remarks>
    ScreenshotFixture? DefaultFixture => ScreenshotFixture.Empty;
}
