import { eq, and, inArray } from "drizzle-orm";
import { db } from "../config/database.js";
import {
  attendance,
  type Attendance,
  type NewAttendance,
} from "./attendance.schema.js";
import { schedules } from "../scheduling/scheduling.schema.js";

export class AttendanceRepository {
  async findById(id: string): Promise<Attendance | undefined> {
    const [result] = await db
      .select()
      .from(attendance)
      .where(eq(attendance.id, id))
      .limit(1);
    return result;
  }

  async findByScheduleAndStudent(
    scheduleId: string,
    studentId: string,
  ): Promise<Attendance | undefined> {
    const [result] = await db
      .select()
      .from(attendance)
      .where(
        and(
          eq(attendance.scheduleId, scheduleId),
          eq(attendance.studentId, studentId),
        ),
      )
      .limit(1);
    return result;
  }

  async findByStudentId(studentId: string): Promise<Attendance[]> {
    return db
      .select()
      .from(attendance)
      .where(eq(attendance.studentId, studentId));
  }

  async findByScheduleId(scheduleId: string): Promise<Attendance[]> {
    return db
      .select()
      .from(attendance)
      .where(eq(attendance.scheduleId, scheduleId));
  }

  async findByClassId(classId: string): Promise<Attendance[]> {
    // Two-step query: find schedule IDs for class, then attendance by those IDs
    const classSchedules = await db
      .select({ id: schedules.id })
      .from(schedules)
      .where(eq(schedules.classId, classId));
    const scheduleIds = classSchedules.map((s) => s.id);
    if (scheduleIds.length === 0) return [];
    return db
      .select()
      .from(attendance)
      .where(inArray(attendance.scheduleId, scheduleIds));
  }

  async create(record: NewAttendance, tx: typeof db = db): Promise<void> {
    await tx.insert(attendance).values(record);
  }

  async update(id: string, data: Partial<NewAttendance>): Promise<void> {
    await db.update(attendance).set(data).where(eq(attendance.id, id));
  }
}

export const attendanceRepository = new AttendanceRepository();
