using System.Globalization;
using MMoneyCoderSharp.Data;

internal static class ThemeCatalogStoredEditorCompatibilityAudit
{
    private const string KrxCrossPrefixCode = "00005724";
    private const string KrxDuplicateIndexCode = "00001164";
    private const string NxtCrossPrefixCode = "00000168";

    public static async Task RunAsync(
        IDataQueryExecutor executor,
        CancellationToken cancellationToken)
    {
        ArgumentNullException.ThrowIfNull(executor);
        var selector = await new LegacyThemeSelectionService(executor).SearchAsync(
            string.Empty,
            ThemeSession.PreMarket,
            LegacyThemeSelectionService.MaximumResults,
            cancellationToken).ConfigureAwait(false);
        if (selector.IsTruncated)
        {
            throw new InvalidOperationException(
                "The ThemeA stored-editor audit requires the complete selector.");
        }

        var krxCrossIdentity = FindIdentity(
            selector,
            ThemeMarket.Krx,
            KrxCrossPrefixCode);
        var krxDuplicateIdentity = FindIdentity(
            selector,
            ThemeMarket.Krx,
            KrxDuplicateIndexCode);
        var nxtCrossIdentity = FindIdentity(
            selector,
            ThemeMarket.Nxt,
            NxtCrossPrefixCode);

        var persistence = new LegacyThemeCatalogPersistenceService(executor);
        var krxCross = await persistence.ReadStoredAsync(
            krxCrossIdentity,
            cancellationToken).ConfigureAwait(false);
        var krxDuplicate = await persistence.ReadStoredAsync(
            krxDuplicateIdentity,
            cancellationToken).ConfigureAwait(false);
        var nxtCross = await persistence.ReadStoredAsync(
            nxtCrossIdentity,
            cancellationToken).ConfigureAwait(false);

        RequireComplete(krxCross);
        RequireComplete(krxDuplicate);
        RequireComplete(nxtCross);
        var krxCrossRows = krxCross.Items.Count(static item =>
            item.ItemCode.Length > 0 && item.ItemCode[0] is 'X' or 'T');
        var nxtCrossRows = nxtCross.Items.Count(static item =>
            item.ItemCode.Length > 0 && item.ItemCode[0] is 'P' or 'D');
        var duplicateGroups = krxDuplicate.Items
            .GroupBy(static item => item.InputIndex)
            .Count(static group => group.Count() > 1);
        var duplicateRows = krxDuplicate.Items
            .GroupBy(static item => item.InputIndex)
            .Where(static group => group.Count() > 1)
            .Sum(static group => group.Count());
        if (krxCrossRows == 0 || nxtCrossRows == 0 ||
            duplicateGroups == 0 || duplicateRows == 0)
        {
            throw new InvalidOperationException(
                "The deployed ThemeA stored-editor compatibility rows were not preserved.");
        }

        Console.WriteLine(
            "THEMEA_STORED_EDITOR_COMPATIBILITY: " +
            $"krxCrossPrefixRows={krxCrossRows.ToString(CultureInfo.InvariantCulture)} " +
            $"nxtCrossPrefixRows={nxtCrossRows.ToString(CultureInfo.InvariantCulture)} " +
            $"duplicateIndexGroups={duplicateGroups.ToString(CultureInfo.InvariantCulture)} " +
            $"duplicateIndexRows={duplicateRows.ToString(CultureInfo.InvariantCulture)} " +
            "rawValuesPrinted=false writesAttempted=false");
    }

    private static ThemeSelectionIdentity FindIdentity(
        ThemeSearchResult selector,
        ThemeMarket market,
        string code) =>
        selector.Items.SingleOrDefault(item =>
            item.Identity.Market == market &&
            string.Equals(item.Identity.ThemeCode, code, StringComparison.Ordinal))?.Identity ??
        throw new InvalidOperationException(
            "A deployed ThemeA stored-editor compatibility identity is missing.");

    private static void RequireComplete(ThemeCatalogStoredResult result)
    {
        if (result.IsTruncated)
        {
            throw new InvalidOperationException(
                "A deployed ThemeA stored definition exceeds the safe editor boundary.");
        }
    }
}
