import Rental from "../models/Rental.js";
import Car from "../models/Car.js";

// Get all rentals (admin sees all, client sees only own)
export const getAllRentals = async (req, res) => {
  try {
    const { search, status, page = 1, limit = 10 } = req.query;

    let query = {};

    // If client, only show their rentals
    if (req.role === "client") {
      query.client = req.userId;
    }

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

    const skip = (parseInt(page) - 1) * parseInt(limit);

    const rentals = await Rental.find(query)
      .populate("client", "fullName email phone")
      .populate("car", "plateNumber brand model dailyRate")
      .skip(skip)
      .limit(parseInt(limit))
      .sort({ createdAt: -1 });

    const total = await Rental.countDocuments(query);

    res.json({
      rentals,
      total,
      page: parseInt(page),
      pages: Math.ceil(total / parseInt(limit))
    });
  } catch (error) {
    console.error("Get all rentals error:", error);
    res.status(500).json({ message: "Server error" });
  }
};

// Get single rental
export const getRental = async (req, res) => {
  try {
    const rental = await Rental.findById(req.params.id)
      .populate("client", "fullName email phone")
      .populate("car", "plateNumber brand model dailyRate");

    if (!rental) {
      return res.status(404).json({ message: "Rental not found" });
    }

    // Check if client is trying to access someone else's rental
    if (req.role === "client" && rental.client._id.toString() !== req.userId) {
      return res.status(403).json({ message: "Access denied" });
    }

    res.json(rental);
  } catch (error) {
    console.error("Get rental error:", error);
    res.status(500).json({ message: "Server error" });
  }
};

// Create rental
export const createRental = async (req, res) => {
  try {
    const { carId, expectedReturnDate } = req.body;

    // Check if car exists
    const car = await Car.findById(carId);
    if (!car) {
      return res.status(404).json({ message: "Car not found" });
    }

    // Check if car is available
    if (car.status !== "available") {
      return res.status(400).json({ message: "Car is not available for rental" });
    }

    // Check for existing active rental for this car
    const existingRental = await Rental.findOne({ car: carId, status: "active" });
    if (existingRental) {
      return res.status(400).json({ message: "Car is already rented" });
    }

    const rentalDate = new Date();
    const expectedReturn = new Date(expectedReturnDate);

    // Calculate total amount
    const rentalDays = Math.ceil((expectedReturn - rentalDate) / (1000 * 60 * 60 * 24)) || 1;
    const totalAmount = car.dailyRate * rentalDays;

    const rental = new Rental({
      client: req.userId,
      car: carId,
      rentalDate,
      expectedReturnDate: expectedReturn,
      totalAmount,
      status: "active"
    });

    await rental.save();

    // Update car status to rented
    car.status = "rented";
    await car.save();

    const populatedRental = await Rental.findById(rental._id)
      .populate("client", "fullName email phone")
      .populate("car", "plateNumber brand model dailyRate");

    res.status(201).json({ message: "Rental created successfully", rental: populatedRental });
  } catch (error) {
    console.error("Create rental error:", error);
    res.status(500).json({ message: "Server error" });
  }
};

// Return rental
export const returnRental = async (req, res) => {
  try {
    const rental = await Rental.findById(req.params.id);

    if (!rental) {
      return res.status(404).json({ message: "Rental not found" });
    }

    // Check if client is trying to return someone else's rental
    if (req.role === "client" && rental.client.toString() !== req.userId) {
      return res.status(403).json({ message: "Access denied" });
    }

    // Check if already returned
    if (rental.status === "returned") {
      return res.status(400).json({ message: "Rental already returned" });
    }

    const actualReturnDate = new Date();

    // Calculate actual rental days and update total
    const rentalDays = Math.ceil((actualReturnDate - rental.rentalDate) / (1000 * 60 * 60 * 24)) || 1;
    const car = await Car.findById(rental.car);
    const totalAmount = car.dailyRate * rentalDays;

    rental.actualReturnDate = actualReturnDate;
    rental.totalAmount = totalAmount;
    rental.status = "returned";

    await rental.save();

    // Update car status to available
    car.status = "available";
    await car.save();

    const populatedRental = await Rental.findById(rental._id)
      .populate("client", "fullName email phone")
      .populate("car", "plateNumber brand model dailyRate");

    res.json({ message: "Car returned successfully", rental: populatedRental });
  } catch (error) {
    console.error("Return rental error:", error);
    res.status(500).json({ message: "Server error" });
  }
};

// Delete rental
export const deleteRental = async (req, res) => {
  try {
    const rental = await Rental.findById(req.params.id);

    if (!rental) {
      return res.status(404).json({ message: "Rental not found" });
    }

    // If rental is active, make car available again
    if (rental.status === "active") {
      await Car.findByIdAndUpdate(rental.car, { status: "available" });
    }

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

    res.json({ message: "Rental deleted successfully" });
  } catch (error) {
    console.error("Delete rental error:", error);
    res.status(500).json({ message: "Server error" });
  }
};