import { eq, and } from "drizzle-orm";
import { db } from "../config/database.js";
import {
  exams,
  examQuestions,
  examSubmissions,
  type Exam,
  type NewExam,
  type ExamQuestion,
  type NewExamQuestion,
  type ExamSubmission,
  type NewExamSubmission,
} from "./exams.schema.js";

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

  async findByClassId(classId: string): Promise<Exam[]> {
    return db.select().from(exams).where(eq(exams.classId, classId));
  }

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

  async delete(id: string): Promise<void> {
    await db.delete(exams).where(eq(exams.id, id));
  }

  // Exam questions
  async addQuestions(questions: NewExamQuestion[]): Promise<void> {
    if (questions.length === 0) return;
    await db.insert(examQuestions).values(questions);
  }

  async listQuestions(examId: string): Promise<ExamQuestion[]> {
    return db
      .select()
      .from(examQuestions)
      .where(eq(examQuestions.examId, examId));
  }

  // Exam submissions
  async findSubmission(
    examId: string,
    studentId: string,
  ): Promise<ExamSubmission | undefined> {
    const [result] = await db
      .select()
      .from(examSubmissions)
      .where(
        and(
          eq(examSubmissions.examId, examId),
          eq(examSubmissions.studentId, studentId),
        ),
      )
      .limit(1);
    return result;
  }

  async findSubmissionById(id: string): Promise<ExamSubmission | undefined> {
    const [result] = await db
      .select()
      .from(examSubmissions)
      .where(eq(examSubmissions.id, id))
      .limit(1);
    return result;
  }

  async createSubmission(
    submission: NewExamSubmission,
    tx: typeof db = db,
  ): Promise<void> {
    await tx.insert(examSubmissions).values(submission);
  }

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

export const examsRepository = new ExamsRepository();
