"use strict";
const { Router } = require("express");
const { query } = require("../db");
const router = Router();

function parseQ(r) {
  return {
    ...r,
    options: r.options ? (typeof r.options === "string" ? JSON.parse(r.options) : r.options) : [],
    subjectId: r.subject_id,
    correctAnswer: r.correct_answer,
  };
}

async function enrichExams(rows) {
  if (!rows.length) return [];
  const subjects = await query("SELECT id, name FROM subjects");
  const classes = await query("SELECT id, name FROM classes");
  const sMap = new Map(subjects.map(s => [s.id, s.name]));
  const cMap = new Map(classes.map(c => [c.id, c.name]));
  return rows.map(r => ({
    ...r,
    subjectId: r.subject_id,
    classId: r.class_id,
    subjectName: sMap.get(r.subject_id) ?? null,
    className: cMap.get(r.class_id) ?? null,
    durationMinutes: r.duration_minutes,
    totalMarks: r.total_marks,
    passMark: r.pass_mark,
    scheduledAt: r.scheduled_at ? new Date(r.scheduled_at).toISOString() : null,
    createdAt: r.created_at ? new Date(r.created_at).toISOString() : null,
  }));
}

router.get("/exams", async (_req, res) => {
  const rows = await query("SELECT * FROM exams ORDER BY scheduled_at ASC");
  res.json(await enrichExams(rows));
});

router.post("/exams", async (req, res) => {
  const { title, instructions, subjectId, classId, durationMinutes, totalMarks, passMark, status, scheduledAt, venue, questionIds } = req.body || {};
  if (!title || !subjectId || !classId) return res.status(400).json({ error: "title, subjectId, classId required" });
  const sat = scheduledAt ? new Date(scheduledAt).toISOString().slice(0, 19).replace("T", " ") : new Date().toISOString().slice(0, 19).replace("T", " ");
  await query("INSERT INTO exams (title, instructions, subject_id, class_id, duration_minutes, total_marks, pass_mark, status, scheduled_at, venue) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
    [title, instructions || null, subjectId, classId, durationMinutes || 60, totalMarks || 100, passMark || null, status || "draft", sat, venue || null]);
  const [row] = await query("SELECT * FROM exams WHERE id = LAST_INSERT_ID()");
  const examId = row.id;
  if (Array.isArray(questionIds) && questionIds.length) {
    for (let i = 0; i < questionIds.length; i++) {
      await query("INSERT INTO exam_questions (exam_id, question_id, position) VALUES (?, ?, ?)", [examId, questionIds[i], i]);
    }
  }
  await query("INSERT INTO activity_log (type, message) VALUES (?, ?)", ["exam", `Created exam: ${title}`]);
  const [enriched] = await enrichExams([row]);
  res.status(201).json(enriched);
});

router.get("/exams/:id", async (req, res) => {
  const id = parseInt(req.params.id);
  if (!id) return res.status(400).json({ error: "Invalid id" });
  const [row] = await query("SELECT * FROM exams WHERE id = ?", [id]);
  if (!row) return res.status(404).json({ error: "Not found" });
  const links = await query("SELECT * FROM exam_questions WHERE exam_id = ? ORDER BY position", [id]);
  let questions = [];
  if (links.length) {
    const qids = links.map(l => l.question_id);
    const qs = await query(`SELECT * FROM questions WHERE id IN (${qids.map(() => "?").join(",")})`, qids);
    const orderMap = new Map(links.map((l, i) => [l.question_id, i]));
    questions = qs.sort((a, b) => (orderMap.get(a.id) || 0) - (orderMap.get(b.id) || 0)).map(parseQ);
  }
  const [enriched] = await enrichExams([row]);
  res.json({ ...enriched, questions });
});

router.patch("/exams/:id", async (req, res) => {
  const id = parseInt(req.params.id);
  if (!id) return res.status(400).json({ error: "Invalid id" });
  const { title, instructions, subjectId, classId, durationMinutes, totalMarks, passMark, status, scheduledAt, venue, questionIds } = req.body || {};
  const sets = []; const vals = [];
  if (title !== undefined) { sets.push("title = ?"); vals.push(title); }
  if (instructions !== undefined) { sets.push("instructions = ?"); vals.push(instructions); }
  if (subjectId !== undefined) { sets.push("subject_id = ?"); vals.push(subjectId); }
  if (classId !== undefined) { sets.push("class_id = ?"); vals.push(classId); }
  if (durationMinutes !== undefined) { sets.push("duration_minutes = ?"); vals.push(durationMinutes); }
  if (totalMarks !== undefined) { sets.push("total_marks = ?"); vals.push(totalMarks); }
  if (passMark !== undefined) { sets.push("pass_mark = ?"); vals.push(passMark); }
  if (status !== undefined) { sets.push("status = ?"); vals.push(status); }
  if (scheduledAt !== undefined) { sets.push("scheduled_at = ?"); vals.push(new Date(scheduledAt).toISOString().slice(0, 19).replace("T", " ")); }
  if (venue !== undefined) { sets.push("venue = ?"); vals.push(venue); }
  if (sets.length) { vals.push(id); await query(`UPDATE exams SET ${sets.join(", ")} WHERE id = ?`, vals); }
  if (Array.isArray(questionIds)) {
    await query("DELETE FROM exam_questions WHERE exam_id = ?", [id]);
    for (let i = 0; i < questionIds.length; i++) {
      await query("INSERT INTO exam_questions (exam_id, question_id, position) VALUES (?, ?, ?)", [id, questionIds[i], i]);
    }
  }
  const [row] = await query("SELECT * FROM exams WHERE id = ?", [id]);
  if (!row) return res.status(404).json({ error: "Not found" });
  const [enriched] = await enrichExams([row]);
  res.json(enriched);
});

router.delete("/exams/:id", async (req, res) => {
  const id = parseInt(req.params.id);
  if (!id) return res.status(400).json({ error: "Invalid id" });
  await query("DELETE FROM exam_questions WHERE exam_id = ?", [id]);
  await query("DELETE FROM exams WHERE id = ?", [id]);
  res.status(204).end();
});

module.exports = router;
