import express from "express";

import { requireAuth, requireRole } from "../../middleware/auth.js";
import { validate } from "../../shared/validate.js";
import { httpError } from "../../shared/errors.js";
import { LeaveRequest } from "./leave.model.js";
import { createLeaveSchema, decideLeaveSchema } from "./leave.schemas.js";

export const leaveRouter = express.Router();
leaveRouter.use(requireAuth);

leaveRouter.use((req, _res, next) => {
  if (req.user?.role === "customer") {
    return next(httpError(403, "Customers cannot access leave"));
  }
  return next();
});

leaveRouter.get("/me", async (req, res, next) => {
  try {
    const items = await LeaveRequest.find({ userId: req.user._id })
      .sort({ createdAt: -1 })
      .lean();
    res.json({ items });
  } catch (err) {
    next(err);
  }
});

leaveRouter.post("/", validate(createLeaveSchema), async (req, res, next) => {
  try {
    const { fromDate, toDate, reason } = req.validated.body;

    const doc = await LeaveRequest.create({
      userId: req.user._id,
      fromDate,
      toDate,
      reason,
      status: "pending",
    });

    res.status(201).json({ leaveRequest: doc });
  } catch (err) {
    next(err);
  }
});

leaveRouter.get("/", requireRole("admin"), async (req, res, next) => {
  try {
    const items = await LeaveRequest.find({})
      .populate("userId", "fullName email role")
      .populate("decidedBy", "fullName email")
      .sort({ createdAt: -1 })
      .lean();

    // Transform to include user data at top level
    const transformedItems = items.map((item) => ({
      ...item,
      userName: item.userId?.fullName || "Unknown",
      userEmail: item.userId?.email || "",
      userRole: item.userId?.role || "",
      decidedByName: item.decidedBy?.fullName || "",
    }));

    res.json({ items: transformedItems });
  } catch (err) {
    next(err);
  }
});

leaveRouter.patch(
  "/:id/decide",
  requireRole("admin"),
  validate(decideLeaveSchema),
  async (req, res, next) => {
    try {
      const { id } = req.validated.params;
      const { status } = req.validated.body;

      const doc = await LeaveRequest.findById(id);
      if (!doc) throw httpError(404, "Leave request not found");
      if (doc.status !== "pending") throw httpError(409, "Already decided");

      doc.status = status;
      doc.decidedBy = req.user._id;
      doc.decidedAt = new Date();

      await doc.save();
      res.json({ leaveRequest: doc });
    } catch (err) {
      next(err);
    }
  }
);
