using Nexus.Api.Helpers;
using System.Text.RegularExpressions;

namespace Nexus.Api.Services;

public sealed partial class IncidentService : IIncidentService
{
    private const string BasePath = "/mnt/workspace-iris/memory/incidents";

    public async Task<IReadOnlyList<IncidentSummary>> GetAllAsync()
    {
        if (!Directory.Exists(BasePath))
            return Array.Empty<IncidentSummary>();

        var incidents = new List<IncidentSummary>();
        foreach (var file in Directory.GetFiles(BasePath, "*.md").OrderByDescending(f => f).Take(50))
        {
            var fi = new FileInfo(file);
            if (fi.Length > 1_000_000) continue;

            var name = Path.GetFileNameWithoutExtension(file);
            var content = await File.ReadAllTextAsync(file);
            var title = ExtractTitle(name, content);
            var date = ExtractDate(name);
            var severity = ExtractSeverity(content);
            var excerpt = ExtractExcerpt(content);

            incidents.Add(new IncidentSummary(Path.GetFileName(file), title, date, severity, excerpt, fi.Length));
        }

        return incidents;
    }

    public async Task<IncidentDetail?> GetByNameAsync(string name)
    {
        if (!PathSecurityHelper.TryResolveSafePath(BasePath, name, out var filePath))
            return null;

        if (!File.Exists(filePath!))
        {
            if (!name.EndsWith(".md", StringComparison.OrdinalIgnoreCase))
                filePath = Path.Combine(BasePath, name + ".md");
            if (!File.Exists(filePath!))
                return null;
        }

        var content = await File.ReadAllTextAsync(filePath!);
        var fi = new FileInfo(filePath!);
        var fileName = Path.GetFileName(filePath!);
        var title = ExtractTitle(Path.GetFileNameWithoutExtension(filePath!), content);
        var date = ExtractDate(fileName);

        return new IncidentDetail(fileName, title, date, content, fi.Length);
    }

    private static string ExtractTitle(string name, string content)
    {
        var match = TitleRegex().Match(content);
        return match.Success ? match.Groups[1].Value.Trim() : name;
    }

    private static string? ExtractDate(string fileName)
    {
        var match = DateRegex().Match(fileName);
        return match.Success ? match.Groups[1].Value : null;
    }

    private static string ExtractSeverity(string content)
    {
        var match = SeverityRegex().Match(content);
        return match.Success ? match.Groups[1].Value.Trim() : "unknown";
    }

    private static string ExtractExcerpt(string content)
    {
        var excerptEnd = content.IndexOf("\n## ", StringComparison.Ordinal);
        var excerpt = excerptEnd > 0 ? content[..excerptEnd].Trim() : content[..Math.Min(300, content.Length)].Trim();
        return excerpt.Length > 200 ? excerpt[..200] + "…" : excerpt;
    }

    [GeneratedRegex(@"^#\s+(.+)$", RegexOptions.Multiline)]
    private static partial Regex TitleRegex();

    [GeneratedRegex(@"^(\d{4}-\d{2}-\d{2})")]
    private static partial Regex DateRegex();

    [GeneratedRegex(@"\*\*Severity:\*\*\s*(.+)$", RegexOptions.Multiline)]
    private static partial Regex SeverityRegex();
}
