/**
 * Grades Controller
 * Student grade management and reporting
 *
 * Grades store raw marks + a per-row `grading_scale` override. The
 * `grade` text column is the resolver-derived letter at write time;
 * the resolved letter on read uses the live chain so a school default
 * change immediately applies to historical rows.
 */

const express = require('express');
const router = express.Router();
const { v4: uuidv4 } = require('uuid');
const {
  letterFor,
  resolveScale,
  isValidScaleKey,
  loadDefaultScaleKey,
  DEFAULT_SCALE_KEY,
  SCALES
} = require('../utils/gradeScales');

// Database path
const dbPath = process.env.DB_PATH || require('path').join(__dirname, '../../data/school.db');
const Database = require('better-sqlite3');
let db;

const getDb = () => {
  if (!db) {
    db = new Database(dbPath);
    db.pragma('foreign_keys = ON');
  }
  return db;
};

const readDefaultScale = () => loadDefaultScaleKey(getDb());

/**
 * Compute the percentage that a row's `marks` / `total_marks` represents.
 * Mirrors the inline `marks / total_marks * 100` used throughout the
 * existing controller so read-time and write-time derivations agree.
 */
const rowPercentage = (row) => {
  if (!row || !row.total_marks) return 0;
  return (row.marks / row.total_marks) * 100;
};

/**
 * Decorate a row with the resolved band. Adds:
 *   - letter           primary display letter
 *   - descriptor       secondary text (or null)
 *   - points           ZIMSEC numeric points (or null)
 *   - resolved_scale   actual scale key used
 *   - percentage       recomputed (so callers don't redo the math)
 *   - grade_letter     legacy alias of `letter`
 */
const decorate = (row, defaultScale) => {
  if (!row) return row;
  const pct = rowPercentage(row);
  const band = letterFor(pct, row.grading_scale || defaultScale);
  return {
    ...row,
    percentage: pct,
    letter: band.letter,
    descriptor: band.descriptor,
    points: band.points,
    resolved_scale: band.scale,
    resolved_scale_label: band.label,
    grade_letter: band.letter, // legacy alias
  };
};

// Auth middleware
const auth = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(401).json({ error: 'No token provided' });
  try {
    const jwt = require('jsonwebtoken');
    const { jwtSecret: JWT_SECRET } = require('../config');
    req.user = jwt.verify(token, JWT_SECRET);
    next();
  } catch (err) {
    res.status(401).json({ error: 'Invalid token' });
  }
};

// Admin or teacher only
const adminOrTeacher = (req, res, next) => {
  if (!['school_admin', 'systems_admin'].includes(req.user.role) && req.user.role !== 'teacher') {
    return res.status(403).json({ error: 'Admin or Teacher access required' });
  }
  next();
};

// Admin-only middleware
const adminOnly = (req, res, next) => {
  if (!['school_admin', 'systems_admin'].includes(req.user.role)) {
    return res.status(403).json({ error: 'Admin access required' });
  }
  next();
};

// ============ GRADES CRUD ============

/**
 * @openapi
 * /api/grades:
 *   get:
 *     summary: List grades
 *     description: |
 *       Returns grades joined with student, subject, class, and
 *       grader names. Optional filters: `student_id`, `subject_id`,
 *       `class_id`, `exam_type`, `academic_year`, `term`. Students
 *       only see their own grades; parents see their children's
 *       grades; staff see all.
 *     tags:
 *       - Grades
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: student_id
 *         schema: { type: integer }
 *       - in: query
 *         name: subject_id
 *         schema: { type: integer }
 *       - in: query
 *         name: class_id
 *         schema: { type: integer }
 *       - in: query
 *         name: exam_type
 *         schema: { type: string }
 *       - in: query
 *         name: academic_year
 *         schema: { type: string }
 *       - in: query
 *         name: term
 *         schema: { type: string }
 *     responses:
 *       200:
 *         description: Grade list
 *         content:
 *           application/json:
 *             schema:
 *               type: array
 *               items: { type: object }
 *       401: { description: Unauthorized }
 *       500: { description: Server error }
 */
router.get('/', auth, (req, res) => {
  try {
    const { student_id, subject_id, class_id, exam_type, academic_year, term } = req.query;
    
    let query = `
      SELECT g.*, 
        u.first_name || ' ' || u.last_name as student_name,
        s.name as subject_name,
        c.name as class_name,
        t.first_name || ' ' || t.last_name as graded_by_name
      FROM grades g
      JOIN users u ON g.student_id = u.id
      JOIN subjects s ON g.subject_id = s.id
      LEFT JOIN classes c ON s.class_id = c.id
      LEFT JOIN users t ON g.graded_by = t.id
      WHERE g.is_deleted = 0
    `;
    const params = [];
    
    // Students can only see their own grades
    if (req.user.role === 'student') {
      query += ' AND g.student_id = ?';
      params.push(req.user.id);
    } else if (req.user.role === 'parent') {
      // Parents can see their children's grades
      query += ' AND g.student_id IN (SELECT id FROM users WHERE is_deleted = 0 AND (id IN (SELECT student_id FROM enrollments WHERE is_deleted = 0) OR 1=0))';
    } else {
      if (student_id) {
        query += ' AND g.student_id = ?';
        params.push(student_id);
      }
    }
    
    if (subject_id) {
      query += ' AND g.subject_id = ?';
      params.push(subject_id);
    }
    if (class_id) {
      query += ' AND s.class_id = ?';
      params.push(class_id);
    }
    if (exam_type) {
      query += ' AND g.exam_type = ?';
      params.push(exam_type);
    }
    if (academic_year) {
      query += ' AND g.academic_year = ?';
      params.push(academic_year);
    }
    if (term) {
      query += ' AND g.term = ?';
      params.push(term);
    }
    
    query += ' ORDER BY g.graded_at DESC';

    const grades = getDb().prepare(query).all(...params);
    const defaultScale = readDefaultScale();
    res.json(grades.map((g) => decorate(g, defaultScale)));
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * @openapi
 * /api/grades/{id}:
 *   get:
 *     summary: Get grade by id
 *     description: |
 *       Returns a single grade with student, subject, class, and
 *       grader details. Students can only access their own grades.
 *     tags:
 *       - Grades
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: id
 *         required: true
 *         schema: { type: integer }
 *     responses:
 *       200:
 *         description: Grade detail
 *         content:
 *           application/json:
 *             schema: { type: object }
 *       401: { description: Unauthorized }
 *       403: { description: Access denied }
 *       404: { description: Grade not found }
 *       500: { description: Server error }
 */
router.get('/:id', auth, (req, res) => {
  try {
    const grade = getDb().prepare(`
      SELECT g.*, 
        u.first_name || ' ' || u.last_name as student_name,
        s.name as subject_name,
        c.name as class_name,
        t.first_name || ' ' || t.last_name as graded_by_name
      FROM grades g
      JOIN users u ON g.student_id = u.id
      JOIN subjects s ON g.subject_id = s.id
      LEFT JOIN classes c ON s.class_id = c.id
      LEFT JOIN users t ON g.graded_by = t.id
      WHERE g.id = ? AND g.is_deleted = 0
    `).get(req.params.id);
    
    if (!grade) {
      return res.status(404).json({ error: 'Grade not found' });
    }
    
    // Students can only see their own grades
    if (req.user.role === 'student' && grade.student_id !== req.user.id) {
      return res.status(403).json({ error: 'Access denied' });
    }

    res.json(decorate(grade, readDefaultScale()));
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * @openapi
 * /api/grades:
 *   post:
 *     summary: Create grade
 *     description: |
 *       Creates a new grade. Calculates the percentage and letter
 *       grade server-side. Restricted to admin or teacher roles.
 *     tags:
 *       - Grades
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required:
 *               - student_id
 *               - subject_id
 *               - exam_type
 *               - marks
 *             properties:
 *               student_id: { type: integer }
 *               subject_id: { type: integer }
 *               exam_type: { type: string }
 *               marks: { type: number }
 *               total_marks: { type: number }
 *               remarks: { type: string }
 *               academic_year: { type: string }
 *               term: { type: string }
 *     responses:
 *       201:
 *         description: Created grade
 *         content:
 *           application/json:
 *             schema: { type: object }
 *       400: { description: Validation error }
 *       401: { description: Unauthorized }
 *       403: { description: Admin or Teacher only }
 *       500: { description: Server error }
 */
router.post('/', auth, adminOrTeacher, (req, res) => {
  try {
    const { student_id, subject_id, exam_type, marks, total_marks, remarks, academic_year, term, grading_scale } = req.body;

    if (!student_id || !subject_id || !exam_type || marks === undefined) {
      return res.status(400).json({ error: 'student_id, subject_id, exam_type, and marks are required' });
    }
    if (grading_scale != null && !isValidScaleKey(grading_scale)) {
      return res.status(400).json({ error: `Invalid grading_scale: ${grading_scale}` });
    }

    const effectiveTotal = total_marks || 100;
    const percentage = (marks / effectiveTotal) * 100;
    const defaultScale = readDefaultScale();
    const band = letterFor(percentage, grading_scale || defaultScale);
    const uid = uuidv4();

    const result = getDb().prepare(`
      INSERT INTO grades (uid, student_id, subject_id, exam_type, marks, total_marks, grade, grading_scale, remarks, graded_by, academic_year, term)
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    `).run(uid, student_id, subject_id, exam_type, marks, effectiveTotal, band.letter, grading_scale || null, remarks, req.user.id, academic_year, term);

    const newGrade = getDb().prepare(`
      SELECT g.*, u.first_name || ' ' || u.last_name as student_name, s.name as subject_name
      FROM grades g
      JOIN users u ON g.student_id = u.id
      JOIN subjects s ON g.subject_id = s.id
      WHERE g.id = ?
    `).get(result.lastInsertRowid);

    res.status(201).json(decorate(newGrade, defaultScale));
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * @openapi
 * /api/grades/bulk:
 *   post:
 *     summary: Bulk create grades
 *     description: |
 *       Inserts many grades in a single transaction. Each entry's
 *       percentage and letter grade is computed server-side, and
 *       per-row failures are reported without aborting the batch.
 *       Restricted to admin or teacher roles.
 *     tags:
 *       - Grades
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required:
 *               - grades
 *             properties:
 *               grades:
 *                 type: array
 *                 items:
 *                   type: object
 *                   required:
 *                     - student_id
 *                     - subject_id
 *                     - exam_type
 *                     - marks
 *                   properties:
 *                     student_id: { type: integer }
 *                     subject_id: { type: integer }
 *                     exam_type: { type: string }
 *                     marks: { type: number }
 *                     total_marks: { type: number }
 *                     remarks: { type: string }
 *                     academic_year: { type: string }
 *                     term: { type: string }
 *     responses:
 *       201:
 *         description: Per-row outcomes
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 created: { type: integer }
 *                 failed: { type: integer }
 *                 results:
 *                   type: array
 *                   items: { type: object }
 *       400: { description: Validation error }
 *       401: { description: Unauthorized }
 *       403: { description: Admin or Teacher only }
 *       500: { description: Server error }
 */
router.post('/bulk', auth, adminOrTeacher, (req, res) => {
  try {
    const { grades } = req.body;

    if (!Array.isArray(grades) || grades.length === 0) {
      return res.status(400).json({ error: 'Grades array required' });
    }

    // Validate any per-row grading_scale overrides up-front; a single bad
    // key in a bulk upload should fail the whole request with a clear
    // message rather than silently falling back.
    for (const g of grades) {
        if (g.grading_scale != null && !isValidScaleKey(g.grading_scale)) {
        return res.status(400).json({
          error: `Invalid grading_scale: ${g.grading_scale} (student_id=${g.student_id}, subject_id=${g.subject_id})`,
        });
      }
    }

    const insert = getDb().prepare(`
      INSERT INTO grades (uid, student_id, subject_id, exam_type, marks, total_marks, grade, grading_scale, remarks, graded_by, academic_year, term)
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    `);

    const defaultScale = readDefaultScale();

    const insertMany = getDb().transaction((grades) => {
      const results = [];
      for (const g of grades) {
        const effectiveTotal = g.total_marks || 100;
        const percentage = (g.marks / effectiveTotal) * 100;
        const band = letterFor(percentage, g.grading_scale || defaultScale);
        const uid = uuidv4();

        try {
          insert.run(uid, g.student_id, g.subject_id, g.exam_type, g.marks, effectiveTotal, band.letter, g.grading_scale || null, g.remarks, req.user.id, g.academic_year, g.term);
          results.push({ student_id: g.student_id, subject_id: g.subject_id, success: true });
        } catch (e) {
          results.push({ student_id: g.student_id, error: e.message, success: false });
        }
      }
      return results;
    });

    const results = insertMany(grades);

    res.status(201).json({
      created: results.filter(r => r.success).length,
      failed: results.filter(r => !r.success).length,
      results
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * @openapi
 * /api/grades/{id}:
 *   put:
 *     summary: Update grade
 *     description: |
 *       Updates the `marks` (and re-computes the letter grade) and
 *       optionally the `remarks`. Restricted to admin or teacher
 *       roles.
 *     tags:
 *       - Grades
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: id
 *         required: true
 *         schema: { type: integer }
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required:
 *               - marks
 *             properties:
 *               marks: { type: number }
 *               remarks: { type: string }
 *     responses:
 *       200:
 *         description: Updated grade
 *         content:
 *           application/json:
 *             schema: { type: object }
 *       400: { description: Validation error }
 *       401: { description: Unauthorized }
 *       403: { description: Admin or Teacher only }
 *       404: { description: Grade not found }
 *       500: { description: Server error }
 */
router.put('/:id', auth, adminOrTeacher, (req, res) => {
  try {
    const { marks, remarks, grading_scale } = req.body;

    if (marks === undefined) {
      return res.status(400).json({ error: 'Marks is required' });
    }
    if (grading_scale != null && !isValidScaleKey(grading_scale)) {
      return res.status(400).json({ error: `Invalid grading_scale: ${grading_scale}` });
    }

    const existing = getDb().prepare('SELECT * FROM grades WHERE id = ?').get(req.params.id);
    if (!existing) {
      return res.status(404).json({ error: 'Grade not found' });
    }

    const effectiveScale = grading_scale !== undefined
      ? (grading_scale || existing.grading_scale)
      : existing.grading_scale;
    const percentage = (marks / existing.total_marks) * 100;
    const defaultScale = readDefaultScale();
    const band = letterFor(percentage, effectiveScale || defaultScale);

    getDb().prepare(`
      UPDATE grades SET
        marks = ?,
        grade = ?,
        grading_scale = ?,
        remarks = COALESCE(?, remarks),
        graded_by = ?,
        graded_at = CURRENT_TIMESTAMP,
        updated_at = CURRENT_TIMESTAMP,
        sync_status = 'pending'
      WHERE id = ? AND is_deleted = 0
    `).run(
      marks,
      band.letter,
      grading_scale !== undefined ? grading_scale : existing.grading_scale,
      remarks,
      req.user.id,
      req.params.id
    );

    const updated = getDb().prepare(`
      SELECT g.*, u.first_name || ' ' || u.last_name as student_name, s.name as subject_name
      FROM grades g
      JOIN users u ON g.student_id = u.id
      JOIN subjects s ON g.subject_id = s.id
      WHERE g.id = ?
    `).get(req.params.id);

    res.json(decorate(updated, defaultScale));
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * @openapi
 * /api/grades/{id}:
 *   delete:
 *     summary: Soft-delete grade
 *     description: |
 *       Marks the grade as deleted (`is_deleted = 1`). Restricted to
 *       admin roles (`school_admin`, `systems_admin`).
 *     tags:
 *       - Grades
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: id
 *         required: true
 *         schema: { type: integer }
 *     responses:
 *       200:
 *         description: Deleted
 *         content:
 *           application/json:
 *             schema: { type: object }
 *       401: { description: Unauthorized }
 *       403: { description: Admin only }
 *       500: { description: Server error }
 */
router.delete('/:id', auth, adminOnly, (req, res) => {
  try {
    getDb().prepare(`
      UPDATE grades SET is_deleted = 1, updated_at = CURRENT_TIMESTAMP, sync_status = 'pending'
      WHERE id = ?
    `).run(req.params.id);
    
    res.json({ success: true, message: 'Grade deleted' });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============ STUDENT PROGRESS ============

/**
 * @openapi
 * /api/grades/students/{studentId}/summary:
 *   get:
 *     summary: Student grade summary
 *     description: |
 *       Returns aggregate grade statistics for a student: overall
 *       average, lowest, highest, per-subject averages, per-exam-type
 *       averages, and the 10 most recent grades. Students may only
 *       request their own summary.
 *     tags:
 *       - Grades
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: studentId
 *         required: true
 *         schema: { type: integer }
 *     responses:
 *       200:
 *         description: Student grade summary
 *         content:
 *           application/json:
 *             schema: { type: object }
 *       401: { description: Unauthorized }
 *       403: { description: Access denied }
 *       500: { description: Server error }
 */
router.get('/students/:studentId/summary', auth, (req, res) => {
  try {
    const studentId = parseInt(req.params.studentId);
    
    // Check access
    if (req.user.role === 'student' && req.user.id !== studentId) {
      return res.status(403).json({ error: 'Access denied' });
    }
    
    // Overall stats
    const overall = getDb().prepare(`
      SELECT 
        COUNT(*) as total_grades,
        AVG(marks / total_marks * 100) as average_percentage,
        MIN(marks / total_marks * 100) as lowest_percentage,
        MAX(marks / total_marks * 100) as highest_percentage
      FROM grades
      WHERE student_id = ? AND is_deleted = 0 AND total_marks > 0
    `).get(studentId);
    
    // By subject
    const bySubject = getDb().prepare(`
      SELECT s.id, s.name,
        COUNT(*) as exam_count,
        AVG(g.marks / g.total_marks * 100) as average_percentage,
        MIN(g.marks / g.total_marks * 100) as lowest,
        MAX(g.marks / g.total_marks * 100) as highest
      FROM grades g
      JOIN subjects s ON g.subject_id = s.id
      WHERE g.student_id = ? AND g.is_deleted = 0 AND g.total_marks > 0
      GROUP BY s.id
      ORDER BY average_percentage DESC
    `).all(studentId);
    
    // By exam type
    const byType = getDb().prepare(`
      SELECT exam_type,
        COUNT(*) as count,
        AVG(marks / total_marks * 100) as average_percentage
      FROM grades
      WHERE student_id = ? AND is_deleted = 0 AND total_marks > 0
      GROUP BY exam_type
    `).all(studentId);
    
    // Recent grades
    const recent = getDb().prepare(`
      SELECT g.*, s.name as subject_name
      FROM grades g
      JOIN subjects s ON g.subject_id = s.id
      WHERE g.student_id = ? AND g.is_deleted = 0
      ORDER BY g.graded_at DESC
      LIMIT 10
    `).all(studentId);

    const defaultScale = readDefaultScale();
    const recentDecorated = recent.map((r) => decorate(r, defaultScale));

    res.json({
      overall,
      by_subject: bySubject,
      by_exam_type: byType,
      recent_grades: recentDecorated
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============ CLASS ANALYTICS ============

/**
 * @openapi
 * /api/grades/class/{classId}/performance:
 *   get:
 *     summary: Class performance analytics
 *     description: |
 *       Returns per-student grade aggregates for the given class:
 *       total exams taken, average, lowest, and highest percentage.
 *       Optionally filterable by `subject_id` and `exam_type`.
 *       Restricted to admin or teacher roles.
 *     tags:
 *       - Grades
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: classId
 *         required: true
 *         schema: { type: integer }
 *       - in: query
 *         name: subject_id
 *         schema: { type: integer }
 *       - in: query
 *         name: exam_type
 *         schema: { type: string }
 *     responses:
 *       200:
 *         description: Per-student performance
 *         content:
 *           application/json:
 *             schema:
 *               type: array
 *               items: { type: object }
 *       401: { description: Unauthorized }
 *       403: { description: Admin or Teacher only }
 *       500: { description: Server error }
 */
router.get('/class/:classId/performance', auth, adminOrTeacher, (req, res) => {
  try {
    const { subject_id, exam_type } = req.query;
    
    let query = `
      SELECT 
        u.id,
        u.first_name,
        u.last_name,
        COUNT(g.id) as total_exams,
        AVG(g.marks / g.total_marks * 100) as average_percentage,
        MIN(g.marks / g.total_marks * 100) as lowest,
        MAX(g.marks / g.total_marks * 100) as highest
      FROM grades g
      JOIN users u ON g.student_id = u.id
      JOIN subjects s ON g.subject_id = s.id
      WHERE s.class_id = ? AND g.is_deleted = 0 AND g.total_marks > 0
    `;
    const params = [req.params.classId];
    
    if (subject_id) {
      query += ' AND g.subject_id = ?';
      params.push(subject_id);
    }
    if (exam_type) {
      query += ' AND g.exam_type = ?';
      params.push(exam_type);
    }
    
    query += ' GROUP BY u.id ORDER BY average_percentage DESC';
    
    const students = getDb().prepare(query).all(...params);
    res.json(students);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============ MY GRADES (Student) ============

/**
 * @openapi
 * /api/grades/my/grades:
 *   get:
 *     summary: My grades (student)
 *     description: |
 *       Returns the calling student's grades joined with subject
 *       name and code, plus a small summary of total and average
 *       percentage. Optional filters: `subject_id`, `academic_year`,
 *       `term`.
 *     tags:
 *       - Grades
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: subject_id
 *         schema: { type: integer }
 *       - in: query
 *         name: academic_year
 *         schema: { type: string }
 *       - in: query
 *         name: term
 *         schema: { type: string }
 *     responses:
 *       200:
 *         description: Caller's grades and summary
 *         content:
 *           application/json:
 *             schema: { type: object }
 *       401: { description: Unauthorized }
 *       500: { description: Server error }
 */
router.get('/my/grades', auth, (req, res) => {
  try {
    const { subject_id, academic_year, term } = req.query;
    
    let query = `
      SELECT g.*, s.name as subject_name, s.code as subject_code
      FROM grades g
      JOIN subjects s ON g.subject_id = s.id
      WHERE g.student_id = ? AND g.is_deleted = 0
    `;
    const params = [req.user.id];
    
    if (subject_id) {
      query += ' AND g.subject_id = ?';
      params.push(subject_id);
    }
    if (academic_year) {
      query += ' AND g.academic_year = ?';
      params.push(academic_year);
    }
    if (term) {
      query += ' AND g.term = ?';
      params.push(term);
    }
    
    query += ' ORDER BY g.graded_at DESC';

    const grades = getDb().prepare(query).all(...params);
    const defaultScale = readDefaultScale();
    const decorated = grades.map((g) => decorate(g, defaultScale));

    // Calculate summary
    const summary = {
      total: decorated.length,
      average: decorated.length > 0
        ? decorated.reduce((sum, g) => sum + g.percentage, 0) / decorated.length
        : 0
    };

    res.json({ grades: decorated, summary });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

module.exports = router;