using System.Text.RegularExpressions;
using AxCopilot.Models;

namespace AxCopilot.Services;

/// <summary>
/// Phase L3-3: AI 스니펫 템플릿 서비스.
/// 템플릿 키워드 검색, 프롬프트 확장, LLM 호출 결과 캐싱을 담당합니다.
/// </summary>
public class SnippetTemplateService
{
    private readonly SettingsService _settings;
    private readonly LlmService _llm;

    // 간단한 인메모리 캐시 (키워드+인자 → 결과)
    private readonly Dictionary<string, string> _cache = new();
    private const int MaxCacheSize = 20;

    public SnippetTemplateService(SettingsService settings, LlmService llm)
    {
        _settings = settings;
        _llm      = llm;
    }

    /// <summary>키워드로 템플릿 목록을 검색합니다.</summary>
    public IReadOnlyList<AiSnippetTemplate> Search(string keyword)
    {
        var q = keyword.Trim().ToLowerInvariant();
        return _settings.Settings.AiSnippetTemplates
            .Where(t => string.IsNullOrEmpty(q) ||
                        t.Keyword.Contains(q, StringComparison.OrdinalIgnoreCase) ||
                        t.Name.Contains(q, StringComparison.OrdinalIgnoreCase))
            .ToList();
    }

    /// <summary>
    /// 템플릿 프롬프트에 인자를 채워 LLM 호출 후 결과를 반환합니다.
    /// </summary>
    public async Task<string> GenerateAsync(AiSnippetTemplate template, string argument, CancellationToken ct)
    {
        var prompt = ExpandPrompt(template.Prompt, argument);
        var cacheKey = $"{template.Keyword}::{prompt}";

        if (_cache.TryGetValue(cacheKey, out var cached))
            return cached;

        var messages = new List<ChatMessage>
        {
            new() { Role = "system", Content = "당신은 사용자의 업무를 돕는 AI 어시스턴트입니다. 요청에 맞게 간결하고 정확한 결과를 제공하세요." },
            new() { Role = "user",   Content = prompt }
        };

        var result = await _llm.SendAsync(messages, ct);

        // 캐시 관리
        if (_cache.Count >= MaxCacheSize)
        {
            var oldest = _cache.Keys.First();
            _cache.Remove(oldest);
        }
        _cache[cacheKey] = result;

        return result;
    }

    /// <summary>템플릿 프롬프트의 {0}, {query} 플레이스홀더를 인자로 치환합니다.</summary>
    private static string ExpandPrompt(string prompt, string argument)
    {
        var encoded = argument.Trim();
        prompt = Regex.Replace(prompt, @"\{0\}", encoded);
        prompt = Regex.Replace(prompt, @"\{query\}", encoded);
        prompt = Regex.Replace(prompt, @"\{input\}", encoded);
        return prompt;
    }
}
