#nullable enable

namespace MBN_STOCK_WEBVIEW.Core.Playout.Scenes;

/// <summary>
/// Typed form of the direction strings used by the legacy scene builders.
/// </summary>
public enum ScenePriceDirection
{
    Unknown,
    LimitUp,
    Up,
    Flat,
    Down,
    LimitDown
}

/// <summary>
/// Reproduces MainForm.setObjectStockChange without exposing a K3D object.
/// The returned sequence intentionally follows the original call order.
/// </summary>
public static class LegacyPriceDirectionMutations
{
    private static readonly string[] DirectionObjects =
        ["upup", "up", "flat", "down", "downdown"];

    private static readonly string[] VariantObjects =
        ["bg", "changePrice", "wonText", "rate", "percent"];

    public static ScenePriceDirection Parse(string? value) => value?.Trim() switch
    {
        "상한" => ScenePriceDirection.LimitUp,
        "상승" or "+" => ScenePriceDirection.Up,
        null or "" or "보합" => ScenePriceDirection.Flat,
        "하락" or "-" => ScenePriceDirection.Down,
        "하한" => ScenePriceDirection.LimitDown,
        _ => ScenePriceDirection.Unknown
    };

    public static IReadOnlyList<PlayoutMutation> Build(
        ScenePriceDirection direction,
        int legacyVariantIndex)
    {
        if (legacyVariantIndex is < 0 or > 3)
        {
            throw new ArgumentOutOfRangeException(
                nameof(legacyVariantIndex),
                "Legacy direction variant must be between zero and three.");
        }

        var suffix = legacyVariantIndex is 1 or 2
            ? legacyVariantIndex.ToString(System.Globalization.CultureInfo.InvariantCulture)
            : string.Empty;
        var mutations = new List<PlayoutMutation>(32);

        foreach (var objectName in DirectionObjects)
        {
            mutations.Add(new PlayoutSetVisible(objectName + suffix, false));
        }

        var activeDirectionObject = direction switch
        {
            ScenePriceDirection.LimitUp => "upup",
            ScenePriceDirection.Up => "up",
            ScenePriceDirection.Flat => "flat",
            ScenePriceDirection.Down => "down",
            ScenePriceDirection.LimitDown => "downdown",
            _ => null
        };

        if (activeDirectionObject is null)
        {
            return mutations;
        }

        mutations.Add(new PlayoutSetVisible(activeDirectionObject + suffix, true));

        var selectedVariant = direction switch
        {
            ScenePriceDirection.LimitUp or ScenePriceDirection.Up => 1,
            ScenePriceDirection.Flat => 2,
            ScenePriceDirection.Down or ScenePriceDirection.LimitDown => 3,
            _ => throw new InvalidOperationException("A known direction was expected.")
        };

        for (var variant = 1; variant <= 3; variant++)
        {
            foreach (var objectName in VariantObjects)
            {
                mutations.Add(new PlayoutSetVisible(
                    $"{objectName}{variant}_{suffix}",
                    variant == selectedVariant));
            }
        }

        if (legacyVariantIndex != 0)
        {
            for (var variant = 1; variant <= 3; variant++)
            {
                mutations.Add(new PlayoutSetVisible(
                    $"unit{variant}_{suffix}",
                    variant == selectedVariant));
            }
        }

        // The original helper only changes price variants for the ordinary
        // up/flat/down branches when cnt == 3.
        if (legacyVariantIndex == 3 &&
            direction is ScenePriceDirection.Up or ScenePriceDirection.Flat or ScenePriceDirection.Down)
        {
            for (var variant = 1; variant <= 3; variant++)
            {
                mutations.Add(new PlayoutSetVisible(
                    $"price{variant}_{suffix}",
                    variant == selectedVariant));
            }
        }

        var pattern = selectedVariant switch
        {
            1 => @"Images\그림_빨강.png",
            2 => @"Images\그림_검정.png",
            3 => @"Images\그림_파랑.png",
            _ => throw new InvalidOperationException("A known visual variant was expected.")
        };
        mutations.Add(new PlayoutSetAssetValue("pattern" + suffix, pattern));

        return mutations;
    }
}
