#nullable enable

using MBN_STOCK_WEBVIEW.Core.Playout.Scenes;

namespace MBN_STOCK_WEBVIEW.LegacyApplication;

/// <summary>
/// Reproduces the ordered, ASCII-space-insensitive alias selection performed by
/// the original MBN_STOCK_N Class/CutList.cs. The returned value is additionally
/// closed against <see cref="LegacySceneCatalog"/> so legacy text can never become
/// an operator-controlled scene name or path.
/// </summary>
public static class LegacyCutInfoSceneAliasResolver
{
    private static readonly string[] OriginalAliases =
    [
        "50160",
        "5081",
        "5080",
        "5079",
        "5076",
        "N5001",
        "5001",
        "5006",
        "5011",
        "5026",
        "5087",
        "5029",
        "5086",
        "8035",
        "8061",
        "8051",
        "8040",
        "8046",
        "8056",
        "8003",
        "5037",
        "5016",
        "5068",
        "5070",
        "5072",
        "8067",
        "5078",
        "6001",
        "5082",
        "5023",
        "5083",
        "5084",
        "5024",
        "6067",
        "5085",
        "5025",
        "8001",
        "8002",
        "5074",
        "5077",
        "5088",
        "5032",
        "8032",
        "8018",
        "50860"
    ];

    static LegacyCutInfoSceneAliasResolver()
    {
        var unregistered = OriginalAliases
            .Where(alias => LegacySceneCatalog.FindByCutAlias(alias).Count == 0)
            .ToArray();
        if (unregistered.Length != 0)
        {
            throw new InvalidOperationException(
                "The original CutList contains an alias that is not registered in the scene catalog.");
        }
    }

    public static bool TryResolve(
        string groupCode,
        string subject,
        string graphicType,
        string subtype,
        out string sceneAlias)
    {
        sceneAlias = string.Empty;
        if (groupCode is null || subject is null || graphicType is null || subtype is null)
        {
            return false;
        }

        // MainForm.Show_PlayList uses this shorter key for the image-graph row.
        // Every other active branch concatenates the four visible legacy fields.
        var legacyCutInfo = string.Equals(
            graphicType,
            "이미지 그래프",
            StringComparison.Ordinal)
            ? subject + graphicType
            : groupCode + subject + graphicType + subtype;

        // The original removes U+0020 only. Other whitespace remains significant.
        var normalized = legacyCutInfo.Replace(" ", string.Empty, StringComparison.Ordinal);
        var candidate = ResolveOriginalCandidate(normalized);
        if (candidate is null || LegacySceneCatalog.FindByCutAlias(candidate).Count == 0)
        {
            return false;
        }

        sceneAlias = candidate;
        return true;
    }

    private static string? ResolveOriginalCandidate(string info)
    {
        if (Contains(info, "2열판-"))
        {
            return "50160";
        }

        if (Contains(info, "영업이익"))
        {
            return "5081";
        }

        if (Contains(info, "매출액"))
        {
            return "5080";
        }

        if (Contains(info, "성장성지표"))
        {
            return "5079";
        }

        if (Contains(info, "주요매출구성"))
        {
            return "5076";
        }

        if (Contains(info, "(NXT)1열판기본"))
        {
            return "N5001";
        }

        if (Contains(info, "1열판기본"))
        {
            return "5001";
        }

        if (Contains(info, "1열판상세"))
        {
            return Contains(info, "시가") ? "5006" : "5011";
        }

        if (Contains(info, "1열판"))
        {
            return "5001";
        }

        if (Contains(info, "종목별비교분석_캔들그래프"))
        {
            return "5026";
        }

        if (Contains(info, "종목별비교분석_라인그래프"))
        {
            return "5087";
        }

        if (Contains(info, "종목별수익률비교"))
        {
            return "5029";
        }

        if (Contains(info, "수익률그래프"))
        {
            return "5086";
        }

        if (Contains(info, "캔들그래프"))
        {
            if (Contains(info, "일봉"))
            {
                return "8035";
            }

            if (Contains(info, "5일"))
            {
                return "8061";
            }

            if (Contains(info, "120일"))
            {
                return "8051";
            }

            if (Contains(info, "20일"))
            {
                return "8040";
            }

            if (Contains(info, "60일"))
            {
                return "8046";
            }

            if (Contains(info, "240일"))
            {
                return "8056";
            }

            return null;
        }

        if (Contains(info, "호가창"))
        {
            return "8003";
        }

        if (Contains(info, "거래원"))
        {
            return "5037";
        }

        if (Contains(info, "3열판"))
        {
            return "5016";
        }

        if (Contains(info, "미국증시지도"))
        {
            return "5068";
        }

        if (Contains(info, "유럽증시지도"))
        {
            return "5070";
        }

        if (Contains(info, "아시아증시지도"))
        {
            return "5072";
        }

        if (Contains(info, "글로벌증시지도"))
        {
            return "8067";
        }

        if (Contains(info, "미국업종") || Contains(info, "섹터지수"))
        {
            return "5078";
        }

        if (Contains(info, "이미지그래프"))
        {
            return "6001";
        }

        if (Contains(info, "주체별매매동향"))
        {
            return "5082";
        }

        if (Contains(info, "매매동향표그래프"))
        {
            return "5023";
        }

        if (Contains(info, "개인매매동향") ||
            Contains(info, "기관매매동향") ||
            Contains(info, "외국인매매동향"))
        {
            return "5083";
        }

        if (Contains(info, "매매동향라인그래프"))
        {
            return "5084";
        }

        if (Contains(info, "매매동향막대그래프"))
        {
            return "5024";
        }

        if (Contains(info, "기관순매수현황"))
        {
            return "6067";
        }

        if (Contains(info, "프로그램매매"))
        {
            return "5085";
        }

        if (Contains(info, "순매도상위"))
        {
            return "5025";
        }

        if (Contains(info, "네모그래프"))
        {
            return Contains(info, "코스피") ? "8001" : "8002";
        }

        if (Contains(info, "5단표그래프"))
        {
            return "5074";
        }

        if (Contains(info, "6종목현재가"))
        {
            return "5077";
        }

        if (Contains(info, "12종목현재가"))
        {
            return "5088";
        }

        if (Contains(info, "2열판"))
        {
            if (Contains(info, "지수") || Contains(info, "종목"))
            {
                return Contains(info, "선물") ? "5032" : "8032";
            }

            if (Contains(info, "코스피"))
            {
                return "8018";
            }

            return Contains(info, "코스닥") ? "8032" : null;
        }

        return Contains(info, "라인그래프") ? "50860" : null;
    }

    private static bool Contains(string source, string value) =>
        source.Contains(value, StringComparison.Ordinal);
}
