using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace JobTrackerApi.Services.JobImport;

public static class SkillTagger
{
    private static readonly (string Tag, Regex Pattern, int Weight)[] Patterns =
    {
        // Symbol skills need punctuation-tolerant boundaries: \b fails next to '#'/'.'
        // (both non-word chars), which previously left "C#," and ".NET," undetected.
        ("C#", new Regex(@"(?<![A-Za-z0-9#])C#|\bc[-\s]?sharp\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 6),
        ("C++", new Regex(@"(?<![A-Za-z0-9+])C\+\+(?!\+)|\bcpp\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 6),
        ("ASP.NET Core", new Regex(@"\bASP\.NET\s+Core\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 6),
        ("Entity Framework Core", new Regex(@"\bEntity Framework(?: Core)?\b|\bEF Core\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 6),
        (".NET", new Regex(@"(?<![A-Za-z0-9.])\.NET\b|\bDOTNET\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 6),
        ("Python", new Regex(@"\bPython\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 6),
        ("Java", new Regex(@"\bJava\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 5),
        ("Go", new Regex(@"\bGolang\b|\bGo\s+(?:programming|language|developer|engineer)\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 5),
        ("JavaScript", new Regex(@"\bJavaScript\b|\bJS\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 5),
        ("TypeScript", new Regex(@"\bTypeScript\b|\bTS\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 5),
        ("React", new Regex(@"\bReact\b|\bReact\.js\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 5),
        ("Node.js", new Regex(@"\bNode\b|\bNode\.js\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 5),
        ("Next.js", new Regex(@"\bNext\.js\b|\bNextJS\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 5),
        ("SQL", new Regex(@"\bSQL\b|\bPostgreSQL\b|\bMySQL\b|\bSQLite\b|\bMS\s*SQL\b|\bT-?SQL\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 5),
        ("Docker", new Regex(@"\bDocker\b|\bcontainers?\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 5),
        ("Kubernetes", new Regex(@"\bKubernetes\b|\bK8s\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 5),
        ("Terraform", new Regex(@"\bTerraform\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 5),
        ("Azure DevOps", new Regex(@"\bAzure\s+DevOps\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 5),
        ("Azure", new Regex(@"\bAzure\b(?!\s+DevOps)", RegexOptions.IgnoreCase | RegexOptions.Compiled), 5),
        ("AWS", new Regex(@"\bAWS\b|\bAmazon Web Services\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 5),
        ("Kafka", new Regex(@"\b(?:Apache\s+)?Kafka\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 5),
        ("Redis", new Regex(@"\bRedis\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 5),
        ("Linux", new Regex(@"\bLinux\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 5),
        ("CI/CD", new Regex(@"\bCI/CD\b|continuous integration|continuous delivery|continuous deployment", RegexOptions.IgnoreCase | RegexOptions.Compiled), 4),
        ("REST APIs", new Regex(@"\bREST\b|RESTful|API development|web services", RegexOptions.IgnoreCase | RegexOptions.Compiled), 4),
        ("GraphQL", new Regex(@"\bGraphQL\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 4),
        ("Testing", new Regex(@"\bunit tests?\b|\bintegration tests?\b|\btesting\b|\bTDD\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 4),
        ("Agile", new Regex(@"\bAgile\b|\bScrum\b|\bKanban\b", RegexOptions.IgnoreCase | RegexOptions.Compiled), 3),
        ("Communication", new Regex(@"communication skills?|communicate effectively|stakeholder management", RegexOptions.IgnoreCase | RegexOptions.Compiled), 3),
        ("Collaboration", new Regex(@"collaborat|cross-functional|team player|work closely with", RegexOptions.IgnoreCase | RegexOptions.Compiled), 3),
        ("Problem Solving", new Regex(@"problem solving|solve complex|analytical|troubleshoot", RegexOptions.IgnoreCase | RegexOptions.Compiled), 3),
        ("Leadership", new Regex(@"leadership|mentor|coaching|leading teams?", RegexOptions.IgnoreCase | RegexOptions.Compiled), 3),
        ("Ownership", new Regex(@"ownership|self-starter|take initiative|proactive", RegexOptions.IgnoreCase | RegexOptions.Compiled), 3),
        ("Adaptability", new Regex(@"adaptable|flexible|fast-paced|ambiguity", RegexOptions.IgnoreCase | RegexOptions.Compiled), 2),
        ("Attention to Detail", new Regex(@"attention to detail|detail-oriented|quality-focused", RegexOptions.IgnoreCase | RegexOptions.Compiled), 2),
    };

    /// <summary>True if `text` matches the same synonym pattern used to detect `tag` in job postings.
    /// Lets CV-side matching accept variants (e.g. "JS" for "JavaScript", "K8s" for "Kubernetes").</summary>
    public static bool MatchesTag(string tag, string? text)
    {
        if (string.IsNullOrWhiteSpace(text)) return false;
        foreach (var (t, pattern, _) in Patterns)
        {
            if (string.Equals(t, tag, StringComparison.OrdinalIgnoreCase)) return pattern.IsMatch(text);
        }
        return false;
    }

    public static string[] Detect(string? description)
    {
        if (string.IsNullOrWhiteSpace(description)) return Array.Empty<string>();

        var matches = new List<(string Tag, int Score)>();
        foreach (var (tag, pattern, weight) in Patterns)
        {
            if (pattern.IsMatch(description)) matches.Add((tag, weight));
        }

        return matches
            .GroupBy(x => x.Tag, StringComparer.OrdinalIgnoreCase)
            .Select(g => new { Tag = g.Key, Score = g.Max(x => x.Score) })
            .OrderByDescending(x => x.Score)
            .ThenBy(x => x.Tag, StringComparer.OrdinalIgnoreCase)
            .Take(12)
            .Select(x => x.Tag)
            .ToArray();
    }
}
