using MBN_STOCK_WEBVIEW.LegacyApplication;
using MMoneyCoderSharp.Data;

namespace MBN_STOCK_WEBVIEW.LegacyApplication.Tests;

public sealed class LegacyIndustryActionCatalogTests
{
    private static readonly string[] ExpectedActionIds =
    [
        "one-column",
        "two-column",
        "yield-5일",
        "yield-20일",
        "yield-60일",
        "yield-120일",
        "yield-240일",
        "candle-일봉",
        "candle-5일",
        "candle-20일",
        "candle-60일",
        "candle-120일",
        "candle-240일",
        "candle-volume-일봉",
        "candle-volume-5일",
        "candle-volume-20일",
        "candle-volume-60일",
        "candle-volume-120일",
        "candle-volume-240일",
        "five-row",
        "square",
        "sector"
    ];

    private static readonly string[] ExpectedRuntimeLabels =
    [
        "1열판",
        "2열판",
        "수익률그래프_5일",
        "수익률그래프_20일",
        "수익률그래프_60일",
        "수익률그래프_120일",
        "수익률그래프_240일",
        "캔들그래프_일봉",
        "캔들그래프_5일",
        "캔들그래프_20일",
        "캔들그래프_60일",
        "캔들그래프_120일",
        "캔들그래프_240일",
        "캔들그래프(거래량)_일봉",
        "캔들그래프(거래량)_5일",
        "캔들그래프(거래량)_20일",
        "캔들그래프(거래량)_60일",
        "캔들그래프(거래량)_120일",
        "캔들그래프(거래량)_240일",
        "5단 표그래프",
        "네모그래프",
        "섹터지수"
    ];

    [Theory]
    [InlineData(
        IndustryMarket.Kospi,
        "bin/Debug/Res/업종_코스피.ini",
        "F21DE58003315EAB41F9FE7B5A573C71653056203E6743D05AA96E7FF1B8BF52")]
    [InlineData(
        IndustryMarket.Kosdaq,
        "bin/Debug/Res/업종_코스닥.ini",
        "F25B8926E8F20FC5FBC94A1891A9E2EAD22852E8C829321EF1A001FE3F42ECE4")]
    public void EachMarketHasTheExactImmutableRuntimeActionsAndAsset(
        IndustryMarket market,
        string expectedPath,
        string expectedSha256)
    {
        var actions = LegacyIndustryActionCatalog.GetActions(market);

        Assert.Equal(LegacyIndustryActionCatalog.ActionsPerMarket, actions.Count);
        Assert.Equal(ExpectedActionIds, actions.Select(action => action.ActionId));
        Assert.Equal(ExpectedRuntimeLabels, actions.Select(action => action.Label));
        Assert.Equal(
            LegacyIndustryActionCatalog.ActionsPerMarket,
            actions.Select(action => action.ActionId).Distinct(StringComparer.Ordinal).Count());
        Assert.All(actions, action => Assert.Equal(market, action.Market));

        var mutableView = Assert.IsAssignableFrom<IList<LegacyIndustryActionDefinition>>(actions);
        Assert.Throws<NotSupportedException>(() => mutableView.RemoveAt(0));

        var asset = LegacyIndustryActionCatalog.GetRuntimeAsset(market);
        Assert.Equal(expectedPath, asset.RelativePath);
        Assert.Equal(expectedSha256, asset.Sha256);
    }

    [Theory]
    [InlineData(IndustryMarket.Kospi, "two-column", "s8018", "8018", 0)]
    [InlineData(IndustryMarket.Kosdaq, "two-column", "s8018", "8032", 0)]
    [InlineData(IndustryMarket.Kospi, "candle-일봉", "s8010", "8035", 0)]
    [InlineData(IndustryMarket.Kospi, "candle-volume-5일", "s8010", "8061", 0)]
    [InlineData(IndustryMarket.Kosdaq, "candle-20일", "s8010", "8040", 0)]
    [InlineData(IndustryMarket.Kosdaq, "candle-volume-60일", "s8010", "8046", 0)]
    [InlineData(IndustryMarket.Kospi, "candle-120일", "s8010", "8051", 0)]
    [InlineData(IndustryMarket.Kosdaq, "candle-volume-240일", "s8010", "8056", 0)]
    [InlineData(IndustryMarket.Kospi, "five-row", "s5074", "5074", 5)]
    [InlineData(IndustryMarket.Kospi, "square", "s8001", "8001", 0)]
    [InlineData(IndustryMarket.Kosdaq, "square", "s8001", "8002", 0)]
    [InlineData(IndustryMarket.Kosdaq, "sector", "s5078", "5078", 0)]
    public void SceneAliasAndPageSizeAreClosedPerMarket(
        IndustryMarket market,
        string actionId,
        string expectedBuilder,
        string expectedAlias,
        int expectedPageSize)
    {
        var action = LegacyIndustryActionCatalog.GetRequiredAction(market, actionId);

        Assert.Equal(expectedBuilder, action.BuilderKey);
        Assert.Equal(expectedAlias, action.SceneAlias);
        Assert.Equal(expectedPageSize, action.PageSize);
    }

    [Theory]
    [InlineData(IndustryMarket.Kospi)]
    [InlineData(IndustryMarket.Kosdaq)]
    public void OnlyFiveRowHasLegacyPaging(IndustryMarket market)
    {
        var paged = Assert.Single(
            LegacyIndustryActionCatalog.GetActions(market),
            action => action.PageSize != 0);

        Assert.Equal("five-row", paged.ActionId);
        Assert.Equal(5, paged.PageSize);
    }

    [Fact]
    public void UnknownMarketAndActionFailClosed()
    {
        Assert.Throws<ArgumentOutOfRangeException>(() =>
            LegacyIndustryActionCatalog.GetActions((IndustryMarket)999));
        Assert.Throws<KeyNotFoundException>(() =>
            LegacyIndustryActionCatalog.GetRequiredAction(IndustryMarket.Kospi, "../5001"));
        Assert.False(LegacyIndustryActionCatalog.TryGetAction(
            IndustryMarket.Kosdaq,
            "ONE-COLUMN",
            out _));
    }
}
