using System.Text.RegularExpressions;

namespace RolemasterDb.CriticalParsing;

public static class CriticalCellParserSupport
{
    private static readonly Regex NumericAffixLineRegex = new(@"^\d+(?:H|∑|∏|π|∫|\s*[–-])", RegexOptions.Compiled);
    private static readonly Regex StandaloneModifierAffixLineRegex = new(@"^(?:\d+)?\((?:\+|-|–)\d+\)$", RegexOptions.Compiled);

    public static bool IsAffixLikeLine(string line, IReadOnlySet<string> affixLegendSymbols)
    {
        var value = line.Trim();
        if (value.Length == 0)
        {
            return false;
        }

        if (value is "-" or "\u2013" or "\u2014")
        {
            return true;
        }

        if (IsConditionalBranchStartLine(value))
        {
            return true;
        }

        if (affixLegendSymbols.Count > 0 &&
            affixLegendSymbols.Any(symbol => value.Contains(symbol, StringComparison.Ordinal)))
        {
            if (value.Any(char.IsDigit))
            {
                return true;
            }

            var remainder = value;
            foreach (var symbol in affixLegendSymbols.OrderByDescending(item => item.Length))
            {
                remainder = remainder.Replace(symbol, string.Empty, StringComparison.Ordinal);
            }

            remainder = remainder
                .Replace("+", string.Empty, StringComparison.Ordinal)
                .Replace("-", string.Empty, StringComparison.Ordinal)
                .Replace("–", string.Empty, StringComparison.Ordinal)
                .Replace("(", string.Empty, StringComparison.Ordinal)
                .Replace(")", string.Empty, StringComparison.Ordinal)
                .Replace("/", string.Empty, StringComparison.Ordinal);

            if (string.IsNullOrWhiteSpace(remainder))
            {
                return true;
            }
        }

        return value.StartsWith("+", StringComparison.Ordinal) ||
               value.StartsWith("\u2211", StringComparison.Ordinal) ||
               value.StartsWith("\u220F", StringComparison.Ordinal) ||
               value.StartsWith("\u03C0", StringComparison.Ordinal) ||
               value.StartsWith("\u222B", StringComparison.Ordinal) ||
               StandaloneModifierAffixLineRegex.IsMatch(value) ||
               NumericAffixLineRegex.IsMatch(value) ||
               value.Contains(" - ", StringComparison.Ordinal) ||
               value.Contains(" – ", StringComparison.Ordinal);
    }

    public static int CountLineTypeSegments(IReadOnlyList<string> lines, IReadOnlySet<string> affixLegendSymbols)
    {
        var segmentCount = 0;
        bool? previousIsAffix = null;

        foreach (var line in lines)
        {
            var currentIsAffix = IsAffixLikeLine(line, affixLegendSymbols);
            if (previousIsAffix == currentIsAffix)
            {
                continue;
            }

            segmentCount++;
            previousIsAffix = currentIsAffix;
        }

        return segmentCount;
    }

    public static string CollapseWhitespace(string value) =>
        Regex.Replace(value.Trim(), @"\s+", " ");

    public static bool IsConditionalBranchStartLine(string value)
    {
        var normalized = value.Trim();
        if (!normalized.Contains(':', StringComparison.Ordinal))
        {
            return false;
        }

        return normalized.StartsWith("with ", StringComparison.OrdinalIgnoreCase) ||
               normalized.StartsWith("w/ ", StringComparison.OrdinalIgnoreCase) ||
               normalized.StartsWith("w/o ", StringComparison.OrdinalIgnoreCase) ||
               normalized.StartsWith("without ", StringComparison.OrdinalIgnoreCase) ||
               normalized.StartsWith("if ", StringComparison.OrdinalIgnoreCase) ||
               normalized.StartsWith("while ", StringComparison.OrdinalIgnoreCase) ||
               normalized.StartsWith("until ", StringComparison.OrdinalIgnoreCase) ||
               normalized.StartsWith("unless ", StringComparison.OrdinalIgnoreCase);
    }

    public static string? NormalizeConditionKey(string conditionText)
    {
        var normalized = CollapseWhitespace(conditionText)
            .ToLowerInvariant()
            .Replace("w/o", "without", StringComparison.Ordinal)
            .Replace("w/", "with", StringComparison.Ordinal);
        normalized = Regex.Replace(normalized, @"[^a-z0-9]+", "_");
        normalized = normalized.Trim('_');
        return normalized.Length == 0 ? null : normalized;
    }
}
