import express from 'express';
import Student from '../models/Student.js';
import StudentPayment from '../models/StudentPayment.js';
import { protect } from '../middleware/auth.js';

const router = express.Router();
router.use(protect);

const attachBalance = async (students) => {
  const list = Array.isArray(students) ? students : [students];
  return Promise.all(
    list.map(async (s) => {
      const obj = s.toObject ? s.toObject() : { ...s };
      const paid = await StudentPayment.aggregate([
        { $match: { student: s._id, status: 'completed' } },
        { $group: { _id: null, total: { $sum: '$amount' } } },
      ]);
      const totalPaid = paid[0]?.total || 0;
      obj.totalPaid = totalPaid;
      obj.balance = Math.max(0, (obj.tuitionFee || 0) - totalPaid);
      return obj;
    })
  );
};

router.get('/', async (req, res, next) => {
  try {
    const { status, grade, search } = req.query;
    const filter = {};
    if (status) filter.status = status;
    if (grade) filter.grade = grade;
    if (search) {
      filter.$or = [
        { firstName: new RegExp(search, 'i') },
        { lastName: new RegExp(search, 'i') },
        { studentId: new RegExp(search, 'i') },
        { parentName: new RegExp(search, 'i') },
      ];
    }
    const students = await Student.find(filter).sort({ createdAt: -1 });
    res.json(await attachBalance(students));
  } catch (err) {
    next(err);
  }
});

router.get('/:id', async (req, res, next) => {
  try {
    const student = await Student.findById(req.params.id);
    if (!student) return res.status(404).json({ message: 'Student not found' });
    const [withBalance] = await attachBalance([student]);
    res.json(withBalance);
  } catch (err) {
    next(err);
  }
});

router.post('/', async (req, res, next) => {
  try {
    const student = await Student.create(req.body);
    const [withBalance] = await attachBalance([student]);
    res.status(201).json(withBalance);
  } catch (err) {
    next(err);
  }
});

router.put('/:id', async (req, res, next) => {
  try {
    const student = await Student.findByIdAndUpdate(req.params.id, req.body, {
      new: true,
      runValidators: true,
    });
    if (!student) return res.status(404).json({ message: 'Student not found' });
    const [withBalance] = await attachBalance([student]);
    res.json(withBalance);
  } catch (err) {
    next(err);
  }
});

router.delete('/:id', async (req, res, next) => {
  try {
    const student = await Student.findByIdAndDelete(req.params.id);
    if (!student) return res.status(404).json({ message: 'Student not found' });
    await StudentPayment.deleteMany({ student: req.params.id });
    res.json({ message: 'Deleted' });
  } catch (err) {
    next(err);
  }
});

export default router;
