using System.IO;
using System.Text;

namespace AxCopilot.Services.Agent;

/// <summary>
/// Phase 18-A: 에이전트 타입별 영속 메모리.
/// 저장: %APPDATA%\AxCopilot\agent-memory\{agentType}\MEMORY.md
/// 동일 타입 에이전트 재실행 시 이전 학습 유지.
/// </summary>
public class AgentTypeMemoryRepository : IAgentMemoryRepository
{
    private static readonly string BaseDir = System.IO.Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
        "AxCopilot", "agent-memory");

    /// <summary>에이전트 타입 메모리 로드.</summary>
    public async Task<string?> LoadMemoryAsync(string agentType)
    {
        var path = GetPath(agentType);
        if (!File.Exists(path)) return null;
        return await File.ReadAllTextAsync(path, Encoding.UTF8);
    }

    /// <summary>에이전트 타입 메모리 전체 저장.</summary>
    public async Task SaveMemoryAsync(string agentType, string content)
    {
        Directory.CreateDirectory(GetDir(agentType));
        await File.WriteAllTextAsync(GetPath(agentType), content, Encoding.UTF8);
    }

    /// <summary>학습 내용을 기존 메모리에 추가.</summary>
    public async Task AppendLearnAsync(string agentType, string learning)
    {
        var existing = await LoadMemoryAsync(agentType) ?? "# 에이전트 메모리\n";
        var entry = $"\n- [{DateTime.Now:yyyy-MM-dd HH:mm}] {learning}";
        await SaveMemoryAsync(agentType, existing + entry);
    }

    /// <summary>등록된 에이전트 타입 목록.</summary>
    public IReadOnlyList<string> GetAgentTypes()
    {
        if (!Directory.Exists(BaseDir)) return Array.Empty<string>();
        return Directory.GetDirectories(BaseDir)
            .Select(d => System.IO.Path.GetFileName(d) ?? "")
            .Where(n => !string.IsNullOrEmpty(n))
            .ToList();
    }

    /// <summary>에이전트 타입 메모리 삭제.</summary>
    public void DeleteMemory(string agentType)
    {
        var dir = GetDir(agentType);
        if (Directory.Exists(dir)) Directory.Delete(dir, true);
    }

    private static string GetDir(string agentType)
        => System.IO.Path.Combine(BaseDir, SanitizeAgentType(agentType));

    private static string GetPath(string agentType)
        => System.IO.Path.Combine(GetDir(agentType), "MEMORY.md");

    private static string SanitizeAgentType(string agentType)
        => string.Concat(agentType.Where(c => char.IsLetterOrDigit(c) || c == '_' || c == '-'));
}
