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 FieldShortcodeHandler : IShortcodeHandler
{
    private readonly IUnitInValueRepository unitInValueRepository;
    private readonly ILogger<FieldShortcodeHandler> logger;
    public int Order => 90; // Всегда последним

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

    public ShortcodeDataRequirementsEnum Requirements => ShortcodeDataRequirementsEnum.None;

    public FieldShortcodeHandler(IUnitInValueRepository unitInValueRepository, ILogger<FieldShortcodeHandler> logger)
    {
        this.unitInValueRepository = unitInValueRepository;
        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 fieldNames = matches.Cast<Match>()
            .Select(m => m.Value.Trim('%').ToUpperInvariant())
            .Distinct()
            .ToList();

        if (fieldNames.Count == 0) return input;

        var fieldValues = await unitInValueRepository.GetFieldValuesAsync(template.UnitId, fieldNames, ct).ConfigureAwait(false);

        var valuesMap = fieldValues
            .GroupBy(x => x.FieldName, StringComparer.OrdinalIgnoreCase)
            .ToDictionary(
                g => g.Key,
                g => string.Join(", ", g.Select(v => v.Value ?? "null")),
                StringComparer.OrdinalIgnoreCase);

        var result = input;
        foreach (var match in matches.Cast<Match>())
        {
            var fieldName = match.Value.Trim('%').ToUpperInvariant();
            if (valuesMap.TryGetValue(fieldName, out var combinedValue))
            {
                result = result.Replace(match.Value, combinedValue, StringComparison.OrdinalIgnoreCase);
            }
            else
            {
                logger.LogDebug("[{Caller}] Поле '{FieldName}' не найдено для UnitId={UnitId}. Шорткод пропущен.", caller, fieldName, template.UnitId);
            }
        }

        return result;
    }
}