using Microsoft.Extensions.Logging;
using PARR.Core.Repositories.Interfaces.Unit;
using PARR.Core.Services.Shortcodes.Enums;
using PARR.Core.Services.Shortcodes.Models;
using System.Text.RegularExpressions;

namespace PARR.Core.Services.Shortcodes.Handlers;

internal class LettersShortcodeHandler : IShortcodeHandler
{
    private readonly IUnitInValueRepository unitInValueRepo;
    private readonly ILogger<LettersShortcodeHandler> logger;

    public int Order => 60;

    private static readonly Regex _pattern = new(@"%БУКВЫ:([^%]+)%", RegexOptions.Compiled | RegexOptions.IgnoreCase);
    public Regex Pattern => _pattern;

    public ShortcodeDataRequirementsEnum Requirements => ShortcodeDataRequirementsEnum.None;

    public LettersShortcodeHandler(IUnitInValueRepository unitInValueRepo, ILogger<LettersShortcodeHandler> logger)
    {
        this.unitInValueRepo = unitInValueRepo;
        this.logger = logger;
    }

    public async Task<string> ResolveAsync(string input, TemplateForShortcode template, string caller, CancellationToken ct = default)
    {
        var matches = Pattern.Matches(input);
        if (matches.Count == 0) return input;

        var uniqueFields = matches.Cast<Match>()
            .Select(m => m.Value.Trim('%').Split(':', 2)[1].Trim())
            .Distinct(StringComparer.OrdinalIgnoreCase)
            .ToList();

        var resolved = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
        foreach (var field in uniqueFields)
        {
            var values = await unitInValueRepo.GetFieldValuesAsync(template.UnitId, new List<string> { field }, ct);
            var rawValue = values.FirstOrDefault().Value;
            var letters = string.IsNullOrEmpty(rawValue) ? string.Empty : new string(rawValue.Where(char.IsLetter).ToArray());
            resolved[$"%БУКВЫ:{field}%"] = letters;
        }

        var result = input;
        foreach (Match m in matches)
        {
            if (resolved.TryGetValue(m.Value, out var val))
                result = result.Replace(m.Value, val, StringComparison.OrdinalIgnoreCase);
        }
        return result;
    }
}