namespace Adapters.Driven.Persistence;

using Adapters.Driven.Persistence.Context;
using Domain.Entities;
using Microsoft.EntityFrameworkCore;

/// <summary>
/// Pre-compiled EF Core queries for frequently used operations.
/// Compiled queries skip expression tree parsing on each execution.
/// </summary>
public static class CompiledQueries
{
    // Student queries
    public static readonly Func<AppDbContext, int, Task<Student?>> GetStudentById =
        EF.CompileAsyncQuery((AppDbContext ctx, int id) =>
            ctx.Students.FirstOrDefault(s => s.Id == id));

    public static readonly Func<AppDbContext, int, Task<bool>> StudentExists =
        EF.CompileAsyncQuery((AppDbContext ctx, int id) =>
            ctx.Students.Any(s => s.Id == id));

    // EmailExists removed - using raw SQL in repository due to value object translation issues

    // Subject queries
    public static readonly Func<AppDbContext, int, Task<Subject?>> GetSubjectById =
        EF.CompileAsyncQuery((AppDbContext ctx, int id) =>
            ctx.Subjects.FirstOrDefault(s => s.Id == id));

    public static readonly Func<AppDbContext, IAsyncEnumerable<Subject>> GetAllSubjects =
        EF.CompileAsyncQuery((AppDbContext ctx) =>
            ctx.Subjects.AsNoTracking());

    // Professor queries
    public static readonly Func<AppDbContext, int, Task<Professor?>> GetProfessorById =
        EF.CompileAsyncQuery((AppDbContext ctx, int id) =>
            ctx.Professors.FirstOrDefault(p => p.Id == id));

    // Enrollment queries
    public static readonly Func<AppDbContext, int, Task<int>> CountStudentEnrollments =
        EF.CompileAsyncQuery((AppDbContext ctx, int studentId) =>
            ctx.Enrollments.Count(e => e.StudentId == studentId));

    public static readonly Func<AppDbContext, int, int, Task<bool>> EnrollmentExists =
        EF.CompileAsyncQuery((AppDbContext ctx, int studentId, int subjectId) =>
            ctx.Enrollments.Any(e => e.StudentId == studentId && e.SubjectId == subjectId));

    // Count queries (for pagination)
    public static readonly Func<AppDbContext, Task<int>> CountStudents =
        EF.CompileAsyncQuery((AppDbContext ctx) =>
            ctx.Students.Count());

    public static readonly Func<AppDbContext, Task<int>> CountSubjects =
        EF.CompileAsyncQuery((AppDbContext ctx) =>
            ctx.Subjects.Count());
}
