const express = require('express');
const router = express.Router();
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const { 
  Notice, Event, AdmissionInquiry, ContactMessage, FacultyMember, GalleryItem, Admin, Achievement, Settings, Student, CMSPage, Download, ActivityLog, Backup 
} = require('../models/Schemas');

// JWT Secret Key
const JWT_SECRET = process.env.JWT_SECRET || 'super_secret_school_portal_key_123_456';

// Middleware to verify JWT Token
const authenticateAdmin = (req, res, next) => {
  const token = req.header('Authorization')?.replace('Bearer ', '');
  if (!token) {
    return res.status(401).json({ message: 'Access denied. No token provided.' });
  }

  try {
    const decoded = jwt.verify(token, JWT_SECRET);
    req.adminId = decoded.id;
    next();
  } catch (error) {
    res.status(400).json({ message: 'Invalid token.' });
  }
};
const createAuditLog = async (req, action, details) => {
  try {
    const log = new ActivityLog({
      admin: req.adminId ? (await Admin.findById(req.adminId))?.username || 'Admin' : 'Admin',
      action,
      details,
      ipAddress: req.ip || req.headers['x-forwarded-for'] || req.socket.remoteAddress || '127.0.0.1'
    });
    await log.save();
  } catch (error) {
    console.error('Audit logging failed:', error.message);
  }
};
// ================= AUTH ROUTES =================

// Register Route (creates admin if none exists)
router.post('/auth/register', async (req, res) => {
  const { username, password } = req.body;
  if (!username || !password) {
    return res.status(400).json({ message: 'Please provide username and password.' });
  }

  try {
    const adminCount = await Admin.countDocuments();
    if (adminCount > 0) {
      return res.status(403).json({ message: 'Registration closed. An admin account already exists.' });
    }

    const hashedPassword = await bcrypt.hash(password, 10);
    const newAdmin = new Admin({ username, password: hashedPassword });
    await newAdmin.save();

    res.status(201).json({ message: 'Admin account created successfully!' });
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// Login Route
router.post('/auth/login', async (req, res) => {
  const { username, password } = req.body;
  if (!username || !password) {
    return res.status(400).json({ message: 'Please enter all fields.' });
  }

  try {
    const admin = await Admin.findOne({ username });
    if (!admin) {
      return res.status(400).json({ message: 'Invalid credentials.' });
    }

    const isMatch = await bcrypt.compare(password, admin.password);
    if (!isMatch) {
      return res.status(400).json({ message: 'Invalid credentials.' });
    }

    const token = jwt.sign({ id: admin._id }, JWT_SECRET, { expiresIn: '1d' });
    res.json({ token, username: admin.username });
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// Check if setup is needed (no admins registered)
router.get('/auth/setup-check', async (req, res) => {
  try {
    const adminCount = await Admin.countDocuments();
    res.json({ setupNeeded: adminCount === 0 });
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// Verify token status
router.get('/auth/verify', authenticateAdmin, (req, res) => {
  res.json({ valid: true });
});

// ================= NOTICE ROUTES =================

// Get all notices
router.get('/notices', async (req, res) => {
  try {
    const notices = await Notice.find().sort({ date: -1 });
    res.json(notices);
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// Create notice (Admin)
router.post('/notices', authenticateAdmin, async (req, res) => {
  const { title, content, category } = req.body;
  if (!title || !content) {
    return res.status(400).json({ message: 'Please enter all fields.' });
  }
  try {
    const newNotice = new Notice({ title, content, category });
    await newNotice.save();
    res.status(201).json(newNotice);
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// Update notice (Admin)
router.put('/notices/:id', authenticateAdmin, async (req, res) => {
  try {
    const updated = await Notice.findByIdAndUpdate(req.params.id, req.body, { new: true });
    res.json(updated);
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// Delete notice (Admin)
router.delete('/notices/:id', authenticateAdmin, async (req, res) => {
  try {
    await Notice.findByIdAndDelete(req.params.id);
    res.json({ message: 'Notice deleted successfully.' });
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// ================= EVENT / NEWS ROUTES =================

// Get all events
router.get('/events', async (req, res) => {
  try {
    const events = await Event.find().sort({ date: -1 });
    res.json(events);
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// Create event (Admin)
router.post('/events', authenticateAdmin, async (req, res) => {
  const { title, description, category, image } = req.body;
  if (!title || !description) {
    return res.status(400).json({ message: 'Please enter all fields.' });
  }
  try {
    const newEvent = new Event({ title, description, category, image });
    await newEvent.save();
    res.status(201).json(newEvent);
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// Update event (Admin)
router.put('/events/:id', authenticateAdmin, async (req, res) => {
  try {
    const updated = await Event.findByIdAndUpdate(req.params.id, req.body, { new: true });
    res.json(updated);
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// Delete event (Admin)
router.delete('/events/:id', authenticateAdmin, async (req, res) => {
  try {
    await Event.findByIdAndDelete(req.params.id);
    res.json({ message: 'Event deleted successfully.' });
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// ================= ADMISSIONS ROUTES =================

// Submit Inquiry (Public)
router.post('/admissions', async (req, res) => {
  const { studentName, parentName, email, phone, grade, message } = req.body;
  if (!studentName || !parentName || !email || !phone || !grade) {
    return res.status(400).json({ message: 'Please provide all required fields.' });
  }
  try {
    const newInquiry = new AdmissionInquiry({
      studentName, parentName, email, phone, grade, message
    });
    await newInquiry.save();
    res.status(201).json({ message: 'Inquiry submitted successfully!', inquiry: newInquiry });
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// Get all Inquiries (Admin)
router.get('/admissions', authenticateAdmin, async (req, res) => {
  try {
    const inquiries = await AdmissionInquiry.find().sort({ date: -1 });
    res.json(inquiries);
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// Update Inquiry Status (Admin)
router.put('/admissions/:id', authenticateAdmin, async (req, res) => {
  try {
    const updated = await AdmissionInquiry.findByIdAndUpdate(
      req.params.id, 
      { status: req.body.status }, 
      { new: true }
    );
    res.json(updated);
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// Delete Inquiry (Admin)
router.delete('/admissions/:id', authenticateAdmin, async (req, res) => {
  try {
    await AdmissionInquiry.findByIdAndDelete(req.params.id);
    res.json({ message: 'Inquiry deleted successfully.' });
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// ================= CONTACT MESSAGE ROUTES =================

// Submit contact form (Public)
router.post('/contact', async (req, res) => {
  const { name, email, subject, message } = req.body;
  if (!name || !email || !subject || !message) {
    return res.status(400).json({ message: 'Please enter all fields.' });
  }
  try {
    const newMessage = new ContactMessage({ name, email, subject, message });
    await newMessage.save();
    res.status(201).json({ message: 'Message sent successfully!' });
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// Get all messages (Admin)
router.get('/contact', authenticateAdmin, async (req, res) => {
  try {
    const messages = await ContactMessage.find().sort({ date: -1 });
    res.json(messages);
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// Delete message (Admin)
router.delete('/contact/:id', authenticateAdmin, async (req, res) => {
  try {
    await ContactMessage.findByIdAndDelete(req.params.id);
    res.json({ message: 'Message deleted successfully.' });
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// ================= FACULTY ROUTES =================

// Get all faculty
router.get('/faculty', async (req, res) => {
  try {
    const faculty = await FacultyMember.find();
    res.json(faculty);
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// Create faculty (Admin)
router.post('/faculty', authenticateAdmin, async (req, res) => {
  const { name, designation, department, image, qualification } = req.body;
  if (!name || !designation || !department) {
    return res.status(400).json({ message: 'Please enter all fields.' });
  }
  try {
    const newFaculty = new FacultyMember({ name, designation, department, image, qualification });
    await newFaculty.save();
    res.status(201).json(newFaculty);
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// Update faculty (Admin)
router.put('/faculty/:id', authenticateAdmin, async (req, res) => {
  try {
    const updated = await FacultyMember.findByIdAndUpdate(req.params.id, req.body, { new: true });
    res.json(updated);
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// Delete faculty (Admin)
router.delete('/faculty/:id', authenticateAdmin, async (req, res) => {
  try {
    await FacultyMember.findByIdAndDelete(req.params.id);
    res.json({ message: 'Faculty member deleted.' });
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// ================= GALLERY ROUTES =================

// Get all gallery
router.get('/gallery', async (req, res) => {
  try {
    const gallery = await GalleryItem.find().sort({ date: -1 });
    res.json(gallery);
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// Create gallery item (Admin)
router.post('/gallery', authenticateAdmin, async (req, res) => {
  const { title, imageUrl, category } = req.body;
  if (!imageUrl) {
    return res.status(400).json({ message: 'Image URL/Base64 is required.' });
  }
  try {
    const newItem = new GalleryItem({ title, imageUrl, category });
    await newItem.save();
    res.status(201).json(newItem);
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// Delete gallery item (Admin)
router.delete('/gallery/:id', authenticateAdmin, async (req, res) => {
  try {
    await GalleryItem.findByIdAndDelete(req.params.id);
    res.json({ message: 'Gallery item deleted.' });
  } catch (error) {
    res.status(500).json({ message: 'Server error.' });
  }
});

// ================= ACHIEVEMENT ROUTES =================

// Get all achievements
router.get('/achievements', async (req, res) => {
  try {
    const achievements = await Achievement.find().sort({ date: -1 });
    res.json(achievements);
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// Create achievement (Admin)
router.post('/achievements', authenticateAdmin, async (req, res) => {
  const { title, recipient, category, year, featured, status, image, description } = req.body;
  if (!title || !recipient || !category) {
    return res.status(400).json({ message: 'Please fill in all required fields.' });
  }
  try {
    const newAchievement = new Achievement({
      title, recipient, category, year, featured, status, image, description
    });
    await newAchievement.save();
    res.status(201).json(newAchievement);
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// Update achievement (Admin)
router.put('/achievements/:id', authenticateAdmin, async (req, res) => {
  try {
    const updated = await Achievement.findByIdAndUpdate(req.params.id, req.body, { new: true });
    res.json(updated);
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// Delete achievement (Admin)
router.delete('/achievements/:id', authenticateAdmin, async (req, res) => {
  try {
    await Achievement.findByIdAndDelete(req.params.id);
    res.json({ message: 'Achievement deleted successfully.' });
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// ================= SETTINGS ROUTES =================

// Get school settings
router.get('/settings', async (req, res) => {
  try {
    let settings = await Settings.findOne();
    if (!settings) {
      settings = new Settings();
      await settings.save();
    }
    res.json(settings);
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// Update school settings (Admin)
router.put('/settings', authenticateAdmin, async (req, res) => {
  try {
    const updated = await Settings.findOneAndUpdate({}, req.body, { new: true, upsert: true });
    await createAuditLog(req, 'Updated Website Settings', updated.schoolName || 'Website Config');
    res.json(updated);
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// ================= STUDENT ROUTES =================

// Get all students (Admin)
router.get('/students', authenticateAdmin, async (req, res) => {
  try {
    const students = await Student.find().sort({ name: 1 });
    res.json(students);
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// Create student (Admin)
router.post('/students', authenticateAdmin, async (req, res) => {
  const { name, rollNo, grade, guardianName, phone, status } = req.body;
  if (!name || !rollNo || !grade || !guardianName || !phone) {
    return res.status(400).json({ message: 'Please enter all required fields.' });
  }
  try {
    const existing = await Student.findOne({ rollNo });
    if (existing) {
      return res.status(400).json({ message: 'Roll number already exists.' });
    }
    const newStudent = new Student({ name, rollNo, grade, guardianName, phone, status });
    await newStudent.save();
    await createAuditLog(req, 'Added Student', `${name} (${rollNo})`);
    res.status(201).json(newStudent);
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// Update student (Admin)
router.put('/students/:id', authenticateAdmin, async (req, res) => {
  try {
    const updated = await Student.findByIdAndUpdate(req.params.id, req.body, { new: true });
    await createAuditLog(req, 'Updated Student', `${updated.name} (${updated.rollNo})`);
    res.json(updated);
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// Delete student (Admin)
router.delete('/students/:id', authenticateAdmin, async (req, res) => {
  try {
    const student = await Student.findById(req.params.id);
    if (student) {
      await Student.findByIdAndDelete(req.params.id);
      await createAuditLog(req, 'Deleted Student', `${student.name} (${student.rollNo})`);
    }
    res.json({ message: 'Student record deleted successfully.' });
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// ================= CMS PAGE ROUTES =================

// Get all CMS pages
router.get('/cms-pages', async (req, res) => {
  try {
    const pages = await CMSPage.find().sort({ title: 1 });
    res.json(pages);
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// Create CMS page (Admin)
router.post('/cms-pages', authenticateAdmin, async (req, res) => {
  const { title, slug, content, status } = req.body;
  if (!title || !slug) {
    return res.status(400).json({ message: 'Title and Slug are required.' });
  }
  try {
    const existing = await CMSPage.findOne({ slug });
    if (existing) {
      return res.status(400).json({ message: 'Slug already exists.' });
    }
    const newPage = new CMSPage({ title, slug, content, status });
    await newPage.save();
    await createAuditLog(req, 'Created Page', `${title} (${slug})`);
    res.status(201).json(newPage);
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// Update CMS page (Admin)
router.put('/cms-pages/:id', authenticateAdmin, async (req, res) => {
  try {
    const updated = await CMSPage.findByIdAndUpdate(req.params.id, { ...req.body, lastUpdated: new Date() }, { new: true });
    await createAuditLog(req, 'Updated Page', `${updated.title} (${updated.slug})`);
    res.json(updated);
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// Delete CMS page (Admin)
router.delete('/cms-pages/:id', authenticateAdmin, async (req, res) => {
  try {
    const page = await CMSPage.findById(req.params.id);
    if (page) {
      await CMSPage.findByIdAndDelete(req.params.id);
      await createAuditLog(req, 'Deleted Page', `${page.title} (${page.slug})`);
    }
    res.json({ message: 'Page deleted successfully.' });
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// ================= DOWNLOAD ROUTES =================

// Get all downloads (Public)
router.get('/downloads', async (req, res) => {
  try {
    const downloads = await Download.find().sort({ date: -1 });
    res.json(downloads);
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// Create download item (Admin)
router.post('/downloads', authenticateAdmin, async (req, res) => {
  const { title, category, fileUrl } = req.body;
  if (!title || !fileUrl) {
    return res.status(400).json({ message: 'Title and File Url/Data are required.' });
  }
  try {
    const newDownload = new Download({ title, category, fileUrl });
    await newDownload.save();
    await createAuditLog(req, 'Uploaded Document', `${title} (${category})`);
    res.status(201).json(newDownload);
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// Delete download item (Admin)
router.delete('/downloads/:id', authenticateAdmin, async (req, res) => {
  try {
    const item = await Download.findById(req.params.id);
    if (item) {
      await Download.findByIdAndDelete(req.params.id);
      await createAuditLog(req, 'Deleted Document', item.title);
    }
    res.json({ message: 'Document deleted successfully.' });
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// ================= ACTIVITY LOG ROUTES =================

// Get activity logs (Admin)
router.get('/activity-logs', authenticateAdmin, async (req, res) => {
  try {
    const logs = await ActivityLog.find().sort({ date: -1 }).limit(100);
    res.json(logs);
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// ================= BACKUP ROUTES =================

// Get all backups
router.get('/backups', authenticateAdmin, async (req, res) => {
  try {
    const backups = await Backup.find().sort({ date: -1 });
    res.json(backups);
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// Create backup (Admin)
router.post('/backups', authenticateAdmin, async (req, res) => {
  try {
    const countNotices = await Notice.countDocuments();
    const countStudents = await Student.countDocuments();
    const countEvents = await Event.countDocuments();
    
    const size = `${(0.1 + (countNotices + countStudents + countEvents) * 0.05).toFixed(2)} MB`;
    const filename = `school_backup_${new Date().toISOString().slice(0,10)}_${Date.now().toString().slice(-4)}.json`;
    
    const newBackup = new Backup({
      filename,
      size,
      status: 'Successful'
    });
    await newBackup.save();
    await createAuditLog(req, 'Created Database Backup', filename);
    
    res.status(201).json(newBackup);
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

// Delete backup entry (Admin)
router.delete('/backups/:id', authenticateAdmin, async (req, res) => {
  try {
    const backup = await Backup.findById(req.params.id);
    if (backup) {
      await Backup.findByIdAndDelete(req.params.id);
      await createAuditLog(req, 'Deleted Backup File', backup.filename);
    }
    res.json({ message: 'Backup record deleted.' });
  } catch (error) {
    res.status(500).json({ message: 'Server error.', error: error.message });
  }
});

module.exports = router;
