using System.Diagnostics.CodeAnalysis;
using RpgRoller.Domain;
using RpgRoller.Services;

namespace RpgRoller.Components.Pages.HomeControls;

[ExcludeFromCodeCoverage]
internal static class RulesetFormHelpers
{
    internal static class RulesetIds
    {
        public const string D6 = "d6";
        public const string Dnd5e = "dnd5e";
        public const string Rolemaster = "rolemaster";
    }

    public static bool IsD6(string? rulesetId)
    {
        return string.Equals(rulesetId, RulesetIds.D6, StringComparison.OrdinalIgnoreCase);
    }

    public static bool IsRolemaster(string? rulesetId)
    {
        return string.Equals(rulesetId, RulesetIds.Rolemaster, StringComparison.OrdinalIgnoreCase);
    }

    public static bool IsRolemasterOpenEndedExpression(string? expression)
    {
        var parseResult = TryParseRolemasterExpression(expression);
        return parseResult.Succeeded && parseResult.Value is not null && parseResult.Value.Kind == DiceExpressionKind.RolemasterOpenEndedPercentile;
    }

    public static string DescribeRolemasterExpression(string expression, int? fumbleRange, bool rolemasterAutoRetry = false)
    {
        var parseResult = TryParseRolemasterExpression(expression);
        if (!parseResult.Succeeded || parseResult.Value is null)
            return expression;

        return parseResult.Value.Kind switch
        {
            DiceExpressionKind.RolemasterOpenEndedPercentile => DescribeOpenEndedExpression(parseResult.Value.Canonical, fumbleRange, rolemasterAutoRetry),
            _                                                => $"Rolemaster: {parseResult.Value.Canonical}"
        };
    }

    public static string RolemasterExampleText()
    {
        return "Examples: d10, 15d10, d100-15, d100!+85";
    }

    private static ServiceResult<DiceExpression> TryParseRolemasterExpression(string? expression)
    {
        if (string.IsNullOrWhiteSpace(expression))
            return ServiceResult<DiceExpression>.Failure("invalid_expression", "Expression is required.");

        return DiceRules.ParseExpression(RulesetKind.Rolemaster, expression);
    }

    private static string DescribeOpenEndedExpression(string canonicalExpression, int? fumbleRange, bool rolemasterAutoRetry)
    {
        var parts = new List<string> { $"Open-ended percentile: {canonicalExpression}" };

        if (fumbleRange.HasValue)
            parts.Add($"fumble <= {fumbleRange.Value}");

        if (rolemasterAutoRetry)
            parts.Add("auto retry");

        return string.Join(", ", parts);
    }
}