using System;
using System.Collections.Generic;
using Tornado3_2026Election.Domain;

namespace Tornado3_2026Election.Services;

public static class CutCategoryResolver
{
    private static readonly IReadOnlyList<CutCategory> OrderedCategories =
    [
        CutCategory.Title,
        CutCategory.MetropolitanHead,
        CutCategory.LocalHead,
        CutCategory.Superintendent,
        CutCategory.MetropolitanCouncil,
        CutCategory.LocalCouncil,
        CutCategory.NationalAssembly,
        CutCategory.BottomTopTwo,
        CutCategory.BottomTopThree,
        CutCategory.BottomCurrentLeader,
        CutCategory.BottomWinner,
        CutCategory.BottomAllCandidates,
        CutCategory.BottomTurnoutSido,
        CutCategory.BottomTurnoutDistrict,
        CutCategory.BottomEarlyTurnout,
        CutCategory.BottomElectionDayTurnout,
        CutCategory.PreElection,
        CutCategory.Historical,
        CutCategory.Turnout
    ];

    public static IReadOnlyList<CutCategory> GetOrderedCategories() => OrderedCategories;

    public static bool IsMatch(FormatTemplateDefinition template, CutCategory category)
    {
        var formatName = template.Name ?? string.Empty;

        return category switch
        {
            CutCategory.MetropolitanHead => IsMetropolitanHeadFormat(formatName),
            CutCategory.LocalHead => Contains(formatName, "기초단체장"),
            CutCategory.Superintendent => Contains(formatName, "교육감"),
            CutCategory.MetropolitanCouncil => Contains(formatName, "광역의원"),
            CutCategory.LocalCouncil => Contains(formatName, "기초의원"),
            CutCategory.NationalAssembly => Contains(formatName, "보궐선거") ||
                Contains(formatName, "국회의원"),
            CutCategory.BottomTopTwo => IsBottomCountingTemplate(template, "1-2위_"),
            CutCategory.BottomTopThree => IsBottomCountingTemplate(template, "1-3위_"),
            CutCategory.BottomCurrentLeader => IsBottomCountingTemplate(template, "1위_"),
            CutCategory.BottomWinner => IsBottomCountingTemplate(template, "당선_"),
            CutCategory.BottomAllCandidates => IsBottomCountingTemplate(template, "전후보_") ||
                IsBottomCountingTemplate(template, "모든후보_"),
            CutCategory.BottomTurnoutSido => IsBottomTurnoutSidoTemplate(template),
            CutCategory.BottomTurnoutDistrict => IsBottomTurnoutDistrictTemplate(template),
            CutCategory.BottomEarlyTurnout => IsBottomEarlyTurnoutTemplate(template),
            CutCategory.BottomElectionDayTurnout => IsBottomElectionDayTurnoutTemplate(template),
            CutCategory.PreElection => Contains(formatName, "사전"),
            CutCategory.Historical => Contains(formatName, "역대"),
            CutCategory.Turnout => Contains(formatName, "투표율"),
            CutCategory.Title => Contains(formatName, "타이틀"),
            _ => false
        };
    }

    public static string GetLabel(CutCategory category)
    {
        return category switch
        {
            CutCategory.MetropolitanHead => "광역단체장",
            CutCategory.LocalHead => "기초단체장",
            CutCategory.Superintendent => "교육감",
            CutCategory.MetropolitanCouncil => "광역의원",
            CutCategory.LocalCouncil => "기초의원",
            CutCategory.NationalAssembly => "국회의원",
            CutCategory.BottomTopTwo => "1-2위",
            CutCategory.BottomTopThree => "1-3위",
            CutCategory.BottomCurrentLeader => "1위",
            CutCategory.BottomWinner => "당선",
            CutCategory.BottomAllCandidates => "전후보",
            CutCategory.BottomTurnoutSido => "시도",
            CutCategory.BottomTurnoutDistrict => "시군구",
            CutCategory.BottomEarlyTurnout => "사전투표율",
            CutCategory.BottomElectionDayTurnout => "투표율",
            CutCategory.PreElection => "사전",
            CutCategory.Historical => "역대",
            CutCategory.Turnout => "투표율",
            CutCategory.Title => "타이틀",
            _ => "광역단체장"
        };
    }

    private static bool Contains(string value, string token)
    {
        return value.Contains(token, StringComparison.Ordinal);
    }

    private static bool IsMetropolitanHeadFormat(string formatName)
    {
        return Contains(formatName, "광역단체장") ||
               string.Equals(formatName, "사전_역대당선자", StringComparison.Ordinal);
    }

    private static bool IsBottomCountingTemplate(FormatTemplateDefinition template, string prefix)
    {
        return template.RecommendedChannel == BroadcastChannel.Bottom &&
               template.SupportsCounting &&
               template.Name.StartsWith(prefix, StringComparison.Ordinal);
    }

    private static bool IsBottomTurnoutSidoTemplate(FormatTemplateDefinition template)
    {
        return template.RecommendedChannel == BroadcastChannel.Bottom &&
               (string.Equals(template.Name, "사전투표율_시도", StringComparison.Ordinal) ||
                string.Equals(template.Name, "투표율_시도", StringComparison.Ordinal));
    }

    private static bool IsBottomTurnoutDistrictTemplate(FormatTemplateDefinition template)
    {
        return template.RecommendedChannel == BroadcastChannel.Bottom &&
               (string.Equals(template.Name, "사전투표율_시군구", StringComparison.Ordinal) ||
                string.Equals(template.Name, "투표율_시군구", StringComparison.Ordinal));
    }

    private static bool IsBottomEarlyTurnoutTemplate(FormatTemplateDefinition template)
    {
        return template.RecommendedChannel == BroadcastChannel.Bottom &&
               (string.Equals(template.Name, "사전투표율_시도", StringComparison.Ordinal) ||
                string.Equals(template.Name, "사전투표율_시군구", StringComparison.Ordinal));
    }

    private static bool IsBottomElectionDayTurnoutTemplate(FormatTemplateDefinition template)
    {
        return template.RecommendedChannel == BroadcastChannel.Bottom &&
               (string.Equals(template.Name, "투표율_시도", StringComparison.Ordinal) ||
                string.Equals(template.Name, "투표율_시군구", StringComparison.Ordinal));
    }
}
