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

namespace PARR.Core.Services.Shortcodes.Handlers;

internal class RelatedUnitTagShortcodeHandler : IShortcodeHandler
{
    private readonly ILogger<RelatedUnitTagShortcodeHandler> logger;

    public int Order => 75;

    private static readonly Regex _pattern = new(@"%ТЕГ_СВЯЗИ:([^%]+)%", RegexOptions.Compiled | RegexOptions.IgnoreCase);
    public Regex Pattern => _pattern;

    public ShortcodeDataRequirementsEnum Requirements => ShortcodeDataRequirementsEnum.UnitsInTemplateTags;

    public RelatedUnitTagShortcodeHandler(ILogger<RelatedUnitTagShortcodeHandler> logger)
    {
        this.logger = logger;
    }

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

        var uniqueTags = matches.Cast<Match>()
            .Select(m => m.Groups[1].Value.Trim())
            .Distinct(StringComparer.OrdinalIgnoreCase)
            .ToList();

        var resolved = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
        foreach (var tagName in uniqueTags)
        {
            resolved[$"%ТЕГ_СВЯЗИ:{tagName}%"] = GetMostPopularTagValue(data.RelatedUnitTags, tagName, caller);
        }

        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 Task.FromResult(result);
    }

    private string GetMostPopularTagValue(Dictionary<Guid, List<string>>? relatedTags, string tagName, string caller)
    {
        if (relatedTags == null || relatedTags.Count == 0)
        {
            return string.Empty;
        }

        var prefix = tagName + ":";
        var matchedValues = new List<string>();

        foreach (var tagList in relatedTags.Values)
        {
            foreach (var tag in tagList)
            {
                string? matchedValue = null;

                if (tag.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
                {
                    matchedValue = tag.Substring(prefix.Length);
                }
                else if (tag.Equals(tagName, StringComparison.OrdinalIgnoreCase))
                {
                    matchedValue = tag;
                }

                if (!string.IsNullOrEmpty(matchedValue))
                {
                    matchedValues.Add(matchedValue);
                }
            }
        }

        if (matchedValues.Count == 0)
        {
            return string.Empty;
        }

        var mostPopular = matchedValues
            .GroupBy(v => v, StringComparer.OrdinalIgnoreCase)
            .Select(g => new { Value = g.Key, Count = g.Count() })
            .OrderByDescending(x => x.Count)
            .ThenBy(x => x.Value, StringComparer.OrdinalIgnoreCase)
            .FirstOrDefault()!;

        return mostPopular.Value;
    }
}