const express = require('express');
const Adminrouter = express.Router();
const Student = require('../models/Student');
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const authenticateAdmin = require('../middleware/Adminmiddleware');
const Teacher = require('../models/Teacher');
const Admin = require('../models/Admin');
const Banner = require('../models/Banner');
const Gallery = require('../models/Gallery');

// Configure multer for file uploads
const storage = multer.diskStorage({
    destination:function(req,file,cb){
      cb(null,"./public/uploads/students")
  },
  filename:function(req,file,cb){
      cb(null,`${Date.now()}_${file.originalname}`)
  }

});

const fileFilter = (req, file, cb) => {
  // Check if file is an image
  if (file.mimetype.startsWith('image/')) {
    cb(null, true);
  } else {
    cb(new Error('Only image files are allowed!'), false);
  }
};

const upload = multer({
  storage: storage,
  fileFilter: fileFilter,
  limits: {
    fileSize: 5 * 1024 * 1024 // 5MB limit
  }
});

// Apply middleware to all routes
Adminrouter.use(authenticateAdmin);
// ==================== DASHBOARD DATA ROUTE ====================
// GET comprehensive dashboard statistics
Adminrouter.get('/dashboard-data', async (req, res) => {
  try {
    // Get current date info for filters
    const now = new Date();
    const currentMonth = now.toLocaleString('default', { month: 'long' });
    const currentYear = now.getFullYear();
    
    // Get start and end of current month for date filtering
    const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
    const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59);
    
    // Get start and end of current day
    const startOfDay = new Date(now.setHours(0, 0, 0, 0));
    const endOfDay = new Date(now.setHours(23, 59, 59, 999));

    // Run all queries in parallel for better performance
    const [
      // Core counts
      totalStudents,
      totalTeachers,
      totalStaff,
      activeTeachers,
      
      // Financial data
      monthlyIncome,
      monthlyExpenses,
      recentPayments,
      pendingFees,
      
      // Library data
      totalBooks,
      borrowedBooks,
      overdueBooks,
      recentBookActivities,
      
      // Student related
      newRegistrations,
      todayAttendance,
      
      // Financial trends
      incomeTrend,
      expenseTrend,
      
      // Department stats
      departmentStats,
      
      // Notices
      activeNotices
    ] = await Promise.all([
      // 1. Total students
      Student.countDocuments(),
      
      // 2. Total teachers
      Teacher.countDocuments(),
      
      // 3. Total staff (if you have staff model, otherwise teachers + admin)
      Promise.resolve(0), // Replace with actual staff count if you have Staff model
      
      // 4. Active teachers
      Teacher.countDocuments({ isActive: true }),
      
      // 5. Monthly income (payments this month)
      Payment.aggregate([
        {
          $match: {
            date: { $gte: startOfMonth, $lte: endOfMonth }
          }
        },
        {
          $group: {
            _id: null,
            total: { $sum: '$amount' }
          }
        }
      ]),
      
      // 6. Monthly expenses
      Expense.aggregate([
        {
          $match: {
            expenseDate: { $gte: startOfMonth, $lte: endOfMonth }
          }
        },
        {
          $group: {
            _id: null,
            total: { $sum: '$amount' }
          }
        }
      ]),
      
      // 7. Recent payments (last 5)
      Payment.find()
        .sort({ date: -1 })
        .limit(5)
        .select('studentName amount date paymentMethod'),
      
      // 8. Pending fees (students with unpaid fees)
      Promise.resolve(0), // You can implement this based on your fee structure
      
      // 9. Total books
      Book.countDocuments(),
      
      // 10. Borrowed books
      BookBorrow.countDocuments({ 
        status: { $in: ['Borrowed', 'Overdue'] } 
      }),
      
      // 11. Overdue books
      BookBorrow.countDocuments({ status: 'Overdue' }),
      
      // 12. Recent book activities
      BookBorrow.find()
        .sort({ createdAt: -1 })
        .limit(5)
        .select('bookTitle borrowerName status dueDate'),
      
      // 13. New registrations today
      Student.countDocuments({
        createdAt: { $gte: startOfDay, $lte: endOfDay }
      }),
      
      // 14. Today's attendance
      Attendance.countDocuments({
        date: { $gte: startOfDay, $lte: endOfDay },
        status: 'Present'
      }),
      
      // 15. Income trend (last 6 months)
      Payment.aggregate([
        {
          $match: {
            date: { 
              $gte: new Date(now.getFullYear(), now.getMonth() - 5, 1),
              $lte: endOfMonth 
            }
          }
        },
        {
          $group: {
            _id: { 
              month: { $month: '$date' },
              year: { $year: '$date' }
            },
            total: { $sum: '$amount' }
          }
        },
        { $sort: { '_id.year': 1, '_id.month': 1 } },
        { $limit: 6 }
      ]),
      
      // 16. Expense trend (last 6 months)
      Expense.aggregate([
        {
          $match: {
            expenseDate: { 
              $gte: new Date(now.getFullYear(), now.getMonth() - 5, 1),
              $lte: endOfMonth 
            }
          }
        },
        {
          $group: {
            _id: { 
              month: { $month: '$expenseDate' },
              year: { $year: '$expenseDate' }
            },
            total: { $sum: '$amount' }
          }
        },
        { $sort: { '_id.year': 1, '_id.month': 1 } },
        { $limit: 6 }
      ]),
      
      // 17. Department statistics
      Teacher.aggregate([
        {
          $group: {
            _id: '$department',
            count: { $sum: 1 }
          }
        },
        { $sort: { count: -1 } }
      ]),
      
      // 18. Active notices
      Notice.find({ isActive: true })
        .sort({ createdAt: -1 })
        .limit(5)
        .select('title createdAt')
    ]);

    // Format monthly trend data
    const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
    
    // Create a map for income by month
    const incomeByMonth = {};
    incomeTrend.forEach(item => {
      const monthName = months[item._id.month - 1];
      incomeByMonth[monthName] = item.total;
    });
    
    // Create a map for expense by month
    const expenseByMonth = {};
    expenseTrend.forEach(item => {
      const monthName = months[item._id.month - 1];
      expenseByMonth[monthName] = item.total;
    });

    // Generate last 6 months for chart
    const last6Months = [];
    for (let i = 5; i >= 0; i--) {
      const d = new Date();
      d.setMonth(d.getMonth() - i);
      const monthName = months[d.getMonth()];
      last6Months.push({
        month: monthName,
        income: incomeByMonth[monthName] || 0,
        expense: expenseByMonth[monthName] || 0
      });
    }

    // Format library activities for display
    const formattedBookActivities = recentBookActivities.map(book => ({
      title: book.bookTitle,
      status: book.status === 'Overdue' ? 'Overdue' : book.status === 'Borrowed' ? 'Issued' : 'Available',
      user: book.borrowerName,
      color: book.status === 'Overdue' ? 'text-rose-600 bg-rose-50' : 
             book.status === 'Borrowed' ? 'text-amber-600 bg-amber-50' : 
             'text-emerald-600 bg-emerald-50'
    }));

    // Format department percentages
    const totalTeachersCount = totalTeachers || 1; // Avoid division by zero
    const formattedDepartmentStats = departmentStats.map(dept => ({
      name: dept._id || 'Other',
      percentage: Math.round((dept.count / totalTeachersCount) * 100)
    }));

    // Add placeholder for missing departments if needed
    const deptNames = ['Academic', 'Administration', 'Maintenance'];
    const finalDepartmentStats = deptNames.map(name => {
      const existing = formattedDepartmentStats.find(d => d.name === name);
      return {
        name,
        percentage: existing ? existing.percentage : Math.floor(Math.random() * 30) + 40 // Random placeholder
      };
    });

    // Compile the final dashboard data
    const dashboardData = {
      // Core KPIs
      coreStats: {
        students: {
          label: 'Students',
          value: totalStudents.toLocaleString(),
          icon: 'RiUser3Line',
          trend: totalStudents > 0 ? '+12%' : '0%',
          trendUp: true
        },
        teachers: {
          label: 'Teachers',
          value: totalTeachers.toString(),
          icon: 'RiUser2Line',
          trend: `${activeTeachers}/${totalTeachers} Active`,
          trendUp: activeTeachers / totalTeachers > 0.8
        },
        staff: {
          label: 'Staff',
          value: '42', // Replace with actual staff count
          icon: 'RiTeamLine',
          trend: '3 New',
          trendUp: true
        },
        library: {
          label: 'Library',
          value: totalBooks.toLocaleString(),
          icon: 'RiBookOpenLine',
          trend: `${borrowedBooks} Borrowed`,
          trendUp: borrowedBooks < totalBooks * 0.3
        },
        payments: {
          label: 'Payments',
          value: `$${((monthlyIncome[0]?.total || 0) / 1000).toFixed(1)}k`,
          icon: 'RiWallet3Line',
          trend: `${((monthlyIncome[0]?.total || 0) - (monthlyExpenses[0]?.total || 0)) > 0 ? '+' : ''}$${Math.abs((monthlyIncome[0]?.total || 0) - (monthlyExpenses[0]?.total || 0)).toLocaleString()}`,
          trendUp: (monthlyIncome[0]?.total || 0) > (monthlyExpenses[0]?.total || 0)
        }
      },

      // Financial trend data for chart
      financialTrend: last6Months,

      // Recent payments
      recentPayments: recentPayments.map(p => ({
        student: p.studentName,
        amount: p.amount,
        date: p.date,
        method: p.paymentMethod
      })),

      // Library circulation
      libraryCirculation: formattedBookActivities,

      // Department staffing percentages
      departmentStaffing: finalDepartmentStats,

      // New registrations
      newRegistrations: {
        count: newRegistrations,
        pending: 14, // You can calculate this from your application model
        message: `You have ${14} student applications pending review for the Spring semester.`
      },

      // Quick notice
      quickNotice: {
        message: activeNotices[0]?.title || 'All monthly financial reports have been reconciled and are ready for download.',
        type: 'info'
      },

      // Payment channels summary
      paymentChannels: [
        { name: 'Tuition Fees', count: await Payment.countDocuments({}) || 0 },
        { name: 'Exam Fees', count: await ExamFee.countDocuments({}) || 0 },
        { name: 'Library Fines', count: await BookBorrow.countDocuments({ fine: { $gt: 0 }, finePaid: false }) || 0 },
        { name: 'Transport', count: 0 } // Add if you have transport model
      ],

      // Today's attendance
      todayAttendance: todayAttendance,

      // Summary stats
      summary: {
        totalIncome: monthlyIncome[0]?.total || 0,
        totalExpense: monthlyExpenses[0]?.total || 0,
        profit: (monthlyIncome[0]?.total || 0) - (monthlyExpenses[0]?.total || 0),
        pendingFees: pendingFees || 0
      }
    };

    res.json({
      success: true,
      data: dashboardData
    });

  } catch (error) {
    console.error('Dashboard data error:', error);
    res.status(500).json({
      success: false,
      message: 'Error fetching dashboard data',
      error: error.message
    });
  }
});

// Optional: GET simplified dashboard stats (lighter version)
Adminrouter.get('/dashboard-stats', async (req, res) => {
  try {
    const [
      totalStudents,
      totalTeachers,
      totalPayments,
      totalBooks
    ] = await Promise.all([
      Student.countDocuments(),
      Teacher.countDocuments(),
      Payment.countDocuments(),
      Book.countDocuments()
    ]);

    res.json({
      success: true,
      data: {
        totalStudents,
        totalTeachers,
        totalPayments,
        totalBooks
      }
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: 'Error fetching dashboard stats',
      error: error.message
    });
  }
});
// GET all students
Adminrouter.get('/students', async (req, res) => {
  try {
    const { page = 1, limit = 100, search = '', class: studentClass, gender } = req.query;

    const query = {};

    // Filter by class if provided
    if (studentClass && studentClass !== 'All' && studentClass !== '') {
      query.class = studentClass.trim();
    }

    // Filter by gender if provided
    if (gender && gender !== 'All' && gender !== '') {
      query.gender = { $regex: `^${gender.trim()}$`, $options: 'i' };
    }

    // Search filter
    if (search) {
      query.$or = [
        { firstName: { $regex: search, $options: 'i' } },
        { lastName:  { $regex: search, $options: 'i' } },
        { studentId: { $regex: search, $options: 'i' } },
        { admissionId: { $regex: search, $options: 'i' } },
      ];
    }

    const students = await Student.find(query)
      .sort({ roll: 1 })           // sort by roll number for attendance pages
      .limit(Number(limit))
      .skip((Number(page) - 1) * Number(limit));

    const total = await Student.countDocuments(query);

    res.json({
      students,
      totalPages: Math.ceil(total / Number(limit)),
      currentPage: Number(page),
      total,
    });
  } catch (error) {
    res.status(500).json({ message: 'Error fetching students', error: error.message });
  }
});

// GET student by ID
Adminrouter.get('/students-card/:id', async (req, res) => {
  try {
    const student = await Student.findOne({studentId:req.params.id});
    if (!student) {
      return res.json({ message: 'Student not found' });
    }
    res.json(student);
  } catch (error) {
    res.status(500).json({ message: 'Error fetching student', error: error.message });
  }
});
Adminrouter.get('/students/:id', async (req, res) => {
  try {
    const student = await Student.findOne({_id:req.params.id});
    if (!student) {
      return res.json({ message: 'Student not found' });
    }
    res.json(student);
  } catch (error) {
    res.status(500).json({ message: 'Error fetching student', error: error.message });
  }
});
Adminrouter.post('/students', upload.single('photo'), async (req, res) => {
  try {
    const {
      firstName,
      gender,
      dob,
      roll,
      rollNo,
      bloodGroup,
      religion,
      email,
      class: studentClass,
      section,
      phone,
      studentId,
      password,
      schoolName,
      monthlyFee,
      admissionDate,
      fatherName,
      motherName,
      guardianName,
      guardianRelation,
      guardianProfession,
      guardianPhone,
      message
    } = req.body;
    
    console.log(req.body)

    // Auto-generate admissionId if not provided
    let admissionId = req.body.admissionId;
    if (!admissionId) {
      // Generate admission ID format: ADM-YYYY-XXXX (e.g., ADM-2024-0001)
      const year = new Date().getFullYear();
      const lastStudent = await Student.findOne({ 
        admissionId: { $regex: `ADM-${year}-` } 
      }).sort({ admissionId: -1 });
      
      let lastNumber = 0;
      if (lastStudent && lastStudent.admissionId) {
        const parts = lastStudent.admissionId.split('-');
        lastNumber = parseInt(parts[2]) || 0;
      }
      
      const newNumber = (lastNumber + 1).toString().padStart(4, '0');
      admissionId = `ADM-${year}-${newNumber}`;
    }

    // Auto-generate admissionNo if not provided
    let admissionNo = req.body.admissionNo;
    if (!admissionNo) {
      // Generate admission number format: ADMNO-YYYYMMDD-XXXX
      const date = new Date();
      const year = date.getFullYear();
      const month = (date.getMonth() + 1).toString().padStart(2, '0');
      const day = date.getDate().toString().padStart(2, '0');
      const dateStr = `${year}${month}${day}`;
      
      // Find the last admission number for today
      const lastStudent = await Student.findOne({ 
        admissionNo: { $regex: `ADMNO-${dateStr}-` } 
      }).sort({ admissionNo: -1 });
      
      let lastSequence = 0;
      if (lastStudent && lastStudent.admissionNo) {
        const parts = lastStudent.admissionNo.split('-');
        lastSequence = parseInt(parts[2]) || 0;
      }
      
      const newSequence = (lastSequence + 1).toString().padStart(3, '0');
      admissionNo = `ADMNO-${dateStr}-${newSequence}`;
    }

    // Alternative simpler format for admissionNo (just sequential)
    /*
    if (!admissionNo) {
      const count = await Student.countDocuments();
      admissionNo = `ADM${(count + 1).toString().padStart(6, '0')}`;
    }
    */

    // Check if student with same admission ID already exists
    if (admissionId) {
      const existingStudent = await Student.findOne({ admissionId });
      if (existingStudent) {
        return res.json({ success: false, message: 'Student with this admission ID already exists' });
      }
    }

    if (studentId) {
      const existingStudent = await Student.findOne({ studentId });
      if (existingStudent) {
        return res.json({ success: false, message: 'Student with this student ID already exists' });
      }
    }

    // Check if admissionNo is unique
    if (admissionNo) {
      const existingStudent = await Student.findOne({ admissionNo });
      if (existingStudent) {
        return res.json({ success: false, message: 'Student with this admission number already exists' });
      }
    }

    const studentData = {
      firstName,
      gender,
      dob,
      roll,
      rollNo,
      admissionNo, // Auto-generated or provided
      bloodGroup,
      religion,
      email,
      class: studentClass,
      section,
      admissionId, // Auto-generated or provided
      phone,
      studentId,
      password,
      schoolName,
      monthlyFee: monthlyFee ? parseInt(monthlyFee) : undefined,
      admissionDate: admissionDate ? new Date(admissionDate) : new Date(), // Default to current date if not provided
      fatherName,
      motherName,
      guardianName,
      guardianRelation,
      guardianProfession,
      guardianPhone,
      message: message || 'অভিনন্দন! আপনার রেজিস্ট্রেশন সম্পন্ন হয়েছে।\n\nপ্রিয় [firstName] [lastName],\nআমরা আপনাকে অল কেয়ার একাডেমিতে স্বাগত জানাই। আপনার রেজিস্ট্রেশন বিবরণ নিম্নরূপ:\n- শ্রেণি: [class]\n- রোল নম্বর: [roll]\n- মাসিক ফি: [monthlyFee] টাকা\n- রেজিস্ট্রেশন আইডি: [admissionId]\n\nঅনুগ্রহ করে যেকোনো প্রশ্নের জন্য আমাদের সাথে যোগাযোগ করুন।\nধন্যবাদ,\nঅল কেয়ার একাডেমি'
    };

    // Add photo if uploaded
    if (req.file) {
      studentData.photo = req.file.filename;
    }

    const student = new Student(studentData);
    await student.save();

    res.status(201).json({
      success: true,
      message: 'Student created successfully',
      student: {
        ...student.toObject(),
      }
    });
  } catch (error) {
    console.log(error);
    res.status(400).json({ message: 'Error creating student', error: error.message });
  }
});
// PUT update student
Adminrouter.put('/students/:id', upload.single('photo'), async (req, res) => {
  try {
    const updates = { ...req.body };
    
    // Handle class field (since 'class' is a reserved word)
    if (updates.class) {
      updates.class = updates.class;
    }

    // Handle file upload
    if (req.file) {
      updates.photo = req.file.filename; // Fixed: using filename instead of path
      
      // Delete old photo if exists
      const existingStudent = await Student.findById(req.params.id);
      if (existingStudent && existingStudent.photo) {
        const photoPath = `uploads/${existingStudent.photo}`;
        if (fs.existsSync(photoPath)) {
          fs.unlinkSync(photoPath);
        }
      }
    }

    // Convert monthlyFee to number if provided
    if (updates.monthlyFee) {
      updates.monthlyFee = parseInt(updates.monthlyFee);
    }

    // Convert admissionDate to Date if provided
    if (updates.admissionDate) {
      updates.admissionDate = new Date(updates.admissionDate);
    }

    // Check for unique fields if they're being updated
    if (updates.admissionNo) {
      const existingStudent = await Student.findOne({ 
        admissionNo: updates.admissionNo,
        _id: { $ne: req.params.id }
      });
      if (existingStudent) {
        return res.status(400).json({ message: 'Admission number already exists' });
      }
    }

    const student = await Student.findByIdAndUpdate(
      req.params.id,
      updates,
      { new: true, runValidators: true }
    );

    if (!student) {
      return res.status(404).json({ message: 'Student not found' });
    }

    res.json({
      success: true,
      message: 'Student updated successfully',
      student
    });
  } catch (error) {
    res.status(400).json({ message: 'Error updating student', error: error.message });
  }
});

// DELETE student
Adminrouter.delete('/students/:id', async (req, res) => {
  try {
    const student = await Student.findById(req.params.id);
    
    if (!student) {
      return res.status(404).json({ message: 'Student not found' });
    }

    // Delete photo file if exists
    if (student.photo && fs.existsSync(student.photo)) {
      fs.unlinkSync(student.photo);
    }

    await Student.findByIdAndDelete(req.params.id);

    res.json({ message: 'Student deleted successfully' });
  } catch (error) {
    res.status(500).json({ message: 'Error deleting student', error: error.message });
  }
});

// GET students by class and section
Adminrouter.get('/students/class/:class', async (req, res) => {
  try {
    const { class: studentClass } = req.params;
    const { section } = req.query;

    const query = { class: studentClass };
    if (section) {
      query.section = section;
    }

    const students = await Student.find(query).sort({ roll: 1 });

    res.json(students);
  } catch (error) {
    res.status(500).json({ message: 'Error fetching students', error: error.message });
  }
});


// Configure multer for file uploads
const teacherstorage = multer.diskStorage({
  destination: function(req, file, cb) {
    cb(null, "./public/uploads/teachers")
  },
  filename:function(req,file,cb){
      cb(null,`${Date.now()}_${file.originalname}`)
  }
});

const uploadteacherimage = multer({
  storage: teacherstorage,
  fileFilter: fileFilter,
  limits: {
    fileSize: 5 * 1024 * 1024 // 5MB limit
  }
});

// Apply middleware to all routes
Adminrouter.use(authenticateAdmin);

// GET all teachers
Adminrouter.get('/teachers', async (req, res) => {
  try {
    const { page = 1, limit = 10, search = '', department = '' } = req.query;
    
    const query = {};
    if (search) {
      query.$or = [
        { firstName: { $regex: search, $options: 'i' } },
        { lastName: { $regex: search, $options: 'i' } },
        { teacherId: { $regex: search, $options: 'i' } },
        { email: { $regex: search, $options: 'i' } },
        { subject: { $regex: search, $options: 'i' } }
      ];
    }

    if (department) {
      query.department = department;
    }

    const teachers = await Teacher.find(query)
      .sort({ createdAt: -1 })
      .limit(limit * 1)
      .skip((page - 1) * limit)
      .select('-password'); // Exclude password from response

    const total = await Teacher.countDocuments(query);

    res.json({
      teachers,
      totalPages: Math.ceil(total / limit),
      currentPage: page,
      total
    });
  } catch (error) {
    res.status(500).json({ message: 'Error fetching teachers', error: error.message });
  }
});

// GET teacher by ID
Adminrouter.get('/teachers/:id', async (req, res) => {
  try {
    const teacher = await Teacher.findOne({ teacherId: req.params.id }).select('-password');
    if (!teacher) {
      return res.status(404).json({ message: 'Teacher not found' });
    }
    res.json(teacher);
  } catch (error) {
    res.status(500).json({ message: 'Error fetching teacher', error: error.message });
  }
});

// POST create new teacher
Adminrouter.post('/teachers', uploadteacherimage.single('photo'), async (req, res) => {
  try {
    const {
      firstName,
      lastName,
      gender,
      dob,
      email,
      phone,
      address,
      qualification,
      department,
      subject,
      joiningDate,
      salary,
      experience,
      teacherId,
      password,
      emergencyContact,
      emergencyPhone
    } = req.body;

    // Check if teacher with same email or teacher ID already exists
    if (email) {
      const existingTeacher = await Teacher.findOne({ email });
      if (existingTeacher) {
        return res.json({ success: false, message: 'Teacher with this email already exists' });
      }
    }

    if (teacherId) {
      const existingTeacher = await Teacher.findOne({ teacherId });
      if (existingTeacher) {
        return res.json({ success: false, message: 'Teacher with this teacher ID already exists' });
      }
    }

    const teacherData = {
      firstName,
      lastName,
      gender,
      dob: dob ? new Date(dob) : undefined,
      email,
      phone,
      address,
      qualification,
      department,
      subject,
      joiningDate: joiningDate ? new Date(joiningDate) : undefined,
      salary: salary ? parseFloat(salary) : undefined,
      experience,
      teacherId,
      password,
      emergencyContact,
      emergencyPhone
    };

    // Add photo if uploaded
    if (req.file) {
      teacherData.photo = req.file.filename;
    }

    const teacher = new Teacher(teacherData);
    await teacher.save();

    // Remove password from response
    const teacherResponse = teacher.toObject();
    delete teacherResponse.password;

    res.status(201).json({
      success: true,
      message: 'Teacher created successfully',
      teacher: teacherResponse
    });
  } catch (error) {
    console.log(error);
    res.status(400).json({ message: 'Error creating teacher', error: error.message });
  }
});

// PUT update teacher
Adminrouter.put('/teachers/:id', upload.single('photo'), async (req, res) => {
  try {
    const updates = { ...req.body };
    
    // Convert date fields if provided
    if (updates.dob) {
      updates.dob = new Date(updates.dob);
    }
    if (updates.joiningDate) {
      updates.joiningDate = new Date(updates.joiningDate);
    }

    // Convert salary to number if provided
    if (updates.salary) {
      updates.salary = parseFloat(updates.salary);
    }

    // Handle file upload
    if (req.file) {
      updates.photo = req.file.filename;
      
      // Delete old photo if exists
      const existingTeacher = await Teacher.findOne({ teacherId: req.params.id });
      if (existingTeacher && existingTeacher.photo) {
        const oldPhotoPath = path.join('./public/uploads/teachers', existingTeacher.photo);
        if (fs.existsSync(oldPhotoPath)) {
          fs.unlinkSync(oldPhotoPath);
        }
      }
    }

    // Don't update password through this route
    if (updates.password) {
      delete updates.password;
    }

    const teacher = await Teacher.findOneAndUpdate(
      { teacherId: req.params.id },
      updates,
      { new: true, runValidators: true }
    ).select('-password');

    if (!teacher) {
      return res.status(404).json({ message: 'Teacher not found' });
    }

    res.json({
      message: 'Teacher updated successfully',
      teacher
    });
  } catch (error) {
    res.status(400).json({ message: 'Error updating teacher', error: error.message });
  }
});

// DELETE teacher
Adminrouter.delete('/teachers/:id', async (req, res) => {
  try {
    const teacher = await Teacher.findOne({ teacherId: req.params.id });
    
    if (!teacher) {
      return res.status(404).json({ message: 'Teacher not found' });
    }

    // Delete photo file if exists
    if (teacher.photo) {
      const photoPath = path.join('./public/uploads/teachers', teacher.photo);
      if (fs.existsSync(photoPath)) {
        fs.unlinkSync(photoPath);
      }
    }

    await Teacher.findOneAndDelete({ teacherId: req.params.id });

    res.json({ message: 'Teacher deleted successfully' });
  } catch (error) {
    res.status(500).json({ message: 'Error deleting teacher', error: error.message });
  }
});

// GET teachers by department
Adminrouter.get('/teachers/department/:department', async (req, res) => {
  try {
    const { department } = req.params;
    const { subject } = req.query;

    const query = { department };
    if (subject) {
      query.subject = { $regex: subject, $options: 'i' };
    }

    const teachers = await Teacher.find(query)
      .sort({ firstName: 1 })
      .select('-password');

    res.json(teachers);
  } catch (error) {
    res.status(500).json({ message: 'Error fetching teachers', error: error.message });
  }
});

// PATCH update teacher status (activate/deactivate)
Adminrouter.patch('/teachers/:id/status', async (req, res) => {
  try {
    const { isActive } = req.body;

    const teacher = await Teacher.findOneAndUpdate(
      { teacherId: req.params.id },
      { isActive },
      { new: true, runValidators: true }
    ).select('-password');

    if (!teacher) {
      return res.status(404).json({ message: 'Teacher not found' });
    }

    res.json({
      message: `Teacher ${isActive ? 'activated' : 'deactivated'} successfully`,
      teacher
    });
  } catch (error) {
    res.status(400).json({ message: 'Error updating teacher status', error: error.message });
  }
});

// GET teacher statistics
Adminrouter.get('/teachers-stats', async (req, res) => {
  try {
    const totalTeachers = await Teacher.countDocuments();
    const activeTeachers = await Teacher.countDocuments({ isActive: true });
    const teachersByDepartment = await Teacher.aggregate([
      {
        $group: {
          _id: '$department',
          count: { $sum: 1 }
        }
      }
    ]);
    const teachersByExperience = await Teacher.aggregate([
      {
        $group: {
          _id: '$experience',
          count: { $sum: 1 }
        }
      }
    ]);

    res.json({
      totalTeachers,
      activeTeachers,
      inactiveTeachers: totalTeachers - activeTeachers,
      departments: teachersByDepartment,
      experience: teachersByExperience
    });
  } catch (error) {
    res.status(500).json({ message: 'Error fetching teacher statistics', error: error.message });
  }
});
// SCHEDULE ROUTES

// GET teacher schedule by teacher ID
Adminrouter.get('/teachers/:id/schedule', async (req, res) => {
  try {
    const teacher = await Teacher.findOne({ teacherId: req.params.id })
      .select('firstName lastName teacherId email phone subject department schedule photo');
  console.log(req.params);
    if (!teacher) {
      return res.json({ message: 'Teacher not found' });
    }

    // Get active schedule only
    const activeSchedule = teacher.schedule.filter(item => item.isActive);
 console.log(activeSchedule);
    res.json({
      teacher: {
        teacherId: teacher.teacherId,
        name: `${teacher.firstName} ${teacher.lastName}`,
        subject: teacher.subject,
        email: teacher.email,
        phone: teacher.phone,
        department: teacher.department,
        photo: teacher.photo,
        schedule: activeSchedule
      }
    });
  } catch (error) {
    res.status(500).json({ message: 'Error fetching teacher schedule', error: error.message });
  }
});

// GET all teachers with their schedules (for search functionality)
Adminrouter.get('/teachers-search', async (req, res) => {
  try {
    const { search = '' } = req.query;
    
    const query = {
      $or: [
        { firstName: { $regex: search, $options: 'i' } },
        { lastName: { $regex: search, $options: 'i' } },
        { teacherId: { $regex: search, $options: 'i' } },
        { email: { $regex: search, $options: 'i' } }
      ]
    };

    const teachers = await Teacher.find(query)
      .select('firstName lastName teacherId email subject photo schedule')
      .limit(10);

    const simplifiedTeachers = teachers.map(teacher => ({
      teacherId: teacher.teacherId,
      name: `${teacher.firstName} ${teacher.lastName}`,
      subject: teacher.subject,
      email: teacher.email,
      photo: teacher.photo,
      scheduleCount: teacher.schedule.filter(item => item.isActive).length
    }));

    res.json(simplifiedTeachers);
  } catch (error) {
    res.status(500).json({ message: 'Error searching teachers', error: error.message });
  }
});

// POST add schedule to teacher
Adminrouter.post('/teachers/:id/schedule', async (req, res) => {
  try {
    const { day, time, class: className, subject, room } = req.body;

    // Validate required fields
    if (!day || !time || !className || !subject || !room) {
      return res.status(400).json({ message: 'All schedule fields are required' });
    }

    // Validate time format
    const timeRegex = /^([0-1]?[0-9]|2[0-3]):[0-5][0-9] - ([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/;
    if (!timeRegex.test(time)) {
      return res.status(400).json({ message: 'Time must be in format "HH:MM - HH:MM"' });
    }

    const teacher = await Teacher.findOne({ teacherId: req.params.id });
    if (!teacher) {
      return res.status(404).json({ message: 'Teacher not found' });
    }

    // Check for schedule conflict
    const hasConflict = teacher.schedule.some(item => 
      item.isActive && 
      item.day === day && 
      item.time === time
    );

    if (hasConflict) {
      return res.status(400).json({ message: 'Schedule conflict: Teacher already has a class at this time' });
    }

    // Add new schedule item
    teacher.schedule.push({
      day,
      time,
      class: className,
      subject,
      room,
      isActive: true
    });

    await teacher.save();

    res.status(201).json({
      success: true,
      message: 'Schedule added successfully',
      schedule: teacher.schedule[teacher.schedule.length - 1]
    });
  } catch (error) {
    res.status(400).json({ message: 'Error adding schedule', error: error.message });
  }
});

// PUT update schedule item
Adminrouter.put('/teachers/:teacherId/schedule/:scheduleId', async (req, res) => {
  try {
    const { day, time, class: className, subject, room, isActive } = req.body;

    const teacher = await Teacher.findOne({ teacherId: req.params.teacherId });
    if (!teacher) {
      return res.status(404).json({ message: 'Teacher not found' });
    }

    const scheduleItem = teacher.schedule.id(req.params.scheduleId);
    if (!scheduleItem) {
      return res.status(404).json({ message: 'Schedule item not found' });
    }

    // Check for schedule conflict (excluding current item)
    if (day && time) {
      const hasConflict = teacher.schedule.some(item => 
        item._id.toString() !== req.params.scheduleId &&
        item.isActive && 
        item.day === (day || scheduleItem.day) && 
        item.time === (time || scheduleItem.time)
      );

      if (hasConflict) {
        return res.status(400).json({ message: 'Schedule conflict: Teacher already has a class at this time' });
      }
    }

    // Update fields
    if (day) scheduleItem.day = day;
    if (time) {
      // Validate time format
      const timeRegex = /^([0-1]?[0-9]|2[0-3]):[0-5][0-9] - ([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/;
      if (!timeRegex.test(time)) {
        return res.status(400).json({ message: 'Time must be in format "HH:MM - HH:MM"' });
      }
      scheduleItem.time = time;
    }
    if (className) scheduleItem.class = className;
    if (subject) scheduleItem.subject = subject;
    if (room) scheduleItem.room = room;
    if (typeof isActive === 'boolean') scheduleItem.isActive = isActive;

    await teacher.save();

    res.json({
      success: true,
      message: 'Schedule updated successfully',
      schedule: scheduleItem
    });
  } catch (error) {
    res.status(400).json({ message: 'Error updating schedule', error: error.message });
  }
});

// DELETE schedule item
Adminrouter.delete('/teachers/:teacherId/schedule/:scheduleId', async (req, res) => {
  try {
    const teacher = await Teacher.findOne({ teacherId: req.params.teacherId });
    if (!teacher) {
      return res.status(404).json({ message: 'Teacher not found' });
    }

    const scheduleItem = teacher.schedule.id(req.params.scheduleId);
    if (!scheduleItem) {
      return res.status(404).json({ message: 'Schedule item not found' });
    }

    // Remove the schedule item
    teacher.schedule.pull(req.params.scheduleId);
    await teacher.save();

    res.json({
      success: true,
      message: 'Schedule item deleted successfully'
    });
  } catch (error) {
    res.status(500).json({ message: 'Error deleting schedule item', error: error.message });
  }
});

// GET schedule statistics for a teacher
Adminrouter.get('/teachers/:id/schedule-stats', async (req, res) => {
  try {
    const teacher = await Teacher.findOne({ teacherId: req.params.id });
    console.log( req.params.id);
    if (!teacher) {
      return res.status(404).json({ message: 'Teacher not found' });
    }

    const activeSchedule = teacher.schedule.filter(item => item.isActive);
    
    const stats = {
      totalClasses: activeSchedule.length,
      workingDays: [...new Set(activeSchedule.map(item => item.day))].length,
      differentClasses: [...new Set(activeSchedule.map(item => item.class))].length,
      differentRooms: [...new Set(activeSchedule.map(item => item.room))].length,
      classesByDay: activeSchedule.reduce((acc, item) => {
        acc[item.day] = (acc[item.day] || 0) + 1;
        return acc;
      }, {})
    };

    res.json(stats);
  } catch (error) {
    res.status(500).json({ message: 'Error fetching schedule statistics', error: error.message });
  }
});

// -----------------------profile-----------------------------
Adminrouter.get("/admin-profile/:id",async(req,res)=>{
 try {
   const admin=await Admin.findById({_id:req.params.id});
   console.log(req.params.id);
   if(!admin){
           return res.send({success:false,message:"Admin not found!"})
   }
   res.send({success:true,data:admin})
 } catch (error) {
  console.log(error);
 }

})
// Update Profile Route
Adminrouter.put("/admin-profile/:id", async (req, res) => {
  try {
    const { username, email, currentPassword, newPassword } = req.body;
    const admin = await Admin.findById(req.params.id);
    
    if (!admin) {
      return res.status(404).send({ success: false, message: "Admin not found!" });
    }

    // Update basic info
    admin.username = username || admin.username;
    admin.email = email || admin.email;

    // Update password if provided
    if (currentPassword && newPassword) {
      const isMatch = await bcrypt.compare(currentPassword, admin.password);
      if (!isMatch) {
        return res.status(400).send({ success: false, message: "Current password is incorrect" });
      }
      admin.password = await bcrypt.hash(newPassword, 10);
    }

    await admin.save();

    res.send({
      success: true,
      message: "Profile updated successfully",
      data: {
        username: admin.username,
        email: admin.email,
        createdAt: admin.createdAt
      }
    });

  } catch (error) {
    console.log(error);
    res.status(500).send({ success: false, message: "Server error" });
  }
});

// Configure multer for banner uploads
const bannerStorage = multer.diskStorage({
  destination: function(req, file, cb) {
    cb(null, "./public/uploads/banners");
  },
  filename: function(req, file, cb) {
    cb(null, `banner_${Date.now()}_${file.originalname}`);
  }
});

const uploadBanner = multer({
  storage: bannerStorage,
  fileFilter: fileFilter,
  limits: {
    fileSize: 5 * 1024 * 1024 // 5MB limit
  }
});

// GET all banners
Adminrouter.get('/banners', async (req, res) => {
  try {
    const banners = await Banner.getAllBanners();
    res.json({
      success: true,
      banners
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching banners', 
      error: error.message 
    });
  }
});

// POST create new banner (only image)
Adminrouter.post('/banners', uploadBanner.single('image'), async (req, res) => {
  try {
    // Validate required image
    if (!req.file) {
      return res.status(400).json({ 
        success: false, 
        message: 'Image is required' 
      });
    }

    const bannerData = {
      image: req.file.filename
    };

    const banner = new Banner(bannerData);
    await banner.save();

    res.status(201).json({
      success: true,
      message: 'Banner uploaded successfully',
      banner
    });
  } catch (error) {
    console.log(error);
    res.status(400).json({ 
      success: false,
      message: 'Error uploading banner', 
      error: error.message 
    });
  }
});

// DELETE banner
Adminrouter.delete('/banners/:id', async (req, res) => {
  try {
    const banner = await Banner.findById(req.params.id);
    
    if (!banner) {
      return res.status(404).json({ 
        success: false,
        message: 'Banner not found' 
      });
    }

    // Delete image file if exists
    if (banner.image) {
      const imagePath = path.join('./public/uploads/banners', banner.image);
      if (fs.existsSync(imagePath)) {
        fs.unlinkSync(imagePath);
      }
    }

    await Banner.findByIdAndDelete(req.params.id);

    res.json({ 
      success: true,
      message: 'Banner deleted successfully' 
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error deleting banner', 
      error: error.message 
    });
  }
});

// Configure multer for gallery uploads
const galleryStorage = multer.diskStorage({
  destination: function(req, file, cb) {
    cb(null, "./public/uploads/gallery");
  },
  filename: function(req, file, cb) {
    cb(null, `gallery_${Date.now()}_${file.originalname}`);
  }
});

const uploadGallery = multer({
  storage: galleryStorage,
  fileFilter: fileFilter,
  limits: {
    fileSize: 5 * 1024 * 1024 // 5MB limit
  }
});

// GET all gallery items (for admin)
Adminrouter.get('/gallery', async (req, res) => {
  try {
    const { category = '', page = 1, limit = 10 } = req.query;
    
    const gallery = await Gallery.getAllGallery(category)
      .limit(limit * 1)
      .skip((page - 1) * limit);

    const total = await Gallery.countDocuments(category && category !== 'all' ? { category } : {});

    // Get distinct categories for filter
    const categories = await Gallery.distinct('category');

    res.json({
      success: true,
      gallery,
      categories,
      totalPages: Math.ceil(total / limit),
      currentPage: page,
      total
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching gallery', 
      error: error.message 
    });
  }
});

// GET gallery for frontend (active items only)
Adminrouter.get('/gallery/active', async (req, res) => {
  try {
    const { category = 'all' } = req.query;
    
    const gallery = await Gallery.getActiveGallery(category);

    // Get distinct categories for tabs
    const categories = await Gallery.aggregate([
      { $match: { isActive: true } },
      { $group: { 
        _id: '$category', 
        name: { $first: '$category' },
        nameBangla: { $first: '$categoryBangla' }
      }},
      { $sort: { name: 1 } }
    ]);

    // Add 'all' category
    const allCategories = [
      { _id: 'all', name: 'all', nameBangla: 'সকল' },
      ...categories
    ];

    res.json({
      success: true,
      gallery,
      categories: allCategories
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching gallery', 
      error: error.message 
    });
  }
});

// GET gallery item by ID
Adminrouter.get('/gallery/:id', async (req, res) => {
  try {
    const galleryItem = await Gallery.findById(req.params.id);
    
    if (!galleryItem) {
      return res.status(404).json({ 
        success: false,
        message: 'Gallery item not found' 
      });
    }

    res.json({
      success: true,
      gallery: galleryItem
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching gallery item', 
      error: error.message 
    });
  }
});

// POST create new gallery item
Adminrouter.post('/gallery', uploadGallery.single('image'), async (req, res) => {
  try {
    const {
      category,
      categoryBangla,
      order = 0
    } = req.body;

    // Validate required fields
    if (!category || !categoryBangla || !req.file) {
      return res.status(400).json({ 
        success: false, 
        message: 'Category, Category Bangla, and Image are required' 
      });
    }

    const galleryData = {
      category: category.trim(),
      categoryBangla: categoryBangla.trim(),
      order: parseInt(order) || 0,
      image: req.file.filename
    };

    const gallery = new Gallery(galleryData);
    await gallery.save();

    res.status(201).json({
      success: true,
      message: 'Gallery item added successfully',
      gallery
    });
  } catch (error) {
    console.log(error);
    res.status(400).json({ 
      success: false,
      message: 'Error adding gallery item', 
      error: error.message 
    });
  }
});

// PUT update gallery item
Adminrouter.put('/gallery/:id', uploadGallery.single('image'), async (req, res) => {
  try {
    const updates = { ...req.body };
    
    // Convert order to number if provided
    if (updates.order) {
      updates.order = parseInt(updates.order);
    }

    // Handle file upload
    if (req.file) {
      updates.image = req.file.filename;
      
      // Delete old image if exists
      const existingGallery = await Gallery.findById(req.params.id);
      if (existingGallery && existingGallery.image) {
        const oldImagePath = path.join('./public/uploads/gallery', existingGallery.image);
        if (fs.existsSync(oldImagePath)) {
          fs.unlinkSync(oldImagePath);
        }
      }
    }

    const gallery = await Gallery.findByIdAndUpdate(
      req.params.id,
      updates,
      { new: true, runValidators: true }
    );

    if (!gallery) {
      return res.status(404).json({ 
        success: false,
        message: 'Gallery item not found' 
      });
    }

    res.json({
      success: true,
      message: 'Gallery item updated successfully',
      gallery
    });
  } catch (error) {
    res.status(400).json({ 
      success: false,
      message: 'Error updating gallery item', 
      error: error.message 
    });
  }
});

// DELETE gallery item
Adminrouter.delete('/gallery/:id', async (req, res) => {
  try {
    const gallery = await Gallery.findById(req.params.id);
    
    if (!gallery) {
      return res.status(404).json({ 
        success: false,
        message: 'Gallery item not found' 
      });
    }

    // Delete image file if exists
    if (gallery.image) {
      const imagePath = path.join('./public/uploads/gallery', gallery.image);
      if (fs.existsSync(imagePath)) {
        fs.unlinkSync(imagePath);
      }
    }

    await Gallery.findByIdAndDelete(req.params.id);

    res.json({ 
      success: true,
      message: 'Gallery item deleted successfully' 
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error deleting gallery item', 
      error: error.message 
    });
  }
});

// PATCH update gallery item status
Adminrouter.patch('/gallery/:id/status', async (req, res) => {
  try {
    const { isActive } = req.body;

    const gallery = await Gallery.findByIdAndUpdate(
      req.params.id,
      { isActive },
      { new: true, runValidators: true }
    );

    if (!gallery) {
      return res.status(404).json({ 
        success: false,
        message: 'Gallery item not found' 
      });
    }

    res.json({
      success: true,
      message: `Gallery item ${isActive ? 'activated' : 'deactivated'} successfully`,
      gallery
    });
  } catch (error) {
    res.status(400).json({ 
      success: false,
      message: 'Error updating gallery item status', 
      error: error.message 
    });
  }
});

// GET gallery statistics
Adminrouter.get('/gallery-stats', async (req, res) => {
  try {
    const totalItems = await Gallery.countDocuments();
    const activeItems = await Gallery.countDocuments({ isActive: true });
    const itemsByCategory = await Gallery.aggregate([
      {
        $group: {
          _id: '$category',
          count: { $sum: 1 },
          banglaName: { $first: '$categoryBangla' }
        }
      },
      { $sort: { count: -1 } }
    ]);

    res.json({
      success: true,
      totalItems,
      activeItems,
      inactiveItems: totalItems - activeItems,
      categories: itemsByCategory
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching gallery statistics', 
      error: error.message 
    });
  }
});

// GET distinct categories
Adminrouter.get('/gallery-categories', async (req, res) => {
  try {
    const categories = await Gallery.aggregate([
      { $match: { isActive: true } },
      { $group: { 
        _id: '$category', 
        name: { $first: '$category' },
        nameBangla: { $first: '$categoryBangla' },
        count: { $sum: 1 }
      }},
      { $sort: { name: 1 } }
    ]);

    res.json({
      success: true,
      categories
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching categories', 
      error: error.message 
    });
  }
});

const Notice = require('../models/Notice');

// NOTICE ROUTES

// GET all notices
Adminrouter.get('/notices', async (req, res) => {
  try {
    const { page = 1, limit = 10, search = '', active = '' } = req.query;
    
    const query = {};
    if (search) {
      query.title = { $regex: search, $options: 'i' };
    }
    if (active === 'true' || active === 'false') {
      query.isActive = active === 'true';
    }

    const notices = await Notice.find(query)
      .sort({ createdAt: -1 })
      .limit(limit * 1)
      .skip((page - 1) * limit);

    const total = await Notice.countDocuments(query);

    res.json({
      success: true,
      notices,
      totalPages: Math.ceil(total / limit),
      currentPage: page,
      total
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching notices', 
      error: error.message 
    });
  }
});

// GET active notices for frontend (like your React component)
Adminrouter.get('/notices/active', async (req, res) => {
  try {
    const notices = await Notice.find({ isActive: true })
      .sort({ createdAt: -1 })
      .limit(10); // Limit for marquee

    res.json({
      success: true,
      notices
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching active notices', 
      error: error.message 
    });
  }
});

// GET notice by ID
Adminrouter.get('/notices/:id', async (req, res) => {
  try {
    const notice = await Notice.findById(req.params.id);
    
    if (!notice) {
      return res.status(404).json({ 
        success: false,
        message: 'Notice not found' 
      });
    }

    res.json({
      success: true,
      notice
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching notice', 
      error: error.message 
    });
  }
});

// POST create new notice
Adminrouter.post('/notices', async (req, res) => {
  try {
    const { title } = req.body;

    // Validate required fields
    if (!title) {
      return res.status(400).json({ 
        success: false, 
        message: 'Notice title is required' 
      });
    }

    const notice = new Notice({
      title: title.trim()
    });

    await notice.save();

    res.status(201).json({
      success: true,
      message: 'Notice created successfully',
      notice
    });
  } catch (error) {
    console.log(error);
    res.status(400).json({ 
      success: false,
      message: 'Error creating notice', 
      error: error.message 
    });
  }
});

// PUT update notice
Adminrouter.put('/notices/:id', async (req, res) => {
  try {
    const { title, isActive } = req.body;

    const updates = {};
    if (title) updates.title = title.trim();
    if (typeof isActive === 'boolean') updates.isActive = isActive;

    const notice = await Notice.findByIdAndUpdate(
      req.params.id,
      updates,
      { new: true, runValidators: true }
    );

    if (!notice) {
      return res.status(404).json({ 
        success: false,
        message: 'Notice not found' 
      });
    }

    res.json({
      success: true,
      message: 'Notice updated successfully',
      notice
    });
  } catch (error) {
    res.status(400).json({ 
      success: false,
      message: 'Error updating notice', 
      error: error.message 
    });
  }
});

// DELETE notice
Adminrouter.delete('/notices/:id', async (req, res) => {
  try {
    const notice = await Notice.findByIdAndDelete(req.params.id);
    
    if (!notice) {
      return res.status(404).json({ 
        success: false,
        message: 'Notice not found' 
      });
    }

    res.json({ 
      success: true,
      message: 'Notice deleted successfully' 
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error deleting notice', 
      error: error.message 
    });
  }
});

// PATCH update notice status
Adminrouter.patch('/notices/:id/status', async (req, res) => {
  try {
    const { isActive } = req.body;

    const notice = await Notice.findByIdAndUpdate(
      req.params.id,
      { isActive },
      { new: true, runValidators: true }
    );

    if (!notice) {
      return res.status(404).json({ 
        success: false,
        message: 'Notice not found' 
      });
    }

    res.json({
      success: true,
      message: `Notice ${isActive ? 'activated' : 'deactivated'} successfully`,
      notice
    });
  } catch (error) {
    res.status(400).json({ 
      success: false,
      message: 'Error updating notice status', 
      error: error.message 
    });
  }
});

// GET notice statistics
Adminrouter.get('/notices-stats', async (req, res) => {
  try {
    const totalNotices = await Notice.countDocuments();
    const activeNotices = await Notice.countDocuments({ isActive: true });

    res.json({
      success: true,
      totalNotices,
      activeNotices,
      inactiveNotices: totalNotices - activeNotices
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching notice statistics', 
      error: error.message 
    });
  }
});


const Payment = require('../models/Payment');

// PAYMENT ROUTES

// GET all payments with search and filters
Adminrouter.get('/payments', async (req, res) => {
  try {
    const { 
      page = 1, 
      limit = 10, 
      search = '', 
      month = '', 
      class: studentClass = '',
      startDate = '',
      endDate = '',
      paymentMethod = ''
    } = req.query;
    
    const query = {};
    
    // Search functionality
    if (search) {
      query.$or = [
        { studentName: { $regex: search, $options: 'i' } },
        { roll: { $regex: search, $options: 'i' } },
        { 'studentDetails.studentId': { $regex: search, $options: 'i' } },
        { 'studentDetails.admissionId': { $regex: search, $options: 'i' } },
        { transactionId: { $regex: search, $options: 'i' } }
      ];
    }

    // Filter by month
    if (month) {
      query.month = month;
    }

    // Filter by class
    if (studentClass) {
      query.class = studentClass;
    }

    // Filter by payment method
    if (paymentMethod) {
      query.paymentMethod = paymentMethod;
    }

    // Filter by date range
    if (startDate || endDate) {
      query.date = {};
      if (startDate) {
        query.date.$gte = new Date(startDate);
      }
      if (endDate) {
        query.date.$lte = new Date(endDate);
      }
    }

    const payments = await Payment.find(query)
      .populate('studentId', 'firstName lastName studentId admissionId phone monthlyFee')
      .sort({ date: -1, createdAt: -1 })
      .limit(limit * 1)
      .skip((page - 1) * limit);

    const total = await Payment.countDocuments(query);

    // Calculate total amount for current query
    const totalAmountResult = await Payment.aggregate([
      { $match: query },
      { $group: { _id: null, totalAmount: { $sum: '$amount' } } }
    ]);
    const totalAmount = totalAmountResult.length > 0 ? totalAmountResult[0].totalAmount : 0;

    res.json({
      success: true,
      payments,
      totalPages: Math.ceil(total / limit),
      currentPage: page,
      total,
      totalAmount
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching payments', 
      error: error.message 
    });
  }
});

// GET payment by ID
Adminrouter.get('/payments/:id', async (req, res) => {
  try {
    const payment = await Payment.findById(req.params.id)
      .populate('studentId', 'firstName lastName studentId admissionId phone monthlyFee class roll');

    if (!payment) {
      return res.status(404).json({ 
        success: false,
        message: 'Payment not found' 
      });
    }

    res.json({
      success: true,
      payment
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching payment', 
      error: error.message 
    });
  }
});

// POST create new payment
Adminrouter.post('/payments', async (req, res) => {
  try {
    const {
      studentName,
      roll,
      class: studentClass,
      amount,
      paymentMethod,
      date,
      month,
      message,
      studentId,
      studentDetails
    } = req.body;

    // Validate required fields
    if (!studentName || !roll || !studentClass || !amount || !paymentMethod || !date || !month || !message) {
      return res.status(400).json({ 
        success: false, 
        message: 'All required fields must be filled' 
      });
    }

    // Check if payment already exists for same student, month, and year
    const existingPayment = await Payment.findOne({
      $or: [
        { studentId },
        { roll, studentName }
      ],
      month,
      year: new Date(date).getFullYear()
    });

    if (existingPayment) {
      return res.status(400).json({
        success: false,
        message: `Payment for ${month} already exists for this student`
      });
    }

    const paymentData = {
      studentName: studentName.trim(),
      roll: roll.trim(),
      class: studentClass,
      amount: parseFloat(amount),
      paymentMethod,
      date: new Date(date),
      month,
      message: message.trim(),
      studentId: studentId || null,
      studentDetails: studentDetails || {}
    };

    const payment = new Payment(paymentData);
    await payment.save();

    // Populate the saved payment for response
    const savedPayment = await Payment.findById(payment._id)
      .populate('studentId', 'firstName lastName studentId admissionId phone monthlyFee');

    // Here you would typically integrate with SMS service
    // await sendSMSNotification(savedPayment);

    res.status(201).json({
      success: true,
      message: 'Payment submitted successfully',
      payment: savedPayment
    });
  } catch (error) {
    console.log(error);
    res.status(400).json({ 
      success: false,
      message: 'Error creating payment', 
      error: error.message 
    });
  }
});

// PUT update payment
Adminrouter.put('/payments/:id', async (req, res) => {
  try {
    const {
      studentName,
      roll,
      class: studentClass,
      amount,
      paymentMethod,
      date,
      month,
      message
    } = req.body;

    const updates = {};
    if (studentName) updates.studentName = studentName.trim();
    if (roll) updates.roll = roll.trim();
    if (studentClass) updates.class = studentClass;
    if (amount) updates.amount = parseFloat(amount);
    if (paymentMethod) updates.paymentMethod = paymentMethod;
    if (date) updates.date = new Date(date);
    if (month) updates.month = month;
    if (message) updates.message = message.trim();

    const payment = await Payment.findByIdAndUpdate(
      req.params.id,
      updates,
      { new: true, runValidators: true }
    ).populate('studentId', 'firstName lastName studentId admissionId phone monthlyFee');

    if (!payment) {
      return res.status(404).json({ 
        success: false,
        message: 'Payment not found' 
      });
    }

    res.json({
      success: true,
      message: 'Payment updated successfully',
      payment
    });
  } catch (error) {
    res.status(400).json({ 
      success: false,
      message: 'Error updating payment', 
      error: error.message 
    });
  }
});

// DELETE payment
Adminrouter.delete('/payments/:id', async (req, res) => {
  try {
    const payment = await Payment.findByIdAndDelete(req.params.id);
    
    if (!payment) {
      return res.status(404).json({ 
        success: false,
        message: 'Payment not found' 
      });
    }

    res.json({ 
      success: true,
      message: 'Payment deleted successfully' 
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error deleting payment', 
      error: error.message 
    });
  }
});

// GET payment statistics
Adminrouter.get('/payments-stats', async (req, res) => {
  try {
    const { month = '', year = new Date().getFullYear() } = req.query;

    const matchStage = { year: parseInt(year) };
    if (month) {
      matchStage.month = month;
    }

    const stats = await Payment.aggregate([
      {
        $addFields: {
          year: { $year: '$date' }
        }
      },
      {
        $match: matchStage
      },
      {
        $group: {
          _id: null,
          totalPayments: { $sum: 1 },
          totalAmount: { $sum: '$amount' },
          averageAmount: { $avg: '$amount' }
        }
      }
    ]);

    // Payments by method
    const paymentsByMethod = await Payment.aggregate([
      {
        $addFields: {
          year: { $year: '$date' }
        }
      },
      {
        $match: matchStage
      },
      {
        $group: {
          _id: '$paymentMethod',
          count: { $sum: 1 },
          totalAmount: { $sum: '$amount' }
        }
      }
    ]);

    // Payments by class
    const paymentsByClass = await Payment.aggregate([
      {
        $addFields: {
          year: { $year: '$date' }
        }
      },
      {
        $match: matchStage
      },
      {
        $group: {
          _id: '$class',
          count: { $sum: 1 },
          totalAmount: { $sum: '$amount' }
        }
      }
    ]);

    // Monthly trend for current year
    const monthlyTrend = await Payment.aggregate([
      {
        $addFields: {
          year: { $year: '$date' },
          month: { $month: '$date' }
        }
      },
      {
        $match: { year: parseInt(year) }
      },
      {
        $group: {
          _id: '$month',
          totalAmount: { $sum: '$amount' },
          paymentCount: { $sum: 1 }
        }
      },
      {
        $sort: { _id: 1 }
      }
    ]);

    const defaultStats = {
      totalPayments: 0,
      totalAmount: 0,
      averageAmount: 0
    };

    res.json({
      success: true,
      stats: stats.length > 0 ? stats[0] : defaultStats,
      paymentsByMethod,
      paymentsByClass,
      monthlyTrend
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching payment statistics', 
      error: error.message 
    });
  }
});

// GET payments by student ID
Adminrouter.get('/payments/student/:studentId', async (req, res) => {
  try {
    const { studentId } = req.params;
    const { page = 1, limit = 10 } = req.query;

    const payments = await Payment.find({
      $or: [
        { studentId },
        { 'studentDetails.studentId': studentId },
        { roll: studentId }
      ]
    })
    .sort({ date: -1 })
    .limit(limit * 1)
    .skip((page - 1) * limit)
    .populate('studentId', 'firstName lastName studentId admissionId phone monthlyFee');

    const total = await Payment.countDocuments({
      $or: [
        { studentId },
        { 'studentDetails.studentId': studentId },
        { roll: studentId }
      ]
    });

    // Calculate total paid by student
    const totalPaid = await Payment.aggregate([
      {
        $match: {
          $or: [
            { studentId: mongoose.Types.ObjectId(studentId) },
            { 'studentDetails.studentId': studentId },
            { roll: studentId }
          ]
        }
      },
      {
        $group: {
          _id: null,
          total: { $sum: '$amount' }
        }
      }
    ]);

    res.json({
      success: true,
      payments,
      totalPages: Math.ceil(total / limit),
      currentPage: page,
      total,
      totalPaid: totalPaid.length > 0 ? totalPaid[0].total : 0
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching student payments', 
      error: error.message 
    });
  }
});

// PATCH resend SMS for payment
Adminrouter.patch('/payments/:id/resend-sms', async (req, res) => {
  try {
    const payment = await Payment.findById(req.params.id)
      .populate('studentId', 'firstName lastName phone');

    if (!payment) {
      return res.status(404).json({ 
        success: false,
        message: 'Payment not found' 
      });
    }

    // Here you would integrate with your SMS service
    // const smsResult = await sendSMSNotification(payment);
    
    // For now, we'll just update the SMS status
    payment.smsSent = true;
    payment.smsSentAt = new Date();
    await payment.save();

    res.json({
      success: true,
      message: 'SMS sent successfully',
      payment
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error sending SMS', 
      error: error.message 
    });
  }
});

const TeacherPayment = require('../models/TeacherPayment');

// TEACHER PAYMENT ROUTES

// GET all teacher payments with search and filters
Adminrouter.get('/teacher-payments', async (req, res) => {
  try {
    const { 
      page = 1, 
      limit = 10, 
      search = '', 
      month = '', 
      department = '',
      status = '',
      paymentMethod = '',
      startDate = '',
      endDate = ''
    } = req.query;

    const filters = {
      ...(search && { search }),
      ...(month && { month }),
      ...(department && { department }),
      ...(status && { status }),
      ...(paymentMethod && { paymentMethod }),
      ...(startDate && { startDate }),
      ...(endDate && { endDate })
    };

    const result = await TeacherPayment.getPayments(filters, page, limit);

    // Calculate total amount for current query
    const totalAmountResult = await TeacherPayment.aggregate([
      { $match: result.payments.length > 0 ? { _id: { $in: result.payments.map(p => p._id) } } : {} },
      { $group: { _id: null, totalAmount: { $sum: '$amount' } } }
    ]);

    const totalAmount = totalAmountResult.length > 0 ? totalAmountResult[0].totalAmount : 0;

    res.json({
      success: true,
      payments: result.payments,
      totalPages: result.totalPages,
      currentPage: result.currentPage,
      total: result.total,
      totalAmount
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching teacher payments', 
      error: error.message 
    });
  }
});

// GET teacher payment by ID
Adminrouter.get('/teacher-payments/:id', async (req, res) => {
  try {
    const payment = await TeacherPayment.findById(req.params.id)
      .populate('teacherId', 'firstName lastName teacherId email phone department subject salary photo');

    if (!payment) {
      return res.status(404).json({ 
        success: false,
        message: 'Teacher payment not found' 
      });
    }

    res.json({
      success: true,
      payment
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching teacher payment', 
      error: error.message 
    });
  }
});

// POST create new teacher payment
Adminrouter.post('/teacher-payments', async (req, res) => {
  try {
    const {
      teacherName,
      employeeId,
      department,
      amount,
      paymentMethod,
      date,
      month,
      message,
      teacherId,
      teacherDetails
    } = req.body;

    // Validate required fields
    if (!teacherName || !employeeId || !department || !amount || !paymentMethod || !date || !month || !message) {
      return res.status(400).json({ 
        success: false, 
        message: 'All required fields must be filled' 
      });
    }

    // Validate amount
    if (parseFloat(amount) <= 0) {
      return res.status(400).json({
        success: false,
        message: 'Amount must be greater than 0'
      });
    }

    // Check if payment already exists for same teacher, month, and year
    const paymentDate = new Date(date);
    const year = paymentDate.getFullYear();

    const existingPayment = await TeacherPayment.findOne({
      $or: [
        { teacherId },
        { employeeId }
      ],
      month,
      year
    });

    if (existingPayment) {
      return res.status(400).json({
        success: false,
        message: `Salary payment for ${month} ${year} already exists for this teacher`
      });
    }

    const paymentData = {
      teacherName: teacherName.trim(),
      employeeId: employeeId.trim(),
      department: department.trim(),
      amount: parseFloat(amount),
      paymentMethod,
      date: paymentDate,
      month,
      message: message.trim(),
      teacherId: teacherId || null,
      teacherDetails: teacherDetails || {}
    };

    const payment = new TeacherPayment(paymentData);
    await payment.save();

    // Populate the saved payment for response
    const savedPayment = await TeacherPayment.findById(payment._id)
      .populate('teacherId', 'firstName lastName teacherId email phone department subject salary photo');

    // Here you would typically integrate with SMS service
    // await sendTeacherSMSNotification(savedPayment);

    res.status(201).json({
      success: true,
      message: 'Salary payment submitted successfully',
      payment: savedPayment
    });
  } catch (error) {
    console.log(error);
    if (error.code === 11000) {
      return res.status(400).json({
        success: false,
        message: 'Transaction ID already exists'
      });
    }
    res.status(400).json({ 
      success: false,
      message: 'Error creating teacher payment', 
      error: error.message 
    });
  }
});

// PUT update teacher payment
Adminrouter.put('/teacher-payments/:id', async (req, res) => {
  try {
    const {
      teacherName,
      employeeId,
      department,
      amount,
      paymentMethod,
      date,
      month,
      message,
      status
    } = req.body;

    const updates = {};
    if (teacherName) updates.teacherName = teacherName.trim();
    if (employeeId) updates.employeeId = employeeId.trim();
    if (department) updates.department = department.trim();
    if (amount) updates.amount = parseFloat(amount);
    if (paymentMethod) updates.paymentMethod = paymentMethod;
    if (date) updates.date = new Date(date);
    if (month) updates.month = month;
    if (message) updates.message = message.trim();
    if (status) updates.status = status;

    const payment = await TeacherPayment.findByIdAndUpdate(
      req.params.id,
      updates,
      { new: true, runValidators: true }
    ).populate('teacherId', 'firstName lastName teacherId email phone department subject salary photo');

    if (!payment) {
      return res.status(404).json({ 
        success: false,
        message: 'Teacher payment not found' 
      });
    }

    res.json({
      success: true,
      message: 'Teacher payment updated successfully',
      payment
    });
  } catch (error) {
    res.status(400).json({ 
      success: false,
      message: 'Error updating teacher payment', 
      error: error.message 
    });
  }
});

// DELETE teacher payment
Adminrouter.delete('/teacher-payments/:id', async (req, res) => {
  try {
    const payment = await TeacherPayment.findByIdAndDelete(req.params.id);
    
    if (!payment) {
      return res.status(404).json({ 
        success: false,
        message: 'Teacher payment not found' 
      });
    }

    res.json({ 
      success: true,
      message: 'Teacher payment deleted successfully' 
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error deleting teacher payment', 
      error: error.message 
    });
  }
});

// GET teacher payments by teacher ID
Adminrouter.get('/teacher-payments/teacher/:teacherId', async (req, res) => {
  try {
    const { teacherId } = req.params;
    const { page = 1, limit = 10, year = new Date().getFullYear() } = req.query;

    const payments = await TeacherPayment.find({
      $or: [
        { teacherId },
        { employeeId: teacherId }
      ],
      year: parseInt(year)
    })
    .populate('teacherId', 'firstName lastName teacherId email phone department subject salary photo')
    .sort({ date: -1 })
    .limit(limit * 1)
    .skip((page - 1) * limit);

    const total = await TeacherPayment.countDocuments({
      $or: [
        { teacherId },
        { employeeId: teacherId }
      ],
      year: parseInt(year)
    });

    // Calculate total paid to teacher
    const totalPaid = await TeacherPayment.aggregate([
      {
        $match: {
          $or: [
            { teacherId: mongoose.Types.ObjectId(teacherId) },
            { employeeId: teacherId }
          ],
          year: parseInt(year)
        }
      },
      {
        $group: {
          _id: null,
          total: { $sum: '$amount' }
        }
      }
    ]);

    // Get payment statistics by month
    const monthlyStats = await TeacherPayment.aggregate([
      {
        $match: {
          $or: [
            { teacherId: mongoose.Types.ObjectId(teacherId) },
            { employeeId: teacherId }
          ],
          year: parseInt(year)
        }
      },
      {
        $group: {
          _id: '$month',
          totalAmount: { $sum: '$amount' },
          paymentCount: { $sum: 1 }
        }
      },
      {
        $sort: {
          _id: 1
        }
      }
    ]);

    res.json({
      success: true,
      payments,
      totalPages: Math.ceil(total / limit),
      currentPage: page,
      total,
      totalPaid: totalPaid.length > 0 ? totalPaid[0].total : 0,
      monthlyStats
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching teacher payments', 
      error: error.message 
    });
  }
});

// PATCH resend SMS for teacher payment
Adminrouter.patch('/teacher-payments/:id/resend-sms', async (req, res) => {
  try {
    const payment = await TeacherPayment.findById(req.params.id)
      .populate('teacherId', 'firstName lastName phone');

    if (!payment) {
      return res.status(404).json({ 
        success: false,
        message: 'Teacher payment not found' 
      });
    }

    // Here you would integrate with your SMS service
    // const smsResult = await sendTeacherSMSNotification(payment);
    
    // For now, we'll just update the SMS status
    payment.smsSent = true;
    payment.smsSentAt = new Date();
    await payment.save();

    res.json({
      success: true,
      message: 'SMS sent successfully to teacher',
      payment
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error sending SMS', 
      error: error.message 
    });
  }
});

// GET teacher payment statistics
Adminrouter.get('/teacher-payments-stats', async (req, res) => {
  try {
    const { year = new Date().getFullYear() } = req.query;

    const matchStage = { year: parseInt(year) };

    const stats = await TeacherPayment.aggregate([
      {
        $match: matchStage
      },
      {
        $group: {
          _id: null,
          totalPayments: { $sum: 1 },
          totalAmount: { $sum: '$amount' },
          averageAmount: { $avg: '$amount' }
        }
      }
    ]);

    // Payments by department
    const paymentsByDepartment = await TeacherPayment.aggregate([
      {
        $match: matchStage
      },
      {
        $group: {
          _id: '$department',
          count: { $sum: 1 },
          totalAmount: { $sum: '$amount' }
        }
      },
      {
        $sort: { totalAmount: -1 }
      }
    ]);

    // Payments by method
    const paymentsByMethod = await TeacherPayment.aggregate([
      {
        $match: matchStage
      },
      {
        $group: {
          _id: '$paymentMethod',
          count: { $sum: 1 },
          totalAmount: { $sum: '$amount' }
        }
      }
    ]);

    // Monthly trend
    const monthlyTrend = await TeacherPayment.aggregate([
      {
        $match: { year: parseInt(year) }
      },
      {
        $group: {
          _id: '$month',
          totalAmount: { $sum: '$amount' },
          paymentCount: { $sum: 1 }
        }
      },
      {
        $sort: { 
          _id: 1 
        }
      }
    ]);

    // Top paid teachers
    const topPaidTeachers = await TeacherPayment.aggregate([
      {
        $match: matchStage
      },
      {
        $group: {
          _id: '$teacherId',
          teacherName: { $first: '$teacherName' },
          employeeId: { $first: '$employeeId' },
          department: { $first: '$department' },
          totalPaid: { $sum: '$amount' },
          paymentCount: { $sum: 1 }
        }
      },
      {
        $sort: { totalPaid: -1 }
      },
      {
        $limit: 10
      }
    ]);

    const defaultStats = {
      totalPayments: 0,
      totalAmount: 0,
      averageAmount: 0
    };

    res.json({
      success: true,
      stats: stats.length > 0 ? stats[0] : defaultStats,
      paymentsByDepartment,
      paymentsByMethod,
      monthlyTrend,
      topPaidTeachers
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching teacher payment statistics', 
      error: error.message 
    });
  }
});

// GET departments for filter
Adminrouter.get('/teacher-payments-departments', async (req, res) => {
  try {
    const departments = await TeacherPayment.aggregate([
      {
        $group: {
          _id: '$department',
          count: { $sum: 1 }
        }
      },
      {
        $sort: { _id: 1 }
      }
    ]);

    res.json({
      success: true,
      departments
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching departments', 
      error: error.message 
    });
  }
});
const Parent = require('../models/Parent');

// PARENT ROUTES

// GET all parents with search and pagination
Adminrouter.get('/parents', async (req, res) => {
  try {
    const { page = 1, limit = 10, search = '', isActive = '' } = req.query;
    
    const filters = {
      ...(search && { search }),
      ...(isActive && { isActive })
    };

    const parents = await Parent.getAllParents(filters, page, limit);
    const total = await Parent.countDocuments(parents._conditions || {});

    res.json({
      success: true,
      parents,
      totalPages: Math.ceil(total / limit),
      currentPage: page,
      total
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching parents', 
      error: error.message 
    });
  }
});

// GET active parents (for dropdowns etc)
Adminrouter.get('/parents/active', async (req, res) => {
  try {
    const parents = await Parent.getActiveParents();
    
    res.json({
      success: true,
      parents
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching active parents', 
      error: error.message 
    });
  }
});

// GET parent by ID
Adminrouter.get('/parents/:id', async (req, res) => {
  try {
    const parent = await Parent.findOne({ parentId: req.params.id });
    
    if (!parent) {
      return res.status(404).json({ 
        success: false,
        message: 'Parent not found' 
      });
    }

    res.json({
      success: true,
      parent
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching parent', 
      error: error.message 
    });
  }
});

// POST create new parent
// POST create new parent
Adminrouter.post('/parents', async (req, res) => {
  try {
    const {
      parentId,
      name,
      gender,
      occupation,
      address,
      phone,
      email,
      children
    } = req.body;

    // Validate required fields
    if (!parentId || !name || !gender || !occupation || !address || !phone) {
      return res.status(400).json({ 
        success: false, 
        message: 'All required fields must be filled' 
      });
    }

    // Check if parent with same ID or email already exists
    const existingParentById = await Parent.findOne({ parentId });
    if (existingParentById) {
      return res.status(400).json({
        success: false,
        message: 'Parent with this ID already exists'
      });
    }

    if (email) {
      const existingParentByEmail = await Parent.findOne({ email });
      if (existingParentByEmail) {
        return res.status(400).json({
          success: false,
          message: 'Parent with this email already exists'
        });
      }
    }

    const existingParentByPhone = await Parent.findOne({ phone });
    if (existingParentByPhone) {
      return res.status(400).json({
        success: false,
        message: 'Parent with this phone number already exists'
      });
    }

    // Parse children data
    let childrenArray = [];
    if (children) {
      if (typeof children === 'string') {
        try {
          // Try to parse if it's a JSON string
          childrenArray = JSON.parse(children);
        } catch {
          // If not JSON, treat as comma-separated names
          childrenArray = children.split(',').map(child => ({
            name: child.trim()
          }));
        }
      } else if (Array.isArray(children)) {
        childrenArray = children.map(child => ({
          name: child.name ? child.name.trim() : '',
          studentId: child.studentId ? child.studentId.trim() : '',
          className: child.className ? child.className.trim() : '',
          section: child.section ? child.section.trim() : ''
        }));
      }
    }

    const parentData = {
      parentId: parentId.trim(),
      name: name.trim(),
      gender,
      occupation: occupation.trim(),
      address: address.trim(),
      phone: phone.trim(),
      email: email ? email.trim().toLowerCase() : '',
      children: childrenArray
    };

    const parent = new Parent(parentData);
    await parent.save();

    res.status(201).json({
      success: true,
      message: 'Parent created successfully',
      parent
    });
  } catch (error) {
    console.log(error);
    if (error.code === 11000) {
      return res.status(400).json({
        success: false,
        message: 'Parent ID, email, or phone number already exists'
      });
    }
    res.status(400).json({ 
      success: false,
      message: 'Error creating parent', 
      error: error.message 
    });
  }
});

// PUT update parent
Adminrouter.put('/parents/:id', async (req, res) => {
  try {
    const {
      name,
      gender,
      occupation,
      address,
      phone,
      email,
      children,
      isActive
    } = req.body;

    const updates = {};
    if (name) updates.name = name.trim();
    if (gender) updates.gender = gender;
    if (occupation) updates.occupation = occupation.trim();
    if (address) updates.address = address.trim();
    if (phone) updates.phone = phone.trim();
    if (email) updates.email = email.trim().toLowerCase();
    if (typeof isActive === 'boolean') updates.isActive = isActive;

    // Parse children data if provided
    if (children) {
      let childrenArray = [];
      if (typeof children === 'string') {
        try {
          childrenArray = JSON.parse(children);
        } catch {
          childrenArray = children.split(',').map(child => ({
            name: child.trim()
          }));
        }
      } else if (Array.isArray(children)) {
        childrenArray = children.map(child => ({
          name: child.name ? child.name.trim() : '',
          studentId: child.studentId ? child.studentId.trim() : '',
          className: child.className ? child.className.trim() : '',
          section: child.section ? child.section.trim() : ''
        }));
      }
      updates.children = childrenArray;
    }

    // Check for duplicate email or phone (excluding current parent)
    if (email) {
      const existingParent = await Parent.findOne({ 
        email: email.trim().toLowerCase(),
        parentId: { $ne: req.params.id }
      });
      if (existingParent) {
        return res.status(400).json({
          success: false,
          message: 'Another parent with this email already exists'
        });
      }
    }

    if (phone) {
      const existingParent = await Parent.findOne({ 
        phone: phone.trim(),
        parentId: { $ne: req.params.id }
      });
      if (existingParent) {
        return res.status(400).json({
          success: false,
          message: 'Another parent with this phone number already exists'
        });
      }
    }

    const parent = await Parent.findOneAndUpdate(
      { parentId: req.params.id },
      updates,
      { new: true, runValidators: true }
    );

    if (!parent) {
      return res.status(404).json({ 
        success: false,
        message: 'Parent not found' 
      });
    }

    res.json({
      success: true,
      message: 'Parent updated successfully',
      parent
    });
  } catch (error) {
    res.status(400).json({ 
      success: false,
      message: 'Error updating parent', 
      error: error.message 
    });
  }
});

// GET parents by class
Adminrouter.get('/parents/by-class/:className', async (req, res) => {
  try {
    const { className } = req.params;
    const { section } = req.query;
    
    const parents = await Parent.getParentsByClass(className, section);
    
    res.json({
      success: true,
      count: parents.length,
      parents
    });
  } catch (error) {
    res.status(400).json({
      success: false,
      message: 'Error fetching parents by class',
      error: error.message
    });
  }
});

// GET parents with filters (including class filter)
Adminrouter.get('/parents', async (req, res) => {
  try {
    const { page = 1, limit = 10, search = '', isActive = '', className = '', section = '' } = req.query;
    
    const filters = { search, isActive, className, section };
    const parents = await Parent.getAllParents(filters, page, limit);
    const total = await Parent.countDocuments(filters);
    
    res.json({
      success: true,
      data: parents,
      pagination: {
        page: parseInt(page),
        limit: parseInt(limit),
        total,
        pages: Math.ceil(total / limit)
      }
    });
  } catch (error) {
    res.status(400).json({
      success: false,
      message: 'Error fetching parents',
      error: error.message
    });
  }
});
// DELETE parent
Adminrouter.delete('/parents/:id', async (req, res) => {
  try {
    const parent = await Parent.findOneAndDelete({ parentId: req.params.id });
    
    if (!parent) {
      return res.status(404).json({ 
        success: false,
        message: 'Parent not found' 
      });
    }

    res.json({ 
      success: true,
      message: 'Parent deleted successfully' 
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error deleting parent', 
      error: error.message 
    });
  }
});

// PATCH update parent status
Adminrouter.patch('/parents/:id/status', async (req, res) => {
  try {
    const { isActive } = req.body;

    const parent = await Parent.findOneAndUpdate(
      { parentId: req.params.id },
      { isActive },
      { new: true, runValidators: true }
    );

    if (!parent) {
      return res.status(404).json({ 
        success: false,
        message: 'Parent not found' 
      });
    }

    res.json({
      success: true,
      message: `Parent ${isActive ? 'activated' : 'deactivated'} successfully`,
      parent
    });
  } catch (error) {
    res.status(400).json({ 
      success: false,
      message: 'Error updating parent status', 
      error: error.message 
    });
  }
});

// GET parent statistics
Adminrouter.get('/parents-stats', async (req, res) => {
  try {
    const totalParents = await Parent.countDocuments();
    const activeParents = await Parent.countDocuments({ isActive: true });
    const parentsByGender = await Parent.aggregate([
      {
        $group: {
          _id: '$gender',
          count: { $sum: 1 }
        }
      }
    ]);

    // Parents with most children
    const parentsWithMostChildren = await Parent.aggregate([
      {
        $project: {
          name: 1,
          parentId: 1,
          email: 1,
          childrenCount: { $size: '$children' }
        }
      },
      {
        $sort: { childrenCount: -1 }
      },
      {
        $limit: 10
      }
    ]);

    res.json({
      success: true,
      totalParents,
      activeParents,
      inactiveParents: totalParents - activeParents,
      genderDistribution: parentsByGender,
      topParents: parentsWithMostChildren
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching parent statistics', 
      error: error.message 
    });
  }
});

// GET parents by child name (search)
Adminrouter.get('/parents/search/child', async (req, res) => {
  try {
    const { childName = '' } = req.query;
    
    const parents = await Parent.find({
      'children.name': { $regex: childName, $options: 'i' }
    })
    .select('parentId name email phone children')
    .limit(20);

    res.json({
      success: true,
      parents
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error searching parents by child', 
      error: error.message 
    });
  }
});
const Attendance = require('../models/Attendance');

// ATTENDANCE ROUTES

// GET attendance records with filters
Adminrouter.get('/attendance', async (req, res) => {
  try {
    const { 
      page = 1, 
      limit = 10, 
      date = '', 
      class: studentClass = '', 
      section = '', 
      status = '',
      search = '',
      startDate = '',
      endDate = ''
    } = req.query;

    const query = {};

    // Date filter
    if (date) {
      const selectedDate = new Date(date);
      const nextDate = new Date(selectedDate);
      nextDate.setDate(nextDate.getDate() + 1);
      
      query.date = {
        $gte: selectedDate,
        $lt: nextDate
      };
    }

    // Date range filter
    if (startDate || endDate) {
      query.date = {};
      if (startDate) {
        query.date.$gte = new Date(startDate);
      }
      if (endDate) {
        const end = new Date(endDate);
        end.setDate(end.getDate() + 1);
        query.date.$lt = end;
      }
    }

    // Class filter
    if (studentClass && studentClass !== 'All') {
      query.class = studentClass;
    }

    // Section filter
    if (section && section !== 'All') {
      query.section = section;
    }

    // Status filter
    if (status && status !== 'All') {
      query.status = status;
    }

    // Search filter
    if (search) {
      query.$or = [
        { name: { $regex: search, $options: 'i' } },
        { admissionNo: { $regex: search, $options: 'i' } },
        { rollNo: { $regex: search, $options: 'i' } }
      ];
    }

    const attendance = await Attendance.find(query)
      .sort({ date: -1, class: 1, section: 1, rollNo: 1 })
      .limit(limit * 1)
      .skip((page - 1) * limit);

    const total = await Attendance.countDocuments(query);

    res.json({
      success: true,
      attendance,
      totalPages: Math.ceil(total / limit),
      currentPage: page,
      total
    });
  } catch (error) {
    console.log(error)
    res.status(500).json({ 
      success: false,
      message: 'Error fetching attendance records', 
      error: error.message 
    });
  }
});

// GET students for attendance marking (with current date's attendance status)
Adminrouter.get('/attendance/students', async (req, res) => {
  try {
    const { 
      date = new Date().toISOString().split('T')[0],
      class: studentClass = '',
      section = ''
    } = req.query;

    const selectedDate = new Date(date);
    const nextDate = new Date(selectedDate);
    nextDate.setDate(nextDate.getDate() + 1);

    // Build student query
    const studentQuery = {};
    if (studentClass && studentClass !== 'All') {
      studentQuery.class = studentClass;
    }
    if (section && section !== 'All') {
      studentQuery.section = section;
    }

    // Get students
    const students = await Student.find(studentQuery)
      .select('admissionId studentId firstName lastName class section roll')
      .sort({ class: 1, section: 1, roll: 1 });

    // Get today's attendance for these students
    const todayAttendance = await Attendance.find({
      studentId: { $in: students.map(s => s._id) },
      date: {
        $gte: selectedDate,
        $lt: nextDate
      }
    });

    // Create a map of studentId to attendance status
    const attendanceMap = {};
    todayAttendance.forEach(att => {
      attendanceMap[att.studentId.toString()] = {
        status: att.status,
        notes: att.notes
      };
    });

    // Combine student data with attendance status
    const studentsWithAttendance = students.map(student => ({
      _id: student._id,
      admissionNo: student.admissionId,
      rollNo: student.roll || student.studentId,
      name: `${student.firstName} ${student.lastName}`,
      class: student.class,
      section: student.section,
      attendanceStatus: attendanceMap[student._id.toString()]?.status || 'Not Marked',
      notes: attendanceMap[student._id.toString()]?.notes || ''
    }));

    res.json({
      success: true,
      students: studentsWithAttendance,
      date: selectedDate
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching students for attendance', 
      error: error.message 
    });
  }
});

// POST mark attendance for multiple students
Adminrouter.post('/attendance/mark', async (req, res) => {
  try {
    const { date, attendanceData, markedBy } = req.body;

    if (!date || !attendanceData || !Array.isArray(attendanceData)) {
      return res.status(400).json({
        success: false,
        message: 'Date and attendance data are required'
      });
    }

    const attendanceDate = new Date(date);
    const nextDate = new Date(attendanceDate);
    nextDate.setDate(nextDate.getDate() + 1);

    const results = [];
    const errors = [];

    for (const attData of attendanceData) {
      try {
        const { studentId, admissionNo, rollNo, name, class: studentClass, section, status, notes } = attData;

        // Check if attendance already exists for this student on this date
        const existingAttendance = await Attendance.findOne({
          studentId,
          date: {
            $gte: attendanceDate,
            $lt: nextDate
          }
        });

        if (existingAttendance) {
          // Update existing attendance
          existingAttendance.status = status;
          existingAttendance.notes = notes || '';
          existingAttendance.markedAt = new Date();
          
          await existingAttendance.save();
          results.push({
            studentId,
            admissionNo,
            status: 'updated',
            attendance: existingAttendance
          });
        } else {
          // Create new attendance record
          const attendance = new Attendance({
            studentId,
            admissionNo,
            rollNo,
            name,
            class: studentClass,
            section,
            date: attendanceDate,
            status,
            notes: notes || '',
          });

          await attendance.save();
          results.push({
            studentId,
            admissionNo,
            status: 'created',
            attendance
          });
        }
      } catch (error) {
        errors.push({
          studentId: attData.studentId,
          admissionNo: attData.admissionNo,
          error: error.message
        });
      }
    }

    res.json({
      success: true,
      message: `Attendance marked for ${results.length} students`,
      results,
      errors: errors.length > 0 ? errors : undefined
    });

  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error marking attendance', 
      error: error.message 
    });
  }
});

// GET attendance statistics
Adminrouter.get('/attendance/stats', async (req, res) => {
  try {
    const { 
      class: studentClass = '',
      section = '',
      month = new Date().getMonth() + 1,
      year = new Date().getFullYear()
    } = req.query;

    const startDate = new Date(year, month - 1, 1);
    const endDate = new Date(year, month, 0);

    const query = {
      date: {
        $gte: startDate,
        $lte: endDate
      }
    };

    if (studentClass && studentClass !== 'All') {
      query.class = studentClass;
    }
    if (section && section !== 'All') {
      query.section = section;
    }

    const stats = await Attendance.aggregate([
      { $match: query },
      {
        $group: {
          _id: '$status',
          count: { $sum: 1 }
        }
      }
    ]);

    const totalAttendance = await Attendance.countDocuments(query);
    
    // Calculate percentage for each status
    const statusStats = {};
    stats.forEach(stat => {
      statusStats[stat._id] = {
        count: stat.count,
        percentage: ((stat.count / totalAttendance) * 100).toFixed(2)
      };
    });

    // Get daily attendance trend for the month
    const dailyTrend = await Attendance.aggregate([
      { $match: query },
      {
        $group: {
          _id: { $dateToString: { format: "%Y-%m-%d", date: "$date" } },
          present: {
            $sum: { $cond: [{ $eq: ["$status", "Present"] }, 1, 0] }
          },
          absent: {
            $sum: { $cond: [{ $eq: ["$status", "Absent"] }, 1, 0] }
          },
          late: {
            $sum: { $cond: [{ $eq: ["$status", "Late"] }, 1, 0] }
          },
          total: { $sum: 1 }
        }
      },
      { $sort: { _id: 1 } }
    ]);

    res.json({
      success: true,
      stats: statusStats,
      total: totalAttendance,
      dailyTrend,
      period: {
        month,
        year,
        startDate,
        endDate
      }
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching attendance statistics', 
      error: error.message 
    });
  }
});

// GET attendance report for a student
Adminrouter.get('/attendance/student/:studentId', async (req, res) => {
  try {
    const { studentId } = req.params;
    const { 
      page = 1, 
      limit = 30,
      startDate = '',
      endDate = ''
    } = req.query;

    const query = { studentId };

    // Date range filter
    if (startDate || endDate) {
      query.date = {};
      if (startDate) {
        query.date.$gte = new Date(startDate);
      }
      if (endDate) {
        const end = new Date(endDate);
        end.setDate(end.getDate() + 1);
        query.date.$lt = end;
      }
    }

    const attendance = await Attendance.find(query)
      .populate('markedBy', 'firstName lastName')
      .sort({ date: -1 })
      .limit(limit * 1)
      .skip((page - 1) * limit);

    const total = await Attendance.countDocuments(query);

    // Calculate summary statistics
    const summary = await Attendance.aggregate([
      { $match: query },
      {
        $group: {
          _id: '$status',
          count: { $sum: 1 }
        }
      }
    ]);

    const totalRecords = summary.reduce((acc, curr) => acc + curr.count, 0);
    const summaryStats = {};
    summary.forEach(stat => {
      summaryStats[stat._id] = {
        count: stat.count,
        percentage: totalRecords > 0 ? ((stat.count / totalRecords) * 100).toFixed(2) : '0.00'
      };
    });

    res.json({
      success: true,
      attendance,
      summary: summaryStats,
      totalPages: Math.ceil(total / limit),
      currentPage: page,
      total
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching student attendance', 
      error: error.message 
    });
  }
});

// DELETE attendance record
Adminrouter.delete('/attendance/:id', async (req, res) => {
  try {
    const attendance = await Attendance.findByIdAndDelete(req.params.id);
    
    if (!attendance) {
      return res.status(404).json({ 
        success: false,
        message: 'Attendance record not found' 
      });
    }

    res.json({ 
      success: true,
      message: 'Attendance record deleted successfully' 
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error deleting attendance record', 
      error: error.message 
    });
  }
});

const TeacherAttendance = require('../models/TeacherAttendance');

// TEACHER ATTENDANCE ROUTES

// GET all teacher attendance records with filters
Adminrouter.get('/teacher-attendance', async (req, res) => {
  try {
    const { 
      page = 1, 
      limit = 10, 
      date = '', 
      department = '', 
      status = '',
      search = '',
      startDate = '',
      endDate = ''
    } = req.query;

    const query = {};

    // Date filter
    if (date) {
      const selectedDate = new Date(date);
      const nextDate = new Date(selectedDate);
      nextDate.setDate(nextDate.getDate() + 1);
      
      query.date = {
        $gte: selectedDate,
        $lt: nextDate
      };
    }

    // Date range filter
    if (startDate || endDate) {
      query.date = {};
      if (startDate) {
        query.date.$gte = new Date(startDate);
      }
      if (endDate) {
        const end = new Date(endDate);
        end.setDate(end.getDate() + 1);
        query.date.$lt = end;
      }
    }

    // Department filter
    if (department && department !== 'All') {
      query.department = department;
    }

    // Status filter
    if (status && status !== 'All') {
      query.status = status;
    }

    // Search filter
    if (search) {
      query.$or = [
        { teacherName: { $regex: search, $options: 'i' } },
        { teacherId: { $regex: search, $options: 'i' } }
      ];
    }

    const attendance = await TeacherAttendance.find(query)
      .sort({ date: -1, teacherName: 1 })
      .limit(limit * 1)
      .skip((page - 1) * limit);

    const total = await TeacherAttendance.countDocuments(query);

    res.json({
      success: true,
      attendance,
      totalPages: Math.ceil(total / limit),
      currentPage: page,
      total
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching teacher attendance records', 
      error: error.message 
    });
  }
});

// GET teachers for attendance marking
Adminrouter.get('/teacher-attendance/teachers', async (req, res) => {
  try {
    const { 
      date = new Date().toISOString().split('T')[0],
      department = '',
      search = ''
    } = req.query;

    const selectedDate = new Date(date);
    const nextDate = new Date(selectedDate);
    nextDate.setDate(nextDate.getDate() + 1);

    // Build teacher query
    const teacherQuery = { isActive: true };
    
    if (department && department !== 'All') {
      teacherQuery.department = department;
    }
    
    if (search) {
      teacherQuery.$or = [
        { firstName: { $regex: search, $options: 'i' } },
        { lastName: { $regex: search, $options: 'i' } },
        { teacherId: { $regex: search, $options: 'i' } }
      ];
    }

    // Get active teachers
    const teachers = await Teacher.find(teacherQuery)
      .select('teacherId firstName lastName email phone department subject photo')
      .sort({ firstName: 1 });

    // Get today's attendance for these teachers
    const todayAttendance = await TeacherAttendance.find({
      teacherId: { $in: teachers.map(t => t.teacherId) },
      date: {
        $gte: selectedDate,
        $lt: nextDate
      }
    });

    // Create a map of teacherId to attendance status
    const attendanceMap = {};
    todayAttendance.forEach(att => {
      attendanceMap[att.teacherId] = {
        status: att.status,
        notes: att.notes
      };
    });

    // Combine teacher data with attendance status
    const teachersWithAttendance = teachers.map(teacher => ({
      _id: teacher._id,
      teacherId: teacher.teacherId,
      name: `${teacher.firstName} ${teacher.lastName}`,
      email: teacher.email,
      phone: teacher.phone,
      department: teacher.department,
      subject: teacher.subject,
      photo: teacher.photo,
      attendanceStatus: attendanceMap[teacher.teacherId]?.status || 'Not Marked',
      notes: attendanceMap[teacher.teacherId]?.notes || ''
    }));

    res.json({
      success: true,
      teachers: teachersWithAttendance,
      date: selectedDate
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching teachers for attendance', 
      error: error.message 
    });
  }
});

// POST mark attendance for multiple teachers
Adminrouter.post('/teacher-attendance/mark', async (req, res) => {
  try {
    const { date, attendanceData, markedBy } = req.body;

    if (!date || !attendanceData || !Array.isArray(attendanceData)) {
      return res.status(400).json({
        success: false,
        message: 'Date and attendance data are required'
      });
    }

    const attendanceDate = new Date(date);
    const nextDate = new Date(attendanceDate);
    nextDate.setDate(nextDate.getDate() + 1);

    const results = [];
    const errors = [];

    for (const attData of attendanceData) {
      try {
        const { teacherId, name, department, status, notes } = attData;

        // Check if attendance already exists for this teacher on this date
        const existingAttendance = await TeacherAttendance.findOne({
          teacherId,
          date: {
            $gte: attendanceDate,
            $lt: nextDate
          }
        });

        if (existingAttendance) {
          // Update existing attendance
          existingAttendance.status = status;
          existingAttendance.notes = notes || '';
          existingAttendance.markedBy = markedBy;
          existingAttendance.markedAt = new Date();
          
          await existingAttendance.save();
          results.push({
            teacherId,
            status: 'updated',
            attendance: existingAttendance
          });
        } else {
          // Create new attendance record
          const attendance = new TeacherAttendance({
            teacherId,
            date: attendanceDate,
            status,
            notes: notes || '',
            markedBy,
            teacherName: name,
            department
          });

          await attendance.save();
          results.push({
            teacherId,
            status: 'created',
            attendance
          });
        }
      } catch (error) {
        errors.push({
          teacherId: attData.teacherId,
          error: error.message
        });
      }
    }

    res.json({
      success: true,
      message: `Attendance marked for ${results.length} teachers`,
      results,
      errors: errors.length > 0 ? errors : undefined
    });

  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error marking teacher attendance', 
      error: error.message 
    });
  }
});

// GET teacher attendance statistics
Adminrouter.get('/teacher-attendance/stats', async (req, res) => {
  try {
    const { 
      department = '',
      month = new Date().getMonth() + 1,
      year = new Date().getFullYear()
    } = req.query;

    const startDate = new Date(year, month - 1, 1);
    const endDate = new Date(year, month, 0);

    const query = {
      date: {
        $gte: startDate,
        $lte: endDate
      }
    };

    if (department && department !== 'All') {
      query.department = department;
    }

    const stats = await TeacherAttendance.aggregate([
      { $match: query },
      {
        $group: {
          _id: '$status',
          count: { $sum: 1 }
        }
      }
    ]);

    const totalAttendance = await TeacherAttendance.countDocuments(query);
    
    // Calculate percentage for each status
    const statusStats = {};
    stats.forEach(stat => {
      statusStats[stat._id] = {
        count: stat.count,
        percentage: totalAttendance > 0 ? ((stat.count / totalAttendance) * 100).toFixed(2) : '0.00'
      };
    });

    // Get daily attendance trend for the month
    const dailyTrend = await TeacherAttendance.aggregate([
      { $match: query },
      {
        $group: {
          _id: { $dateToString: { format: "%Y-%m-%d", date: "$date" } },
          present: {
            $sum: { $cond: [{ $eq: ["$status", "Present"] }, 1, 0] }
          },
          absent: {
            $sum: { $cond: [{ $eq: ["$status", "Absent"] }, 1, 0] }
          },
          late: {
            $sum: { $cond: [{ $eq: ["$status", "Late"] }, 1, 0] }
          },
          total: { $sum: 1 }
        }
      },
      { $sort: { _id: 1 } }
    ]);

    // Get department-wise statistics
    const departmentStats = await TeacherAttendance.aggregate([
      { $match: query },
      {
        $group: {
          _id: '$department',
          total: { $sum: 1 },
          present: {
            $sum: { $cond: [{ $eq: ["$status", "Present"] }, 1, 0] }
          },
          absent: {
            $sum: { $cond: [{ $eq: ["$status", "Absent"] }, 1, 0] }
          },
          late: {
            $sum: { $cond: [{ $eq: ["$status", "Late"] }, 1, 0] }
          }
        }
      }
    ]);

    res.json({
      success: true,
      stats: statusStats,
      total: totalAttendance,
      dailyTrend,
      departmentStats,
      period: {
        month,
        year,
        startDate,
        endDate
      }
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching teacher attendance statistics', 
      error: error.message 
    });
  }
});

// GET attendance report for a specific teacher
Adminrouter.get('/teacher-attendance/teacher/:teacherId', async (req, res) => {
  try {
    const { teacherId } = req.params;
    const { 
      page = 1, 
      limit = 30,
      startDate = '',
      endDate = ''
    } = req.query;

    const query = { teacherId };

    // Date range filter
    if (startDate || endDate) {
      query.date = {};
      if (startDate) {
        query.date.$gte = new Date(startDate);
      }
      if (endDate) {
        const end = new Date(endDate);
        end.setDate(end.getDate() + 1);
        query.date.$lt = end;
      }
    }

    const attendance = await TeacherAttendance.find(query)
      .populate('markedBy', 'username')
      .sort({ date: -1 })
      .limit(limit * 1)
      .skip((page - 1) * limit);

    const total = await TeacherAttendance.countDocuments(query);

    // Calculate summary statistics
    const summary = await TeacherAttendance.aggregate([
      { $match: query },
      {
        $group: {
          _id: '$status',
          count: { $sum: 1 }
        }
      }
    ]);

    const totalRecords = summary.reduce((acc, curr) => acc + curr.count, 0);
    const summaryStats = {};
    summary.forEach(stat => {
      summaryStats[stat._id] = {
        count: stat.count,
        percentage: totalRecords > 0 ? ((stat.count / totalRecords) * 100).toFixed(2) : '0.00'
      };
    });

    res.json({
      success: true,
      attendance,
      summary: summaryStats,
      totalPages: Math.ceil(total / limit),
      currentPage: page,
      total
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching teacher attendance report', 
      error: error.message 
    });
  }
});

// DELETE teacher attendance record
Adminrouter.delete('/teacher-attendance/:id', async (req, res) => {
  try {
    const attendance = await TeacherAttendance.findByIdAndDelete(req.params.id);
    
    if (!attendance) {
      return res.status(404).json({ 
        success: false,
        message: 'Teacher attendance record not found' 
      });
    }

    res.json({ 
      success: true,
      message: 'Teacher attendance record deleted successfully' 
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error deleting teacher attendance record', 
      error: error.message 
    });
  }
});

// GET departments for filter dropdown
Adminrouter.get('/teacher-attendance/departments', async (req, res) => {
  try {
    const departments = await Teacher.distinct('department');
    
    res.json({
      success: true,
      departments: ['All', ...departments]
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching departments', 
      error: error.message 
    });
  }
});



const ExamFee = require('../models/ExamFee');

// EXAM FEE ROUTES

// GET all exam fees
Adminrouter.get('/exam-fees', async (req, res) => {
  try {
    const { page = 1, limit = 10, search = '', examName = '', className = '' } = req.query;
    
    const query = {};
    
    if (search) {
      query.$or = [
        { studentName: { $regex: search, $options: 'i' } },
        { rollNo: { $regex: search, $options: 'i' } }
      ];
    }
    
    if (examName) query.examName = examName;
    if (className) query.className = className;

    const examFees = await ExamFee.find(query)
      .populate('studentId', 'firstName lastName phone')
      .populate('createdBy', 'username')
      .sort({ createdAt: -1 })
      .limit(limit * 1)
      .skip((page - 1) * limit);

    const total = await ExamFee.countDocuments(query);

    res.json({
      success: true,
      examFees,
      totalPages: Math.ceil(total / limit),
      currentPage: page,
      total
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching exam fees', 
      error: error.message 
    });
  }
});

// GET exam fee by ID
Adminrouter.get('/exam-fees/:id', async (req, res) => {
  try {
    const examFee = await ExamFee.findById(req.params.id)
      .populate('studentId')
      .populate('createdBy', 'username');
    
    if (!examFee) {
      return res.status(404).json({ 
        success: false,
        message: 'Exam fee record not found' 
      });
    }

    res.json({
      success: true,
      examFee
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching exam fee', 
      error: error.message 
    });
  }
});

Adminrouter.post('/exam-fees', async (req, res) => {
  try {
    const {
      studentId,
      studentName,
      className,
      rollNo,
      examName,
      amount,
      paidAmount,
      paymentMethod,
      paymentDate,
      remarks
    } = req.body;

    // Validate required fields - removed dueDate from validation
    if (!studentId || !studentName || !className || !examName || !amount) {
      return res.status(400).json({ 
        success: false, 
        message: 'Please fill all required fields' 
      });
    }

    // Check if exam fee already exists for this student and exam
    const existingFee = await ExamFee.findOne({
      studentId,
      examName,
      examYear: new Date().getFullYear()
    });

    const examFeeData = {
      studentId,
      studentName,
      className,
      rollNo,
      examName,
      amount: parseFloat(amount),
      paidAmount: paidAmount ? parseFloat(paidAmount) : 0,
      paymentMethod,
      paymentDate: paymentDate || null,
      remarks,
      createdBy: req.adminId // Assuming you have admin ID from auth middleware
    };

    const examFee = new ExamFee(examFeeData);
    await examFee.save();

    res.status(201).json({
      success: true,
      message: 'Exam fee created successfully',
      examFee
    });
  } catch (error) {
    console.log(error);
    res.status(400).json({ 
      success: false,
      message: 'Error creating exam fee', 
      error: error.message 
    });
  }
});

// PUT update exam fee (no changes needed here)
Adminrouter.put('/exam-fees/:id', async (req, res) => {
  try {
    const {
      paidAmount,
      paymentMethod,
      paymentDate,
      remarks
    } = req.body;

    const examFee = await ExamFee.findById(req.params.id);
    
    if (!examFee) {
      return res.status(404).json({ 
        success: false,
        message: 'Exam fee not found' 
      });
    }

    // Update fields
    if (paidAmount !== undefined) examFee.paidAmount = parseFloat(paidAmount);
    if (paymentMethod) examFee.paymentMethod = paymentMethod;
    if (paymentDate) examFee.paymentDate = new Date(paymentDate);
    if (remarks) examFee.remarks = remarks;

    await examFee.save();

    res.json({
      success: true,
      message: 'Exam fee updated successfully',
      examFee
    });
  } catch (error) {
    res.status(400).json({ 
      success: false,
      message: 'Error updating exam fee', 
      error: error.message 
    });
  }
});

// DELETE exam fee
Adminrouter.delete('/exam-fees/:id', async (req, res) => {
  try {
    const examFee = await ExamFee.findByIdAndDelete(req.params.id);
    
    if (!examFee) {
      return res.status(404).json({ 
        success: false,
        message: 'Exam fee not found' 
      });
    }

    res.json({ 
      success: true,
      message: 'Exam fee deleted successfully' 
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error deleting exam fee', 
      error: error.message 
    });
  }
});

// GET exam fee summary
Adminrouter.get('/exam-fees-summary', async (req, res) => {
  try {
    const { examName = '', examYear = new Date().getFullYear() } = req.query;

    const summary = await ExamFee.aggregate([
      {
        $match: {
          examName: examName || { $exists: true },
          examYear: parseInt(examYear)
        }
      },
      {
        $group: {
          _id: '$examName',
          totalAmount: { $sum: '$amount' },
          totalPaid: { $sum: '$paidAmount' },
          totalDue: { $sum: '$dueAmount' },
          studentCount: { $sum: 1 },
          paidCount: {
            $sum: { $cond: [{ $eq: ['$paymentStatus', 'Paid'] }, 1, 0] }
          },
          partialCount: {
            $sum: { $cond: [{ $eq: ['$paymentStatus', 'Partial'] }, 1, 0] }
          },
          unpaidCount: {
            $sum: { $cond: [{ $eq: ['$paymentStatus', 'Unpaid'] }, 1, 0] }
          }
        }
      }
    ]);

    res.json({
      success: true,
      summary
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching exam fee summary', 
      error: error.message 
    });
  }
});

// GET students for exam fee dropdown
Adminrouter.get('/exam-fee-students', async (req, res) => {
  try {
    const { className = '', search = '' } = req.query;
    
    const query = {};
    if (className) query.class = className;
    if (search) {
      query.$or = [
        { firstName: { $regex: search, $options: 'i' } },
        { lastName: { $regex: search, $options: 'i' } },
        { studentId: { $regex: search, $options: 'i' } }
      ];
    }

    const students = await Student.find(query)
      .select('firstName lastName studentId class roll monthlyFee')
      .limit(20);

    res.json({
      success: true,
      students: students.map(s => ({
        id: s._id,
        name: `${s.firstName} ${s.lastName}`,
        studentId: s.studentId,
        class: s.class,
        roll: s.roll,
        monthlyFee: s.monthlyFee
      }))
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching students', 
      error: error.message 
    });
  }
});

// GET exam names for filter
Adminrouter.get('/exam-names', async (req, res) => {
  try {
    const examNames = ['Half Yearly', 'Final', 'Monthly Test', 'Quarterly', 'Pre-Test', 'Test Exam'];
    res.json({
      success: true,
      examNames
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching exam names', 
      error: error.message 
    });
  }
});




const Expense = require('../models/Expense');

// ==================== EXPENSE ROUTES ====================

// GET all expenses with filters
Adminrouter.get('/expenses', async (req, res) => {
  try {
    const { page = 1, limit = 10, search = '', category = '' } = req.query;
    
    const query = {};
    
    // Search by title or description
    if (search) {
      query.$or = [
        { expenseTitle: { $regex: search, $options: 'i' } },
        { description: { $regex: search, $options: 'i' } },
        { vendorName: { $regex: search, $options: 'i' } }
      ];
    }
    
    // Category filter
    if (category && category !== 'All') {
      query.expenseCategory = category;
    }

    const expenses = await Expense.find(query)
      .populate('createdBy', 'username')
      .sort({ expenseDate: -1, createdAt: -1 })
      .limit(limit * 1)
      .skip((page - 1) * limit);

    const total = await Expense.countDocuments(query);

    // Calculate total amount
    const totalAmount = await Expense.aggregate([
      { $match: query },
      { $group: { _id: null, total: { $sum: '$amount' } } }
    ]);

    res.json({
      success: true,
      expenses,
      totalPages: Math.ceil(total / limit),
      currentPage: page,
      total,
      totalAmount: totalAmount.length > 0 ? totalAmount[0].total : 0
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching expenses', 
      error: error.message 
    });
  }
});

// GET expense by ID
Adminrouter.get('/expenses/:id', async (req, res) => {
  try {
    const expense = await Expense.findById(req.params.id)
      .populate('createdBy', 'username');
    
    if (!expense) {
      return res.status(404).json({ 
        success: false,
        message: 'Expense not found' 
      });
    }

    res.json({
      success: true,
      expense
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching expense', 
      error: error.message 
    });
  }
});

// POST create new expense
Adminrouter.post('/expenses', async (req, res) => {
  try {
    const {
      expenseTitle,
      expenseCategory,
      amount,
      expenseDate,
      paymentMethod,
      description,
      vendorName,
      remarks
    } = req.body;

    // Validate required fields
    if (!expenseTitle || !expenseCategory || !amount || !paymentMethod) {
      return res.status(400).json({ 
        success: false, 
        message: 'Please fill all required fields' 
      });
    }

    const expenseData = {
      expenseTitle: expenseTitle.trim(),
      expenseCategory,
      amount: parseFloat(amount),
      expenseDate: expenseDate ? new Date(expenseDate) : new Date(),
      paymentMethod,
      description: description || '',
      vendorName: vendorName || '',
      remarks: remarks || '',
      createdBy: req.adminId
    };

    const expense = new Expense(expenseData);
    await expense.save();

    res.status(201).json({
      success: true,
      message: 'Expense added successfully',
      expense
    });
  } catch (error) {
    console.log(error);
    res.status(400).json({ 
      success: false,
      message: 'Error adding expense', 
      error: error.message 
    });
  }
});

// PUT update expense
Adminrouter.put('/expenses/:id', async (req, res) => {
  try {
    const {
      expenseTitle,
      expenseCategory,
      amount,
      expenseDate,
      paymentMethod,
      description,
      vendorName,
      remarks
    } = req.body;

    const updates = {};
    if (expenseTitle) updates.expenseTitle = expenseTitle.trim();
    if (expenseCategory) updates.expenseCategory = expenseCategory;
    if (amount) updates.amount = parseFloat(amount);
    if (expenseDate) updates.expenseDate = new Date(expenseDate);
    if (paymentMethod) updates.paymentMethod = paymentMethod;
    if (description !== undefined) updates.description = description;
    if (vendorName !== undefined) updates.vendorName = vendorName;
    if (remarks !== undefined) updates.remarks = remarks;

    const expense = await Expense.findByIdAndUpdate(
      req.params.id,
      updates,
      { new: true, runValidators: true }
    ).populate('createdBy', 'username');

    if (!expense) {
      return res.status(404).json({ 
        success: false,
        message: 'Expense not found' 
      });
    }

    res.json({
      success: true,
      message: 'Expense updated successfully',
      expense
    });
  } catch (error) {
    res.status(400).json({ 
      success: false,
      message: 'Error updating expense', 
      error: error.message 
    });
  }
});

// DELETE expense
Adminrouter.delete('/expenses/:id', async (req, res) => {
  try {
    const expense = await Expense.findByIdAndDelete(req.params.id);
    
    if (!expense) {
      return res.status(404).json({ 
        success: false,
        message: 'Expense not found' 
      });
    }

    res.json({ 
      success: true,
      message: 'Expense deleted successfully' 
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error deleting expense', 
      error: error.message 
    });
  }
});

// GET expense summary by category
Adminrouter.get('/expenses-summary', async (req, res) => {
  try {
    const { month, year = new Date().getFullYear() } = req.query;

    const matchStage = { year: parseInt(year) };
    if (month && month !== 'All') {
      matchStage.month = month;
    }

    const summary = await Expense.aggregate([
      {
        $addFields: {
          month: { $dateToString: { format: "%B", date: "$expenseDate" } },
          year: { $year: "$expenseDate" }
        }
      },
      { $match: matchStage },
      {
        $group: {
          _id: '$expenseCategory',
          totalAmount: { $sum: '$amount' },
          count: { $sum: 1 }
        }
      },
      { $sort: { totalAmount: -1 } }
    ]);

    // Total expenses for the period
    const totalResult = await Expense.aggregate([
      {
        $addFields: {
          month: { $dateToString: { format: "%B", date: "$expenseDate" } },
          year: { $year: "$expenseDate" }
        }
      },
      { $match: matchStage },
      {
        $group: {
          _id: null,
          totalAmount: { $sum: '$amount' },
          totalCount: { $sum: 1 }
        }
      }
    ]);

    res.json({
      success: true,
      summary,
      total: totalResult.length > 0 ? totalResult[0] : { totalAmount: 0, totalCount: 0 }
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching expense summary', 
      error: error.message 
    });
  }
});

// GET expense categories list
Adminrouter.get('/expense-categories', async (req, res) => {
  try {
    const categories = [
      'Salary', 'Electricity Bill', 'Water Bill', 'Internet Bill',
      'Rent', 'Maintenance', 'Stationery', 'Equipment', 'Transportation',
      'Food', 'Events', 'Sports', 'Library', 'Medical', 'Other'
    ];
    
    res.json({
      success: true,
      categories
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching categories', 
      error: error.message 
    });
  }
});
const Book = require('../models/Book');
const BookBorrow = require('../models/BookBorrow ');
// Configure multer for book image uploads
const bookStorage = multer.diskStorage({
  destination: function(req, file, cb) {
    const dir = "./public/uploads/books";
    // Create directory if it doesn't exist
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, { recursive: true });
    }
    cb(null, dir);
  },
  filename: function(req, file, cb) {
    cb(null, `book_${Date.now()}_${file.originalname}`);
  }
});

const uploadBookImage = multer({
  storage: bookStorage,
  fileFilter: fileFilter,
  limits: {
    fileSize: 5 * 1024 * 1024 // 5MB limit
  }
});
// ==================== BOOK ROUTES ====================

// GET all books with filters and pagination
Adminrouter.get('/books', async (req, res) => {
  try {
    const { page = 1, limit = 10, search = '', category = '' } = req.query;
    
    const query = {};
    
    // Search by title, author, or publisher
    if (search) {
      query.$or = [
        { bookTitle: { $regex: search, $options: 'i' } },
        { authorName: { $regex: search, $options: 'i' } },
        { publisher: { $regex: search, $options: 'i' } }
      ];
    }
    
    // Category filter
    if (category && category !== 'All') {
      query.bookCategory = category;
    }

    const books = await Book.find(query)
      .populate('createdBy', 'username')
      .sort({ createdAt: -1 })
      .limit(limit * 1)
      .skip((page - 1) * limit);

    const total = await Book.countDocuments(query);

    // Calculate total books count
    const totalStats = await Book.aggregate([
      { $match: query },
      {
        $group: {
          _id: null,
          totalQuantity: { $sum: '$quantity' },
          totalAvailable: { $sum: '$availableQuantity' }
        }
      }
    ]);

    res.json({
      success: true,
      books,
      totalPages: Math.ceil(total / limit),
      currentPage: page,
      total,
      stats: totalStats.length > 0 ? totalStats[0] : { totalQuantity: 0, totalAvailable: 0 }
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching books', 
      error: error.message 
    });
  }
});

// GET book by ID
Adminrouter.get('/books/:id', async (req, res) => {
  try {
    const book = await Book.findById(req.params.id)
      .populate('createdBy', 'username');
    
    if (!book) {
      return res.status(404).json({ 
        success: false,
        message: 'Book not found' 
      });
    }

    res.json({
      success: true,
      book
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching book', 
      error: error.message 
    });
  }
});

// POST create new book with image
Adminrouter.post('/books', uploadBookImage.single('bookImage'), async (req, res) => {
  try {
    const {
      bookTitle,
      bookCategory,
      authorName,
      publisher,
      edition,
      publicationYear,
      quantity,
      description
    } = req.body;

    // Validate required fields
    if (!bookTitle || !bookCategory || !authorName || !quantity) {
      return res.status(400).json({ 
        success: false, 
        message: 'Please fill all required fields' 
      });
    }

    const bookData = {
      bookTitle: bookTitle.trim(),
      bookCategory,
      authorName: authorName.trim(),
      publisher: publisher || '',
      edition: edition || '',
      publicationYear: publicationYear ? parseInt(publicationYear) : null,
      quantity: parseInt(quantity),
      availableQuantity: parseInt(quantity), // Initially same as total quantity
      description: description || '',
      createdBy: req.adminId
    };

    // Add book image if uploaded
    if (req.file) {
      bookData.bookImage = req.file.filename;
    }

    const book = new Book(bookData);
    await book.save();

    res.status(201).json({
      success: true,
      message: 'Book added successfully',
      book
    });
  } catch (error) {
    console.log(error);
    res.status(400).json({ 
      success: false,
      message: 'Error adding book', 
      error: error.message 
    });
  }
});

// PUT update book with image
Adminrouter.put('/books/:id', uploadBookImage.single('bookImage'), async (req, res) => {
  try {
    const {
      bookTitle,
      bookCategory,
      authorName,
      publisher,
      edition,
      publicationYear,
      quantity,
      description
    } = req.body;

    const updates = {};
    if (bookTitle) updates.bookTitle = bookTitle.trim();
    if (bookCategory) updates.bookCategory = bookCategory;
    if (authorName) updates.authorName = authorName.trim();
    if (publisher !== undefined) updates.publisher = publisher;
    if (edition !== undefined) updates.edition = edition;
    if (publicationYear) updates.publicationYear = parseInt(publicationYear);
    if (quantity) {
      updates.quantity = parseInt(quantity);
      // When quantity changes, update available quantity accordingly
      const book = await Book.findById(req.params.id);
      if (book) {
        const diff = parseInt(quantity) - book.quantity;
        updates.availableQuantity = Math.max(0, book.availableQuantity + diff);
      }
    }
    if (description !== undefined) updates.description = description;

    // Handle file upload
    if (req.file) {
      updates.bookImage = req.file.filename;
      
      // Delete old image if exists
      const existingBook = await Book.findById(req.params.id);
      if (existingBook && existingBook.bookImage) {
        const oldImagePath = path.join('./public/uploads/books', existingBook.bookImage);
        if (fs.existsSync(oldImagePath)) {
          fs.unlinkSync(oldImagePath);
        }
      }
    }

    const book = await Book.findByIdAndUpdate(
      req.params.id,
      updates,
      { new: true, runValidators: true }
    ).populate('createdBy', 'username');

    if (!book) {
      return res.status(404).json({ 
        success: false,
        message: 'Book not found' 
      });
    }

    res.json({
      success: true,
      message: 'Book updated successfully',
      book
    });
  } catch (error) {
    res.status(400).json({ 
      success: false,
      message: 'Error updating book', 
      error: error.message 
    });
  }
});

// DELETE book
Adminrouter.delete('/books/:id', async (req, res) => {
  try {
    const book = await Book.findById(req.params.id);
    
    if (!book) {
      return res.status(404).json({ 
        success: false,
        message: 'Book not found' 
      });
    }

    // Delete book image if exists
    if (book.bookImage) {
      const imagePath = path.join('./public/uploads/books', book.bookImage);
      if (fs.existsSync(imagePath)) {
        fs.unlinkSync(imagePath);
      }
    }

    await Book.findByIdAndDelete(req.params.id);

    res.json({ 
      success: true,
      message: 'Book deleted successfully' 
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error deleting book', 
      error: error.message 
    });
  }
});

// GET books by category
Adminrouter.get('/books/category/:category', async (req, res) => {
  try {
    const { category } = req.params;
    const { page = 1, limit = 10 } = req.query;

    const books = await Book.find({ bookCategory: category })
      .sort({ bookTitle: 1 })
      .limit(limit * 1)
      .skip((page - 1) * limit);

    const total = await Book.countDocuments({ bookCategory: category });

    res.json({
      success: true,
      books,
      totalPages: Math.ceil(total / limit),
      currentPage: page,
      total
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching books by category', 
      error: error.message 
    });
  }
});

// GET book categories list
Adminrouter.get('/book-categories', async (req, res) => {
  try {
    const categories = [
      'Textbook', 'Story Book', 'Novel', 'Poetry', 'Drama',
      'Science', 'Math', 'History', 'Geography', 'Religion',
      'Dictionary', 'Encyclopedia', 'Magazine', 'Other'
    ];
    
    res.json({
      success: true,
      categories
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching categories', 
      error: error.message 
    });
  }
});

// GET books summary/statistics
Adminrouter.get('/books-summary', async (req, res) => {
  try {
    // Total books stats
    const totalStats = await Book.aggregate([
      {
        $group: {
          _id: null,
          totalBooks: { $sum: 1 },
          totalQuantity: { $sum: '$quantity' },
          totalAvailable: { $sum: '$availableQuantity' }
        }
      }
    ]);

    // Books by category
    const booksByCategory = await Book.aggregate([
      {
        $group: {
          _id: '$bookCategory',
          count: { $sum: 1 },
          totalQuantity: { $sum: '$quantity' }
        }
      },
      { $sort: { count: -1 } }
    ]);

    // Recently added books
    const recentBooks = await Book.find()
      .sort({ createdAt: -1 })
      .limit(5)
      .select('bookTitle authorName quantity availableQuantity bookImage');

    // Low stock books (available quantity < 5)
    const lowStockBooks = await Book.find({ availableQuantity: { $lt: 5 } })
      .select('bookTitle authorName quantity availableQuantity bookImage');

    res.json({
      success: true,
      summary: totalStats.length > 0 ? totalStats[0] : { 
        totalBooks: 0, 
        totalQuantity: 0, 
        totalAvailable: 0
      },
      booksByCategory,
      recentBooks,
      lowStockBooks,
      lowStockCount: lowStockBooks.length
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching book summary', 
      error: error.message 
    });
  }
});


// ==================== SIMPLE LIBRARY BOOK BORROWING ROUTES ====================

// GET all borrowed books
Adminrouter.get('/book-borrows', async (req, res) => {
  try {
    const { page = 1, limit = 10, search = '', status = '' } = req.query;
    
    const query = {};
    
    if (search) {
      query.$or = [
        { borrowerName: { $regex: search, $options: 'i' } },
        { bookTitle: { $regex: search, $options: 'i' } },
        { borrowerId: { $regex: search, $options: 'i' } }
      ];
    }
    
    if (status && status !== 'All') {
      query.status = status;
    }

    // Update overdue status
    await BookBorrow.updateMany(
      { status: 'Borrowed', dueDate: { $lt: new Date() } },
      { status: 'Overdue' }
    );

    const borrows = await BookBorrow.find(query)
      .populate('issuedBy', 'username')
      .sort({ createdAt: -1 })
      .limit(limit * 1)
      .skip((page - 1) * limit);

    const total = await BookBorrow.countDocuments(query);

    res.json({
      success: true,
      borrows,
      totalPages: Math.ceil(total / limit),
      currentPage: page,
      total
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching borrowed books', 
      error: error.message 
    });
  }
});

// GET single borrow record
Adminrouter.get('/book-borrows/:id', async (req, res) => {
  try {
    const borrow = await BookBorrow.findById(req.params.id)
      .populate('issuedBy', 'username');
    
    if (!borrow) {
      return res.status(404).json({ 
        success: false,
        message: 'Record not found' 
      });
    }

    res.json({
      success: true,
      borrow
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching record', 
      error: error.message 
    });
  }
});

// GET borrowers for dropdown (students and teachers)
Adminrouter.get('/borrowers', async (req, res) => {
  try {
    const { type = 'student', search = '' } = req.query;
    
    let borrowers = [];
    
    if (type === 'student') {
      const query = search ? {
        $or: [
          { firstName: { $regex: search, $options: 'i' } },
          { lastName: { $regex: search, $options: 'i' } },
          { studentId: { $regex: search, $options: 'i' } }
        ]
      } : {};
      
      const students = await Student.find(query)
        .select('firstName lastName studentId class section phone email')
        .limit(20);
      
      borrowers = students.map(s => ({
        id: s.studentId,
        name: `${s.firstName} ${s.lastName}`,
        type: 'student',
        class: s.class,
        section: s.section,
        phone: s.phone
      }));
    } else {
      const query = search ? {
        $or: [
          { firstName: { $regex: search, $options: 'i' } },
          { lastName: { $regex: search, $options: 'i' } },
          { teacherId: { $regex: search, $options: 'i' } }
        ]
      } : {};
      
      const teachers = await Teacher.find(query)
        .select('firstName lastName teacherId department phone email')
        .limit(20);
      
      borrowers = teachers.map(t => ({
        id: t.teacherId,
        name: `${t.firstName} ${t.lastName}`,
        type: 'teacher',
        department: t.department,
        phone: t.phone
      }));
    }

    res.json({
      success: true,
      borrowers
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching borrowers', 
      error: error.message 
    });
  }
});

// POST issue a book
Adminrouter.post('/book-borrows/issue', async (req, res) => {
  try {
    const {
      bookId,
      bookTitle,
      borrowerType,
      borrowerId,
      borrowerName,
      borrowerClass,
      borrowerPhone,
      dueDate,
      remarks
    } = req.body;

    // Validation
    if (!bookId || !borrowerType || !borrowerId || !borrowerName || !dueDate) {
      return res.status(400).json({ 
        success: false, 
        message: 'Please fill all required fields' 
      });
    }

    // Check if book exists and is available
    const book = await Book.findById(bookId);
    if (!book) {
      return res.status(404).json({ 
        success: false, 
        message: 'Book not found' 
      });
    }

    if (book.availableQuantity < 1) {
      return res.status(400).json({ 
        success: false, 
        message: 'Book is not available' 
      });
    }

    // Check if borrower already has this book
    const existingBorrow = await BookBorrow.findOne({
      bookId,
      borrowerId,
      status: { $in: ['Borrowed', 'Overdue'] }
    });

    if (existingBorrow) {
      return res.status(400).json({ 
        success: false, 
        message: 'This borrower already has this book and hasn\'t returned it yet' 
      });
    }

    // Create borrow record
    const borrowData = {
      bookId,
      bookTitle: book.bookTitle,
      borrowerType,
      borrowerId,
      borrowerName,
      borrowerPhone,
      dueDate: new Date(dueDate),
      remarks,
      issuedBy: req.adminId
    };

    if (borrowerType === 'student' && borrowerClass) {
      borrowData.borrowerClass = borrowerClass;
    }

    const borrow = new BookBorrow(borrowData);
    await borrow.save();

    // Update book quantity
    book.availableQuantity -= 1;
    await book.save();

    res.status(201).json({
      success: true,
      message: 'Book issued successfully',
      borrow
    });
  } catch (error) {
    console.log(error);
    res.status(400).json({ 
      success: false,
      message: 'Error issuing book', 
      error: error.message 
    });
  }
});

// POST return a book
Adminrouter.post('/book-borrows/return/:id', async (req, res) => {
  try {
    const { fine, remarks, condition } = req.body;
    
    const borrow = await BookBorrow.findById(req.params.id);
    
    if (!borrow) {
      return res.status(404).json({ 
        success: false,
        message: 'Borrow record not found' 
      });
    }

    if (borrow.status === 'Returned') {
      return res.status(400).json({ 
        success: false,
        message: 'Book already returned' 
      });
    }

    // Calculate fine if overdue
    const today = new Date();
    const dueDate = new Date(borrow.dueDate);
    let fineAmount = 0;
    
    if (today > dueDate && borrow.status !== 'Lost') {
      const daysOverdue = Math.ceil((today - dueDate) / (1000 * 60 * 60 * 24));
      fineAmount = daysOverdue * 5; // 5 taka per day
    }

    // Update borrow record
    borrow.returnDate = today;
    borrow.status = condition === 'Lost' ? 'Lost' : 'Returned';
    borrow.returnNotes = remarks;
    borrow.receivedBy = req.adminId;
    
    if (condition === 'Damaged') {
      borrow.condition = 'Damaged';
      borrow.conditionNotes = remarks;
    }
    
    if (condition === 'Lost') {
      borrow.condition = 'Lost';
      borrow.replacementCost = fine || 0;
    }

    // Set fine if applicable
    if (fineAmount > 0 || fine > 0) {
      borrow.fine = fine || fineAmount;
      borrow.finePaid = false;
    }

    await borrow.save();

    // Update book quantity (if not lost)
    if (condition !== 'Lost') {
      const book = await Book.findById(borrow.bookId);
      if (book) {
        book.availableQuantity += borrow.quantity || 1;
        await book.save();
      }
    }

    res.json({
      success: true,
      message: condition === 'Lost' ? 'Book marked as lost' : 'Book returned successfully',
      borrow
    });
  } catch (error) {
    res.status(400).json({ 
      success: false,
      message: 'Error returning book', 
      error: error.message 
    });
  }
});

// POST pay fine
Adminrouter.post('/book-borrows/pay-fine/:id', async (req, res) => {
  try {
    const { amount } = req.body;
    
    const borrow = await BookBorrow.findById(req.params.id);
    
    if (!borrow) {
      return res.status(404).json({ 
        success: false,
        message: 'Borrow record not found' 
      });
    }

    if (borrow.finePaid) {
      return res.status(400).json({ 
        success: false,
        message: 'Fine already paid' 
      });
    }

    borrow.finePaid = true;
    borrow.fine = amount || borrow.fine;
    
    await borrow.save();

    res.json({
      success: true,
      message: 'Fine paid successfully',
      borrow
    });
  } catch (error) {
    res.status(400).json({ 
      success: false,
      message: 'Error paying fine', 
      error: error.message 
    });
  }
});

// GET borrower history
Adminrouter.get('/book-borrows/borrower/:borrowerId', async (req, res) => {
  try {
    const { borrowerId } = req.params;
    const { page = 1, limit = 10 } = req.query;

    const borrows = await BookBorrow.find({ borrowerId })
      .populate('issuedBy', 'username')
      .populate('receivedBy', 'username')
      .sort({ createdAt: -1 })
      .limit(limit * 1)
      .skip((page - 1) * limit);

    const total = await BookBorrow.countDocuments({ borrowerId });

    // Get borrower info
    let borrowerInfo = null;
    const student = await Student.findOne({ studentId: borrowerId });
    if (student) {
      borrowerInfo = {
        type: 'student',
        name: `${student.firstName} ${student.lastName}`,
        class: student.class,
        section: student.section,
        phone: student.phone
      };
    } else {
      const teacher = await Teacher.findOne({ teacherId: borrowerId });
      if (teacher) {
        borrowerInfo = {
          type: 'teacher',
          name: `${teacher.firstName} ${teacher.lastName}`,
          department: teacher.department,
          phone: teacher.phone
        };
      }
    }

    res.json({
      success: true,
      borrows,
      borrowerInfo,
      totalPages: Math.ceil(total / limit),
      currentPage: page,
      total
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching borrower history', 
      error: error.message 
    });
  }
});

// GET library statistics
Adminrouter.get('/library-stats', async (req, res) => {
  try {
    const totalBooks = await Book.countDocuments();
    const availableBooks = await Book.aggregate([
      { $group: { _id: null, total: { $sum: '$availableQuantity' } } }
    ]);
    
    const activeBorrows = await BookBorrow.countDocuments({ 
      status: { $in: ['Borrowed', 'Overdue'] } 
    });
    
    const overdueBooks = await BookBorrow.countDocuments({ 
      status: 'Overdue' 
    });
    
    const todayReturns = await BookBorrow.countDocuments({
      dueDate: {
        $gte: new Date().setHours(0, 0, 0),
        $lt: new Date().setHours(23, 59, 59)
      },
      status: { $in: ['Borrowed', 'Overdue'] }
    });

    const totalFine = await BookBorrow.aggregate([
      { $match: { finePaid: false, fine: { $gt: 0 } } },
      { $group: { _id: null, total: { $sum: '$fine' } } }
    ]);

    res.json({
      success: true,
      stats: {
        totalBooks,
        availableBooks: availableBooks[0]?.total || 0,
        activeBorrows,
        overdueBooks,
        todayReturns,
        pendingFine: totalFine[0]?.total || 0
      }
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching library statistics', 
      error: error.message 
    });
  }
});

// DELETE borrow record (admin only)
Adminrouter.delete('/book-borrows/:id', async (req, res) => {
  try {
    const borrow = await BookBorrow.findById(req.params.id);
    
    if (!borrow) {
      return res.status(404).json({ 
        success: false,
        message: 'Borrow record not found' 
      });
    }

    // If book is still borrowed, update book quantity
    if (borrow.status === 'Borrowed' || borrow.status === 'Overdue') {
      const book = await Book.findById(borrow.bookId);
      if (book) {
        book.availableQuantity += borrow.quantity || 1;
        await book.save();
      }
    }

    await BookBorrow.findByIdAndDelete(req.params.id);

    res.json({ 
      success: true,
      message: 'Borrow record deleted successfully' 
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error deleting borrow record', 
      error: error.message 
    });
  }
});



// ==================== MARKS ROUTES ====================
const Marks = require('../models/Marks');

// Helper function to calculate overall grade
const calculateOverallGrade = (percentage) => {
  if (percentage >= 80) return 'A+';
  if (percentage >= 70) return 'A';
  if (percentage >= 60) return 'A-';
  if (percentage >= 50) return 'B';
  if (percentage >= 40) return 'C';
  if (percentage >= 33) return 'D';
  return 'F';
};

// GET all marks with filters (updated with month)
Adminrouter.get('/marks', async (req, res) => {
  try {
    const { 
      page = 1, 
      limit = 10, 
      search = '', 
      className = '', 
      section = '',
      examName = '',
      examYear = new Date().getFullYear(),
      gender = '',
      month = ''  // Added month filter
    } = req.query;
    
    const query = {};
    
    // Search by student name, roll no, or message
    if (search) {
      query.$or = [
        { studentName: { $regex: search, $options: 'i' } },
        { rollNo: { $regex: search, $options: 'i' } },
        { message: { $regex: search, $options: 'i' } },
        { remarks: { $regex: search, $options: 'i' } }
      ];
    }
    
    // Class filter
    if (className && className !== 'All' && className !== '') {
      query.className = className;
    }
    
    // Section filter
    if (section && section !== 'All' && section !== '') {
      query.section = section;
    }
    
    // Gender filter
    if (gender && gender !== 'All' && gender !== '') {
      query.gender = gender;
    }
    
    // Exam filter
    if (examName && examName !== 'All' && examName !== '') {
      query.examName = examName;
    }
    
    // Month filter (new)
    if (month && month !== 'All' && month !== '') {
      query.month = month;
    }
    
    // Year filter
    if (examYear && examYear !== 'All') {
      const startDate = new Date(parseInt(examYear), 0, 1);
      const endDate = new Date(parseInt(examYear), 11, 31, 23, 59, 59);
      query.examDate = { $gte: startDate, $lte: endDate };
    }

    const marks = await Marks.find(query)
      .populate('studentId', 'firstName lastName photo phone')
      .populate('createdBy', 'username')
      .sort({ examDate: -1, className: 1, rollNo: 1 })
      .limit(limit * 1)
      .skip((page - 1) * limit);

    const total = await Marks.countDocuments(query);

    // Get statistics (updated to include month aggregation)
    const stats = await Marks.aggregate([
      { $match: query },
      {
        $group: {
          _id: null,
          totalEntries: { $sum: 1 },
          averagePercentage: { $avg: { $avg: '$percentage' } },
          passedCount: {
            $sum: { 
              $cond: [
                { 
                  $and: [
                    { $gte: [{ $avg: '$percentage' }, 33] },
                    { $eq: ['$isAbsent', false] }
                  ]
                }, 
                1, 
                0
              ]
            }
          },
          absentCount: {
            $sum: { $cond: ['$isAbsent', 1, 0] }
          }
        }
      }
    ]);

    // Gender distribution
    const genderStats = await Marks.aggregate([
      { $match: query },
      {
        $group: {
          _id: '$gender',
          count: { $sum: 1 }
        }
      }
    ]);

    // Month distribution (new)
    const monthStats = await Marks.aggregate([
      { $match: query },
      {
        $group: {
          _id: '$month',
          count: { $sum: 1 },
          averageMarks: { $avg: '$obtainedMarks' }
        }
      },
      { $sort: { '_id': 1 } }
    ]);

    res.json({
      success: true,
      marks,
      totalPages: Math.ceil(total / limit),
      currentPage: page,
      total,
      stats: stats[0] || { totalEntries: 0, averagePercentage: 0, passedCount: 0, absentCount: 0 },
      genderStats,
      monthStats  // Added month statistics
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching marks', 
      error: error.message 
    });
  }
});

// GET mark by ID
Adminrouter.get('/marks/:id', async (req, res) => {
  try {
    const mark = await Marks.findById(req.params.id)
      .populate('studentId', 'firstName lastName photo phone admissionId')
      .populate('createdBy', 'username');
    
    if (!mark) {
      return res.status(404).json({ 
        success: false,
        message: 'Mark record not found' 
      });
    }

    res.json({
      success: true,
      mark
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching mark', 
      error: error.message 
    });
  }
});

// GET students for marks entry (with roll numbers and gender)
Adminrouter.get('/marks/students', async (req, res) => {
  try {
    const { className = '', section = '' } = req.query;
    
    if (!className) {
      return res.status(400).json({
        success: false,
        message: 'Class name is required'
      });
    }
    
    // Build student query
    const studentQuery = {};
    if (className && className !== 'All') {
      studentQuery.class = className;
    }
    if (section && section !== 'All' && section !== '') {
      studentQuery.section = section;
    }

    // Get students sorted by roll number
    const students = await Student.find(studentQuery)
      .select('firstName lastName class section roll studentId admissionId gender')
      .sort({ roll: 1 });

    // Format student data for marks entry
    const formattedStudents = students.map(student => ({
      studentId: student._id,
      rollNo: student.roll || '',
      studentName: `${student.firstName} ${student.lastName || ''}`.trim(),
      className: student.class,
      section: student.section || '',
      admissionNo: student.admissionId || '',
      studentIdNumber: student.studentId || '',
      gender: student.gender || ''
    }));

    res.json({
      success: true,
      students: formattedStudents,
      count: formattedStudents.length
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching students for marks entry', 
      error: error.message 
    });
  }
});

// POST create new mark entry (single subject) with gender and month
Adminrouter.post('/marks', async (req, res) => {
  try {
    const {
      studentId,
      studentName,
      rollNo,
      gender,
      className,
      section,
      examName,
      examDate,
      month,  // Added month field
      subjectName,
      totalMarks,
      obtainedMarks,
      isAbsent,
      message,
      remarks
    } = req.body;

    // Validate required fields
    if (!studentId || !studentName || !className || !examName || !subjectName || !totalMarks || !gender || !month) {
      return res.status(400).json({ 
        success: false, 
        message: 'Please fill all required fields including gender and month' 
      });
    }

    // Validate gender
    if (!['Male', 'Female', 'Other'].includes(gender)) {
      return res.status(400).json({
        success: false,
        message: 'Invalid gender value'
      });
    }

    // Validate month
    const validMonths = [
      'January', 'February', 'March', 'April', 'May', 'June',
      'July', 'August', 'September', 'October', 'November', 'December'
    ];
    if (!validMonths.includes(month)) {
      return res.status(400).json({
        success: false,
        message: 'Invalid month value'
      });
    }

    // Check if marks already exist for this student, exam, and subject
    const existingMark = await Marks.findOne({
      studentId,
      examName,
      subjectName,
      month,  // Added month to check
      examDate: examDate ? new Date(examDate) : undefined
    });

    if (existingMark) {
      return res.status(400).json({
        success: false,
        message: `Marks for ${subjectName} already exist for this student in ${month} ${examName ? 'for ' + examName : ''}`
      });
    }

    const markData = {
      studentId,
      studentName: studentName.trim(),
      rollNo: rollNo || '',
      gender,
      className,
      section: section || '',
      examName: examName.trim(),
      examDate: examDate ? new Date(examDate) : new Date(),
      month,  // Added month
      subjectName: subjectName.trim(),
      totalMarks: parseFloat(totalMarks),
      obtainedMarks: isAbsent ? 0 : parseFloat(obtainedMarks || 0),
      isAbsent: isAbsent || false,
      message: message || '',
      remarks: remarks || '',
      createdBy: req.adminId
    };

    const mark = new Marks(markData);
    await mark.save();

    res.status(201).json({
      success: true,
      message: 'Marks added successfully',
      mark
    });
  } catch (error) {
    console.log(error);
    res.status(400).json({ 
      success: false,
      message: 'Error adding marks', 
      error: error.message 
    });
  }
});

// POST bulk marks entry for multiple students/subjects with gender and month
Adminrouter.post('/marks/bulk', async (req, res) => {
  try {
    const { marksData } = req.body;
    
    if (!marksData || !marksData.length) {
      return res.status(400).json({
        success: false,
        message: 'Marks data is required'
      });
    }

    const results = [];
    const errors = [];

    for (const data of marksData) {
      try {
        const {
          studentId,
          studentName,
          rollNo,
          gender,
          className,
          section,
          examName,
          examDate,
          month,  // Added month
          subjectName,
          totalMarks,
          obtainedMarks,
          isAbsent,
          message,
          remarks
        } = data;

        // Validate gender
        if (!gender || !['Male', 'Female', 'Other'].includes(gender)) {
          errors.push({
            studentId,
            studentName,
            subjectName,
            error: 'Invalid or missing gender'
          });
          continue;
        }

        // Validate month
        const validMonths = [
          'January', 'February', 'March', 'April', 'May', 'June',
          'July', 'August', 'September', 'October', 'November', 'December'
        ];
        if (!month || !validMonths.includes(month)) {
          errors.push({
            studentId,
            studentName,
            subjectName,
            error: 'Invalid or missing month'
          });
          continue;
        }

        // Check if marks already exist
        const existingMark = await Marks.findOne({
          studentId,
          examName,
          subjectName,
          month,  // Added month
          examDate: examDate ? new Date(examDate) : undefined
        });

        if (existingMark) {
          errors.push({
            studentId,
            studentName,
            subjectName,
            error: 'Marks already exist'
          });
          continue;
        }

        const mark = new Marks({
          studentId,
          studentName,
          rollNo,
          gender,
          className,
          section,
          examName,
          examDate: examDate ? new Date(examDate) : new Date(),
          month,  // Added month
          subjectName,
          totalMarks: parseFloat(totalMarks),
          obtainedMarks: isAbsent ? 0 : parseFloat(obtainedMarks || 0),
          isAbsent: isAbsent || false,
          message: message || '',
          remarks: remarks || '',
          createdBy: req.adminId
        });

        await mark.save();
        results.push(mark);
      } catch (error) {
        errors.push({
          studentId: data.studentId,
          studentName: data.studentName,
          subjectName: data.subjectName,
          error: error.message
        });
      }
    }

    res.status(201).json({
      success: true,
      message: `Successfully added ${results.length} marks entries`,
      results,
      errors: errors.length > 0 ? errors : undefined
    });
  } catch (error) {
    res.status(400).json({ 
      success: false,
      message: 'Error bulk adding marks', 
      error: error.message 
    });
  }
});

// PUT update mark entry (including gender and month)
Adminrouter.put('/marks/:id', async (req, res) => {
  try {
    const {
      subjectName,
      totalMarks,
      obtainedMarks,
      isAbsent,
      gender,
      month,  // Added month
      message,
      remarks
    } = req.body;

    const mark = await Marks.findById(req.params.id);
    
    if (!mark) {
      return res.status(404).json({ 
        success: false,
        message: 'Mark record not found' 
      });
    }

    // Update fields
    if (subjectName) mark.subjectName = subjectName.trim();
    if (totalMarks) mark.totalMarks = parseFloat(totalMarks);
    if (obtainedMarks !== undefined) mark.obtainedMarks = parseFloat(obtainedMarks);
    if (isAbsent !== undefined) {
      mark.isAbsent = isAbsent;
      if (isAbsent) mark.obtainedMarks = 0;
    }
    if (gender && ['Male', 'Female', 'Other'].includes(gender)) {
      mark.gender = gender;
    }
    
    // Validate and update month
    const validMonths = [
      'January', 'February', 'March', 'April', 'May', 'June',
      'July', 'August', 'September', 'October', 'November', 'December'
    ];
    if (month && validMonths.includes(month)) {
      mark.month = month;
    }
    
    if (message !== undefined) mark.message = message;
    if (remarks !== undefined) mark.remarks = remarks;
    
    mark.updatedBy = req.adminId;

    await mark.save();

    res.json({
      success: true,
      message: 'Marks updated successfully',
      mark
    });
  } catch (error) {
    res.status(400).json({ 
      success: false,
      message: 'Error updating marks', 
      error: error.message 
    });
  }
});

// DELETE mark entry
Adminrouter.delete('/marks/:id', async (req, res) => {
  try {
    const mark = await Marks.findByIdAndDelete(req.params.id);
    
    if (!mark) {
      return res.status(404).json({ 
        success: false,
        message: 'Mark record not found' 
      });
    }

    res.json({ 
      success: true,
      message: 'Mark record deleted successfully' 
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error deleting mark record', 
      error: error.message 
    });
  }
});

// GET marks by student ID (with gender)
Adminrouter.get('/marks/student/:studentId', async (req, res) => {
  try {
    const { studentId } = req.params;
    const { examName, examYear, month } = req.query;  // Added month

    const query = { studentId };
    if (examName) query.examName = examName;
    if (month) query.month = month;  // Added month filter
    if (examYear) {
      const startDate = new Date(parseInt(examYear), 0, 1);
      const endDate = new Date(parseInt(examYear), 11, 31, 23, 59, 59);
      query.examDate = { $gte: startDate, $lte: endDate };
    }

    const marks = await Marks.find(query)
      .populate('studentId', 'firstName lastName photo phone')
      .sort({ examDate: -1, subjectName: 1 });

    // Get student gender from first mark
    const studentGender = marks.length > 0 ? marks[0].gender : '';

    // Group by exam and month
    const groupedMarks = marks.reduce((acc, mark) => {
      const examKey = `${mark.examName}_${mark.examDate}_${mark.month}`;
      if (!acc[examKey]) {
        acc[examKey] = {
          examName: mark.examName,
          examDate: mark.examDate,
          month: mark.month,
          subjects: []
        };
      }
      acc[examKey].subjects.push({
        subjectName: mark.subjectName,
        totalMarks: mark.totalMarks,
        obtainedMarks: mark.obtainedMarks,
        percentage: mark.percentage,
        grade: mark.grade,
        isAbsent: mark.isAbsent,
        message: mark.message
      });
      return acc;
    }, {});

    // Calculate totals for each exam
    const examResults = Object.values(groupedMarks).map(exam => {
      const totalObtained = exam.subjects.reduce((sum, sub) => sum + sub.obtainedMarks, 0);
      const totalPossible = exam.subjects.reduce((sum, sub) => sum + sub.totalMarks, 0);
      const overallPercentage = totalPossible > 0 ? (totalObtained / totalPossible) * 100 : 0;
      
      return {
        ...exam,
        totalObtained,
        totalPossible,
        overallPercentage: overallPercentage.toFixed(2),
        overallGrade: calculateOverallGrade(overallPercentage)
      };
    });

    res.json({
      success: true,
      marks: examResults,
      studentGender
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching student marks', 
      error: error.message 
    });
  }
});

// GET marks by class and exam (with gender stats and month)
Adminrouter.get('/marks/class/:className', async (req, res) => {
  try {
    const { className } = req.params;
    const { section, examName, examDate, subjectName, month } = req.query;  // Added month

    const query = { className };
    if (section && section !== 'All') query.section = section;
    if (examName) query.examName = examName;
    if (month) query.month = month;  // Added month filter
    if (examDate) {
      const startDate = new Date(examDate);
      startDate.setHours(0, 0, 0, 0);
      const endDate = new Date(examDate);
      endDate.setHours(23, 59, 59, 999);
      query.examDate = { $gte: startDate, $lte: endDate };
    }
    if (subjectName) query.subjectName = subjectName;

    const marks = await Marks.find(query)
      .populate('studentId', 'firstName lastName photo')
      .sort({ rollNo: 1 });

    // Calculate class statistics
    const stats = {
      totalStudents: marks.length,
      passedCount: marks.filter(m => !m.isAbsent && parseFloat(m.percentage) >= 33).length,
      failedCount: marks.filter(m => !m.isAbsent && parseFloat(m.percentage) < 33).length,
      absentCount: marks.filter(m => m.isAbsent).length,
      averageMarks: marks.reduce((sum, m) => sum + (m.isAbsent ? 0 : m.obtainedMarks), 0) / marks.length || 0,
      highestMarks: Math.max(...marks.map(m => m.isAbsent ? 0 : m.obtainedMarks), 0),
      lowestMarks: Math.min(...marks.map(m => m.isAbsent ? Infinity : m.obtainedMarks), Infinity)
    };

    // Gender-wise statistics
    const genderStats = {
      male: marks.filter(m => m.gender === 'Male').length,
      female: marks.filter(m => m.gender === 'Female').length,
      other: marks.filter(m => m.gender === 'Other').length
    };

    // Month statistics (new)
    const monthStats = marks.reduce((acc, mark) => {
      if (!acc[mark.month]) {
        acc[mark.month] = {
          count: 0,
          totalMarks: 0
        };
      }
      acc[mark.month].count++;
      acc[mark.month].totalMarks += mark.obtainedMarks;
      return acc;
    }, {});

    // Calculate averages for each month
    Object.keys(monthStats).forEach(month => {
      monthStats[month].average = (monthStats[month].totalMarks / monthStats[month].count).toFixed(2);
    });

    res.json({
      success: true,
      marks,
      stats,
      genderStats,
      monthStats  // Added month statistics
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching class marks', 
      error: error.message 
    });
  }
});

// GET marks summary/statistics (including gender and month breakdown)
Adminrouter.get('/marks-summary', async (req, res) => {
  try {
    const { examYear = new Date().getFullYear(), month } = req.query;  // Added month

    const startDate = new Date(parseInt(examYear), 0, 1);
    const endDate = new Date(parseInt(examYear), 11, 31, 23, 59, 59);

    const matchStage = {
      examDate: { $gte: startDate, $lte: endDate }
    };
    
    // Add month filter if provided
    if (month && month !== 'All') {
      matchStage.month = month;
    }

    const summary = await Marks.aggregate([
      {
        $match: matchStage
      },
      {
        $group: {
          _id: {
            className: '$className',
            examName: '$examName',
            month: '$month'  // Added month to grouping
          },
          totalStudents: { $sum: 1 },
          passedCount: {
            $sum: { 
              $cond: [
                { 
                  $and: [
                    { $gte: [{ $avg: '$percentage' }, 33] },
                    { $eq: ['$isAbsent', false] }
                  ]
                }, 
                1, 
                0
              ]
            }
          },
          absentCount: {
            $sum: { $cond: ['$isAbsent', 1, 0] }
          },
          averageMarks: { $avg: '$obtainedMarks' },
          highestMarks: { $max: '$obtainedMarks' },
          lowestMarks: { $min: '$obtainedMarks' }
        }
      },
      {
        $sort: { '_id.className': 1, '_id.month': 1, '_id.examName': 1 }
      }
    ]);

    // Overall statistics
    const overallStats = await Marks.aggregate([
      {
        $match: matchStage
      },
      {
        $group: {
          _id: null,
          totalEntries: { $sum: 1 },
          totalPassed: {
            $sum: { 
              $cond: [
                { 
                  $and: [
                    { $gte: [{ $avg: '$percentage' }, 33] },
                    { $eq: ['$isAbsent', false] }
                  ]
                }, 
                1, 
                0
              ]
            }
          },
          totalAbsent: { $sum: { $cond: ['$isAbsent', 1, 0] } },
          overallAverage: { $avg: '$obtainedMarks' }
        }
      }
    ]);

    // Gender breakdown
    const genderBreakdown = await Marks.aggregate([
      {
        $match: matchStage
      },
      {
        $group: {
          _id: '$gender',
          count: { $sum: 1 },
          averageMarks: { $avg: '$obtainedMarks' },
          passedCount: {
            $sum: { 
              $cond: [
                { 
                  $and: [
                    { $gte: [{ $avg: '$percentage' }, 33] },
                    { $eq: ['$isAbsent', false] }
                  ]
                }, 
                1, 
                0
              ]
            }
          }
        }
      }
    ]);

    // Monthly breakdown (new)
    const monthlyBreakdown = await Marks.aggregate([
      {
        $match: matchStage
      },
      {
        $group: {
          _id: '$month',
          count: { $sum: 1 },
          averageMarks: { $avg: '$obtainedMarks' },
          passedCount: {
            $sum: { 
              $cond: [
                { 
                  $and: [
                    { $gte: [{ $avg: '$percentage' }, 33] },
                    { $eq: ['$isAbsent', false] }
                  ]
                }, 
                1, 
                0
              ]
            }
          }
        }
      },
      {
        $sort: { '_id': 1 }
      }
    ]);

    res.json({
      success: true,
      summary,
      overall: overallStats[0] || { totalEntries: 0, totalPassed: 0, totalAbsent: 0, overallAverage: 0 },
      genderBreakdown,
      monthlyBreakdown,  // Added monthly breakdown
      year: examYear,
      month: month || 'All'
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching marks summary', 
      error: error.message 
    });
  }
});

// GET exam names list (distinct)
Adminrouter.get('/exam-names-list', async (req, res) => {
  try {
    const examNames = await Marks.distinct('examName');
    
    res.json({
      success: true,
      examNames: examNames.sort()
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching exam names', 
      error: error.message 
    });
  }
});

// GET subjects list (distinct)
Adminrouter.get('/subjects-list', async (req, res) => {
  try {
    const subjects = await Marks.distinct('subjectName');
    
    res.json({
      success: true,
      subjects: subjects.sort()
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching subjects', 
      error: error.message 
    });
  }
});

// GET months list (new route)
Adminrouter.get('/months-list', async (req, res) => {
  try {
    const months = [
      'January', 'February', 'March', 'April', 'May', 'June',
      'July', 'August', 'September', 'October', 'November', 'December'
    ];
    
    // Get months that have data
    const monthsWithData = await Marks.distinct('month');
    
    res.json({
      success: true,
      allMonths: months,
      monthsWithData: monthsWithData.sort()
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching months', 
      error: error.message 
    });
  }
});

// GET gender list for filter
Adminrouter.get('/gender-list', async (req, res) => {
  try {
    const genders = ['Male', 'Female', 'Other'];
    
    res.json({
      success: true,
      genders
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error fetching genders', 
      error: error.message 
    });
  }
});

// PATCH update message only
Adminrouter.patch('/marks/:id/message', async (req, res) => {
  try {
    const { message } = req.body;

    const mark = await Marks.findByIdAndUpdate(
      req.params.id,
      { message },
      { new: true, runValidators: true }
    );

    if (!mark) {
      return res.status(404).json({ 
        success: false,
        message: 'Mark record not found' 
      });
    }

    res.json({
      success: true,
      message: 'Message updated successfully',
      mark
    });
  } catch (error) {
    res.status(400).json({ 
      success: false,
      message: 'Error updating message', 
      error: error.message 
    });
  }
});

// GET marks by message content (search)
Adminrouter.get('/marks/search/message', async (req, res) => {
  try {
    const { text = '' } = req.query;
    
    const marks = await Marks.find({
      message: { $regex: text, $options: 'i' }
    })
    .populate('studentId', 'firstName lastName')
    .limit(50);

    res.json({
      success: true,
      marks,
      count: marks.length
    });
  } catch (error) {
    res.status(500).json({ 
      success: false,
      message: 'Error searching marks by message', 
      error: error.message 
    });
  }
});

module.exports = Adminrouter;