const { Rental, Item, User } = require("../models");
const emailServices = require("./email");
const { isActive } = require("../utils/rentalStatus");
const logger = require("../utils/logger");

class LateReturnService {
  /**
   * Calculate late fees based on actual return time vs scheduled end time
   * @param {Object} rental - Rental instance with populated item data
   * @param {Date} actualReturnDateTime - When the item was actually returned
   * @returns {Object} - { lateHours, lateFee, isLate }
   */
  static calculateLateFee(rental, actualReturnDateTime) {
    const scheduledEnd = new Date(rental.endDateTime);
    const actualReturn = new Date(actualReturnDateTime);

    // Calculate hours late
    const hoursLate = (actualReturn - scheduledEnd) / (1000 * 60 * 60);

    if (hoursLate <= 0) {
      return {
        lateHours: 0,
        lateFee: 0.0,
        isLate: false,
      };
    }

    let lateFee = 0;
    let pricingType = "daily";
    const billableDays = Math.ceil(hoursLate / 24);

    // Calculate late fees per day, deriving daily rate from available pricing tiers
    if (rental.item?.pricePerDay && rental.item.pricePerDay > 0) {
      // Daily pricing - charge per day late
      lateFee = billableDays * parseFloat(rental.item.pricePerDay);
    } else if (rental.item?.pricePerWeek && rental.item.pricePerWeek > 0) {
      // Weekly pricing - derive daily rate and charge per day late
      const dailyRate = parseFloat(rental.item.pricePerWeek) / 7;
      lateFee = billableDays * dailyRate;
    } else if (rental.item?.pricePerMonth && rental.item.pricePerMonth > 0) {
      // Monthly pricing - derive daily rate and charge per day late
      const dailyRate = parseFloat(rental.item.pricePerMonth) / 30;
      lateFee = billableDays * dailyRate;
    } else if (rental.item?.pricePerHour && rental.item.pricePerHour > 0) {
      // Hourly pricing - derive daily rate and charge per day late
      const dailyRate = parseFloat(rental.item.pricePerHour) * 24;
      lateFee = billableDays * dailyRate;
    } else {
      // Free borrows - charge $10 per day late
      lateFee = billableDays * 10.0;
    }

    return {
      lateHours: hoursLate,
      lateFee: parseFloat(lateFee.toFixed(2)),
      isLate: true,
      pricingType,
    };
  }

  /**
   * Process late return and update rental with fees
   * @param {string} rentalId - Rental ID
   * @param {Date} actualReturnDateTime - When item was returned
   * @returns {Object} - Updated rental with late fee information
   */
  static async processLateReturn(rentalId, actualReturnDateTime) {
    const rental = await Rental.findByPk(rentalId, {
      include: [{ model: Item, as: "item" }],
    });

    if (!rental) {
      throw new Error("Rental not found");
    }

    if (!isActive(rental)) {
      throw new Error("Can only process late returns for active rentals");
    }

    const lateCalculation = this.calculateLateFee(rental, actualReturnDateTime);

    const updates = {
      actualReturnDateTime: new Date(actualReturnDateTime),
      status: lateCalculation.isLate ? "returned_late" : "completed",
      payoutStatus: "pending",
    };

    const updatedRental = await rental.update(updates);

    // Send notification to customer service if late return detected
    if (lateCalculation.isLate && lateCalculation.lateFee > 0) {
      // Fetch owner and renter user data for email
      const owner = await User.findByPk(updatedRental.ownerId);
      const renter = await User.findByPk(updatedRental.renterId);

      await emailServices.customerService.sendLateReturnToCustomerService(
        updatedRental,
        owner,
        renter,
        lateCalculation
      );
    }

    // Trigger immediate payout if rental is verified to be actually completed not late
    if (!lateCalculation.isLate) {
      // Import here to avoid circular dependency
      const PayoutService = require("./payoutService");
      PayoutService.triggerPayoutOnCompletion(rentalId).catch((err) => {
        logger.error("Error triggering payout on late return processing", {
          rentalId,
          error: err.message,
        });
      });
    }

    return {
      rental: updatedRental,
      lateCalculation,
    };
  }
}

module.exports = LateReturnService;
