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

namespace ClaudeDo.Data.Repositories;

public sealed class DailyNoteRepository
{
    private readonly ClaudeDoDbContext _context;

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

    public async Task<IReadOnlyList<DailyNoteEntity>> ListByDayAsync(DateOnly day, CancellationToken ct = default) =>
        await _context.DailyNotes.AsNoTracking()
            .Where(n => n.Date == day)
            .OrderBy(n => n.SortOrder)
            .ToListAsync(ct);

    public async Task<IReadOnlyList<DailyNoteEntity>> ListBetweenAsync(
        DateOnly start, DateOnly end, CancellationToken ct = default) =>
        await _context.DailyNotes.AsNoTracking()
            .Where(n => n.Date >= start && n.Date <= end)
            .OrderBy(n => n.Date).ThenBy(n => n.SortOrder)
            .ToListAsync(ct);

    /// <summary>Notes an agent wrote on <paramref name="day"/> — the number the MCP cap counts against.</summary>
    public async Task<int> CountAgentNotesAsync(DateOnly day, CancellationToken ct = default) =>
        await _context.DailyNotes.AsNoTracking()
            .CountAsync(n => n.Date == day && n.FromAgent, ct);

    public async Task<DailyNoteEntity> AddAsync(
        DateOnly day, string text, bool fromAgent = false, CancellationToken ct = default)
    {
        var nextOrder = await _context.DailyNotes
            .Where(n => n.Date == day)
            .Select(n => (int?)n.SortOrder)
            .MaxAsync(ct) ?? -1;

        var note = new DailyNoteEntity
        {
            Date = day,
            Text = text,
            SortOrder = nextOrder + 1,
            FromAgent = fromAgent,
            CreatedAt = DateTime.UtcNow,
        };
        _context.DailyNotes.Add(note);
        await _context.SaveChangesAsync(ct);
        return note;
    }

    public async Task UpdateAsync(string id, string text, CancellationToken ct = default)
    {
        var row = await _context.DailyNotes.FirstOrDefaultAsync(n => n.Id == id, ct);
        if (row is null) return;
        row.Text = text;
        await _context.SaveChangesAsync(ct);
    }

    public async Task DeleteAsync(string id, CancellationToken ct = default)
    {
        var row = await _context.DailyNotes.FirstOrDefaultAsync(n => n.Id == id, ct);
        if (row is null) return;
        _context.DailyNotes.Remove(row);
        await _context.SaveChangesAsync(ct);
    }
}
