using ClaudeDo.Data.Models;
using Microsoft.EntityFrameworkCore;

namespace ClaudeDo.Data.Repositories;

public sealed class SessionSkillRepository
{
    private readonly ClaudeDoDbContext _context;

    public SessionSkillRepository(ClaudeDoDbContext context) => _context = context;

    public async Task<IReadOnlyList<SessionSkillEntity>> ListAsync(CancellationToken ct = default)
    {
        return await _context.SessionSkills.AsNoTracking()
            .OrderBy(s => s.Name)
            .ToListAsync(ct);
    }

    public async Task<SessionSkillEntity?> GetAsync(string name, CancellationToken ct = default) =>
        await _context.SessionSkills.AsNoTracking().FirstOrDefaultAsync(s => s.Name == name, ct);

    public async Task UpsertAsync(SessionSkillEntity entity, CancellationToken ct = default)
    {
        var existing = await _context.SessionSkills.FirstOrDefaultAsync(s => s.Name == entity.Name, ct);
        if (existing is null)
        {
            _context.SessionSkills.Add(entity);
        }
        else
        {
            existing.SourceUrl = entity.SourceUrl;
            existing.PinnedRef = entity.PinnedRef;
            existing.Subpath = entity.Subpath;
            existing.Description = entity.Description;
            existing.AddedAt = entity.AddedAt;
        }
        await _context.SaveChangesAsync(ct);
    }

    public async Task DeleteAsync(string name, CancellationToken ct = default)
    {
        await _context.SessionSkills
            .Where(s => s.Name == name)
            .ExecuteDeleteAsync(ct);
    }

    public async Task DeleteBySourceAsync(string sourceUrl, CancellationToken ct = default)
    {
        await _context.SessionSkills
            .Where(s => s.SourceUrl == sourceUrl)
            .ExecuteDeleteAsync(ct);
    }

    public async Task<IReadOnlyList<SessionSkillEntity>> ListBySourceAsync(string sourceUrl, CancellationToken ct = default)
    {
        return await _context.SessionSkills.AsNoTracking()
            .Where(s => s.SourceUrl == sourceUrl)
            .OrderBy(s => s.Name)
            .ToListAsync(ct);
    }
}
