using MBN_STOCK_WEBVIEW.LegacyApplication;
using System.Text.Json;

namespace MBN_STOCK_WEBVIEW.LegacyBridge;

public sealed record LegacyExecutePlayoutIntent(LegacyOperatorPlayoutCommand Command)
    : LegacyUiIntent;

/// <summary>
/// Process-scoped Gate A PREPARE request. The opaque capability is validated and
/// consumed by the native launch authorization; it is never emitted in state.
/// </summary>
public sealed record LegacyGateAPrepareIntent(string Capability) : LegacyUiIntent;

public sealed record LegacySetFadeDurationIntent(int Duration)
    : LegacyUiIntent;

public sealed record LegacyToggleBackgroundIntent : LegacyUiIntent;

public sealed record LegacyChooseBackgroundIntent : LegacyUiIntent;

internal static class LegacyPlayoutUiIntentParser
{
    public static LegacyUiIntent? Parse(string type, JsonElement payload) => type switch
    {
        "gate-a-prepare" => ParseGateAPrepare(payload),
        "prepare-playout" => ParseEmpty(
            payload,
            static () => new LegacyExecutePlayoutIntent(
                LegacyOperatorPlayoutCommand.Prepare)),
        "take-in" => ParseEmpty(
            payload,
            static () => new LegacyExecutePlayoutIntent(
                LegacyOperatorPlayoutCommand.TakeIn)),
        "next-playout" => ParseEmpty(
            payload,
            static () => new LegacyExecutePlayoutIntent(
                LegacyOperatorPlayoutCommand.Next)),
        "take-out" => ParseEmpty(
            payload,
            static () => new LegacyExecutePlayoutIntent(
                LegacyOperatorPlayoutCommand.TakeOut)),
        "set-fade-duration" => ParseFadeDuration(payload),
        "toggle-background" => ParseEmpty(
            payload,
            static () => new LegacyToggleBackgroundIntent()),
        "choose-background" => ParseEmpty(
            payload,
            static () => new LegacyChooseBackgroundIntent()),
        _ => null
    };

    private static LegacyUiIntent? ParseGateAPrepare(JsonElement payload)
    {
        if (payload.ValueKind != JsonValueKind.Object ||
            payload.GetRawText().Length > 128 ||
            payload.EnumerateObject().Count() != 1 ||
            !payload.TryGetProperty("capability", out var capabilityElement) ||
            capabilityElement.ValueKind != JsonValueKind.String)
        {
            return null;
        }

        var capability = capabilityElement.GetString();
        if (capability is null || capability.Length != 64 ||
            capability.Any(character =>
                character is not (>= '0' and <= '9') and
                    not (>= 'A' and <= 'F')))
        {
            return null;
        }

        return new LegacyGateAPrepareIntent(capability);
    }

    private static LegacyUiIntent? ParseFadeDuration(JsonElement payload)
    {
        if (payload.ValueKind != JsonValueKind.Object ||
            payload.GetRawText().Length > 64 ||
            payload.EnumerateObject().Count() != 1 ||
            !payload.TryGetProperty("duration", out var durationElement) ||
            durationElement.ValueKind != JsonValueKind.Number ||
            !durationElement.TryGetInt32(out var duration) ||
            duration is < 0 or > 19)
        {
            return null;
        }

        return new LegacySetFadeDurationIntent(duration);
    }

    private static LegacyUiIntent? ParseEmpty(
        JsonElement payload,
        Func<LegacyUiIntent> factory) =>
        payload.ValueKind == JsonValueKind.Object &&
        !payload.EnumerateObject().Any()
            ? factory()
            : null;
}
