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

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

router.get('/', async (req, res, next) => {
  try {
    const { student, status, paymentType, month, year } = req.query;
    const filter = {};
    if (student) filter.student = student;
    if (status) filter.status = status;
    if (paymentType) filter.paymentType = paymentType;
    if (month && year) {
      const start = new Date(Number(year), Number(month) - 1, 1);
      const end = new Date(Number(year), Number(month), 0, 23, 59, 59);
      filter.paidAt = { $gte: start, $lte: end };
    }
    const payments = await StudentPayment.find(filter)
      .populate('student', 'firstName lastName studentId grade section')
      .populate('recordedBy', 'name')
      .sort({ paidAt: -1 });
    res.json(payments);
  } catch (err) {
    next(err);
  }
});

router.get('/summary', async (req, res, next) => {
  try {
    const now = new Date();
    const month = Number(req.query.month) || now.getMonth() + 1;
    const year = Number(req.query.year) || now.getFullYear();
    const start = new Date(year, month - 1, 1);
    const end = new Date(year, month, 0, 23, 59, 59);

    const [monthlyPayments, allStudents, outstandingAgg] = await Promise.all([
      StudentPayment.find({ paidAt: { $gte: start, $lte: end }, status: 'completed' }),
      Student.countDocuments({ status: 'active' }),
      Student.find({ status: 'active' }),
    ]);

    let totalOutstanding = 0;
    for (const s of outstandingAgg) {
      const paid = await StudentPayment.aggregate([
        { $match: { student: s._id, status: 'completed' } },
        { $group: { _id: null, total: { $sum: '$amount' } } },
      ]);
      totalOutstanding += Math.max(0, s.tuitionFee - (paid[0]?.total || 0));
    }

    const totalCollected = monthlyPayments.reduce((sum, p) => sum + p.amount, 0);
    const pendingCount = await StudentPayment.countDocuments({ status: 'pending' });

    const byType = await StudentPayment.aggregate([
      { $match: { paidAt: { $gte: start, $lte: end }, status: 'completed' } },
      { $group: { _id: '$paymentType', total: { $sum: '$amount' }, count: { $sum: 1 } } },
    ]);

    res.json({
      month,
      year,
      totalCollected,
      paymentCount: monthlyPayments.length,
      activeStudents: allStudents,
      totalOutstanding,
      pendingCount,
      byType: byType.map((t) => ({ type: t._id, total: t.total, count: t.count })),
    });
  } catch (err) {
    next(err);
  }
});

router.post('/', async (req, res, next) => {
  try {
    const student = await Student.findById(req.body.student);
    if (!student) return res.status(404).json({ message: 'Student not found' });

    const payment = await StudentPayment.create({
      ...req.body,
      recordedBy: req.user._id,
      paidAt: req.body.paidAt || new Date(),
    });

    const populated = await StudentPayment.findById(payment._id)
      .populate('student', 'firstName lastName studentId grade')
      .populate('recordedBy', 'name');

    res.status(201).json(populated);
  } catch (err) {
    next(err);
  }
});

router.patch('/:id/status', async (req, res, next) => {
  try {
    const payment = await StudentPayment.findByIdAndUpdate(
      req.params.id,
      { status: req.body.status },
      { new: true }
    )
      .populate('student', 'firstName lastName studentId')
      .populate('recordedBy', 'name');
    if (!payment) return res.status(404).json({ message: 'Payment not found' });
    res.json(payment);
  } catch (err) {
    next(err);
  }
});

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

export default router;
