const express = require("express");
const requireAdmin = require("../../middleware/requireAdmin");
const router = express.Router();
router.use(requireAdmin);
const Batch = require("../../models/Batch");
const Course = require("../../models/Course");
const User = require("../../models/User");

const multer = require("multer")

const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, "uploads/")
  },
  filename: (req, file, cb) => {
    cb(null, Date.now() + "-" + file.originalname)
  }
})

const upload = multer({ storage })

router.post("/batches", upload.single("thumbnail"), async (req, res) => {
  try {

    const batchData = {
      ...req.body,
      thumbnail: req.file ? req.file.filename : ""
    }

    const batch = await Batch.create(batchData)

    res.status(201).json(batch)

  } catch (error) {
    res.status(400).json({
      message: "Failed to create batch",
      error: error.message
    })
  }
})

router.get("/batches", async (req, res) => {
  try {
    const batches = await Batch.find({
      $or: [
        { isArchived: false },
        { isArchived: { $exists: false } }
      ]
    })
      .populate("courses")
      .sort({ createdAt: -1 });
    
    const batchesWithStudents = await Promise.all(
      batches.map(async (batch) => {
        const students = await User.find({ batch: batch._id })
          .select("name class");

        return {
          ...batch.toObject(),
          students
        };
      })
    );

    res.json(batchesWithStudents);

  } catch (error) {
    res.status(500).json({
      message: "Failed to fetch batches",
      error: error.message
    });
  }
});

router.patch("/batches/:id/archive", async (req, res) => {
  try{
    const batch = await Batch.findById(req.params.id)

    if (!batch) {
      return res.status(404).json({ message: "Batch not found" })
    }

    const updated = await Batch.findByIdAndUpdate(
      req.params.id,
      { isArchived: !batch.isArchived},
      { new: true }
    )

    res.json(updated)
  } catch (error) {
    res.status(500).json({
      message:"Failed to archive batch",
      error: error.message
    })
  }
})

router.put("/batches/:id/courses", async (req, res) => {
  try {

    const { courses } = req.body

    const batch = await Batch.findById(req.params.id)

    if (!batch) {
      return res.status(404).json({
        message: "Batch not found"
      })
    }

    batch.courses = courses

    await batch.save()

    res.json({
      message: "Courses assigned successfully",
      batch
    })

  } catch (error) {
    res.status(500).json({
      message: "Failed to assign courses",
      error: error.message
    })
  }
})

router.get("/batches/:id/courses", async (req, res) => {
  try {

    const batch = await Batch.findById(req.params.id)

    if (!batch) {
      return res.status(404).json({ message: "Batch not found" })
    }

    const courses = await Course.find({
      isFrozen: false,
      isActive: true,
      isArchived: false
    }).select("name class")

    res.json({
      batchCourses: batch.courses || [],
      allCourses: courses
    })

  } catch (error) {
    res.status(500).json({
      message: "Failed to fetch courses",
      error: error.message
    })
  }
})

router.put("/batches/:id", upload.single("thumbnail"), async (req, res) => {
  try {

    const updateData = {
      ...req.body
    }

    if (req.file) {
      updateData.thumbnail = req.file.filename
    }

    const batch = await Batch.findByIdAndUpdate(
      req.params.id,
      updateData,
      { new: true }
    )

    res.json(batch)

  } catch (error) {
    res.status(500).json({
      message: "Failed to update batch",
      error: error.message
    })
  }
})

router.delete("/batches/:id", async (req, res) => {
  try{
    const deleted = await Batch.findByIdAndDelete(req.params.id)

    if (!deleted) {
      return res.status(404).json({ message: "Batch not found" })
    }

    res.json({ message: "Batch permanently deleted" })
  } catch (error) {
    res.status(500).json({
      message: "Failed to delete batch ",
      error: error.message
    })
  }
})

router.get("/batches/archived", async (req, res) => {
  try{
    const batches = await Batch.find({ isArchived: true })
    res.json(batches)
  } catch (error) {
    res.status(500).json({
      message: "Failed to fetch archived batches",
      error: error.message
    })
  }
})

module.exports = router;
