const express = require("express")
const jwt = require("jsonwebtoken")
const User = require("../../models/User")
const Batch = require("../../models/Batch")
const requireAuth = require("../../middleware/requireAuth")

const rateLimit = require("express-rate-limit")

const limiter = rateLimit({
  windowMs: 10 * 60 * 1000,
  max: 5,
  message: "Too many signup attempts. Try again later"
})

const router = express.Router()

// ================= ADMIN SIGNUP =================
router.post("/admin/signup", async (req, res) => {
  try {
    const { name, email, password } = req.body

    const exists = await User.findOne({ email })
    if (exists) {
      return res.status(400).json({ message: "Admin already exists" })
    }

    const bcrypt = require("bcrypt")

    const hashed = await bcrypt.hash(password, 10)

    const admin = await User.create({
      name,
      email,
      password: hashed,
      role: "admin",
      registrationType: "admin"
    })

    res.status(201).json({
      message: "Admin created",
      admin: {
        id: admin._id,
        email: admin.email
      }
    })
  } catch (error) {
    console.error("ADMIN SIGNUP ERROR ->", error)
    res.status(500).json({ message: "Admin signup failed" })
  }
})

// ================= ADMIN LOGIN =================
router.post("/admin/login", async (req, res) => {
  try {
    const { email, password } = req.body

    const user = await User.findOne({ email, role: "admin" })
    if (!user) {
      return res.status(401).json({ message: "Admin not found" })
    }

    const isMatch = await user.comparePassword(password)
    if (!isMatch) {
      return res.status(401).json({ message: "Invalid credentials" })
    }

    const token = jwt.sign(
      { id: user._id, role: user.role },
      process.env.JWT_SECRET,
      { expiresIn: "7d" }
    )

    res.json({
      token,
      admin: {
        id: user._id,
        email: user.email,
        role: user.role
      }
    })
  } catch (error) {
    console.error("ADMIN LOGIN ERROR ->", error)
    res.status(500).json({ message: "Login failed" })
  }
})

// ================= CREATE ACCOUNT REQUEST =================
router.post("/create-account", limiter, async (req, res) => {
  try {
    const { name, email, password } = req.body

    if (!email.endsWith("@gmail.com")) {
      return res.status(403).json({
        message: "Only Gmail accounts are allowed"
      })
    }

    const exists = await User.findOne({ email })
    if (exists) {
      return res.status(400).json({ message: "Account already requested" })
    }

    const bcrypt = require("bcrypt")

    const hashed = await bcrypt.hash(password, 10)

    await User.create({
      name,
      email,
      password: hashed,
      role: "student",
      status: "pending",
      registrationType: req.headers["x-admin"] ? "admin" : "web"
    })

    res.status(201).json({
      message: "Account request sent. Wait for admin approval."
    })
  } catch (error) {
    console.error("CREATE ACCOUNT ERROR ->", error)
    res.status(500).json({ message: "Account request failed" })
  }
})

// ================= STUDENT LOGIN =================
router.post("/login", async (req, res) => {
  try {
    const { email, password } = req.body

    const user = await User.findOne({ email, role: "student" })
    if (!user) {
      return res.status(401).json({ message: "Invalid credentials" })
    }

    if (user.status === "pending") {
      return res.status(403).json({
        message: "Account waiting for admin approval"
      })
    }

    if (user.status === "frozen") {
      return res.status(403).json({
        message: "Account is blocked by admin"
      })
    }

    const match = await user.comparePassword(password)

    console.log("ENTERED:", password)
    console.log("HASHED:", user.password)
    console.log("MATCH:", match)

    if (!match) {
      return res.status(401).json({ message: "Invalid credentials" })
    }

    const token = jwt.sign(
      { id: user._id, role: user.role },
      process.env.JWT_SECRET,
      { expiresIn: "7d" }
    )

    res.json({
      token,
      user: {
        _id: user._id,
        name: user.name,
        email: user.email,
        class: user.class || null,
        stream: user.stream || null,
        goal: user.goal || null,
        profileCompleted: user.profileCompleted || false
      }
    })
  } catch (error) {
    console.error("STUDENT LOGIN ERROR ->", error)
    res.status(500).json({ message: "Login failed" })
  }
})

router.post("/update-profile", requireAuth, async (req, res) => {
  try {
    const { class: studentClass, stream, goal } = req.body

    const user = await User.findById(req.user.id)

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

    // Step 1: Save class
    if (studentClass) {
      user.class = studentClass

      if (studentClass === "Class 9" || studentClass === "Class 10") {
        user.profileCompleted = true
      }
    }

    // Step 2: Save stream
    if (stream) {
      user.stream = stream
      user.profileCompleted = true
    }

    await user.save()

    if (goal) {
      user.goal = goal

      const batch = await Batch.findOne({
        class: user.class,
        stream: user.stream,
        goal: goal,
        isArchive: true
      })

      if (batch) {
        user.batch = batch._id
      }
    }

    res.json({
      message: "Profile updated successfully"
    })

  } catch (error) {
    console.error("UPDATE PROFILE ERROR ->", error)
    res.status(500).json({ message: "Profile update failed" })
  }
})

router.get("/me", requireAuth, async (req, res) => {
  try {
    const user = await User.findById(req.user.id)
      .select("-password")
      .populate("batch", "name class")
      .populate("purchasedCourses", "name class")

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

    res.json(user)
  } catch (error) {
    console.error("GET PROFILE ERROR ->", error)
    res.status(500).json({ message: "Failed to fetch profile" })
  }
})

module.exports = router
