const EmailClient = require("../core/EmailClient");
const TemplateManager = require("../core/TemplateManager");
const logger = require("../../../utils/logger");

/**
 * CustomerServiceEmailService handles all customer service alert emails
 * This service is responsible for:
 * - Sending late return notifications to CS team
 * - Sending damage report notifications to CS team
 * - Sending lost item notifications to CS team
 */
class CustomerServiceEmailService {
  constructor() {
    this.emailClient = new EmailClient();
    this.templateManager = new TemplateManager();
    this.initialized = false;
  }

  /**
   * Initialize the customer service email service
   * @returns {Promise<void>}
   */
  async initialize() {
    if (this.initialized) return;

    await Promise.all([
      this.emailClient.initialize(),
      this.templateManager.initialize(),
    ]);

    this.initialized = true;
    logger.info("Customer Service Email Service initialized successfully");
  }

  /**
   * Send late return notification to customer service
   * @param {Object} rental - Rental object
   * @param {number} rental.id - Rental ID
   * @param {Date} rental.endDateTime - Scheduled end date/time
   * @param {Date} rental.actualReturnDateTime - Actual return date/time
   * @param {Object} rental.item - Item object with name property
   * @param {Object} owner - Owner user object
   * @param {string} owner.firstName - Owner's first name
   * @param {string} owner.lastName - Owner's last name
   * @param {string} owner.email - Owner's email
   * @param {Object} renter - Renter user object
   * @param {string} renter.firstName - Renter's first name
   * @param {string} renter.lastName - Renter's last name
   * @param {string} renter.email - Renter's email
   * @param {Object} lateCalculation - Late fee calculation
   * @param {number} lateCalculation.lateHours - Hours late
   * @param {number} lateCalculation.lateFee - Late fee amount
   * @returns {Promise<{success: boolean, messageId?: string, error?: string}>}
   */
  async sendLateReturnToCustomerService(rental, owner, renter, lateCalculation) {
    if (!this.initialized) {
      await this.initialize();
    }

    try {
      const csEmail = process.env.CUSTOMER_SUPPORT_EMAIL;
      if (!csEmail) {
        logger.warn("No customer service email configured");
        return { success: false, error: "No customer service email configured" };
      }

      // Format dates
      const scheduledEnd = new Date(rental.endDateTime).toLocaleString();
      const actualReturn = new Date(rental.actualReturnDateTime).toLocaleString();

      const variables = {
        rentalId: rental.id,
        itemName: rental.item.name,
        ownerName: `${owner.firstName} ${owner.lastName}`,
        ownerEmail: owner.email,
        renterName: `${renter.firstName} ${renter.lastName}`,
        renterEmail: renter.email,
        scheduledEnd,
        actualReturn,
        hoursLate: lateCalculation.lateHours.toFixed(1),
        lateFee: lateCalculation.lateFee.toFixed(2),
      };

      const htmlContent = await this.templateManager.renderTemplate(
        "lateReturnToCS",
        variables
      );

      const result = await this.emailClient.sendEmail(
        csEmail,
        "Late Return Detected - Action Required",
        htmlContent
      );

      if (result.success) {
        logger.info(
          `Late return notification sent to customer service for rental ${rental.id}`
        );
      }

      return result;
    } catch (error) {
      logger.error(
        "Failed to send late return notification to customer service:",
        error
      );
      return { success: false, error: error.message };
    }
  }

  /**
   * Send damage report notification to customer service
   * @param {Object} rental - Rental object
   * @param {number} rental.id - Rental ID
   * @param {Object} rental.item - Item object with name property
   * @param {Object} owner - Owner user object
   * @param {string} owner.firstName - Owner's first name
   * @param {string} owner.lastName - Owner's last name
   * @param {string} owner.email - Owner's email
   * @param {Object} renter - Renter user object
   * @param {string} renter.firstName - Renter's first name
   * @param {string} renter.lastName - Renter's last name
   * @param {string} renter.email - Renter's email
   * @param {Object} damageAssessment - Damage assessment details
   * @param {string} damageAssessment.description - Damage description
   * @param {boolean} damageAssessment.canBeFixed - Whether item can be repaired
   * @param {number} [damageAssessment.repairCost] - Repair cost if applicable
   * @param {boolean} damageAssessment.needsReplacement - Whether item needs replacement
   * @param {number} [damageAssessment.replacementCost] - Replacement cost if applicable
   * @param {Object} damageAssessment.feeCalculation - Fee calculation details
   * @param {string} damageAssessment.feeCalculation.type - Fee type (repair/replacement)
   * @param {number} damageAssessment.feeCalculation.amount - Fee amount
   * @param {Array} [damageAssessment.proofOfOwnership] - Proof of ownership documents
   * @param {Object} [lateCalculation] - Late fee calculation (optional)
   * @param {number} [lateCalculation.lateFee] - Late fee amount
   * @returns {Promise<{success: boolean, messageId?: string, error?: string}>}
   */
  async sendDamageReportToCustomerService(
    rental,
    owner,
    renter,
    damageAssessment,
    lateCalculation = null
  ) {
    if (!this.initialized) {
      await this.initialize();
    }

    try {
      const csEmail = process.env.CUSTOMER_SUPPORT_EMAIL;
      if (!csEmail) {
        logger.warn("No customer service email configured");
        return { success: false, error: "No customer service email configured" };
      }

      // Calculate total fees (ensure numeric values)
      const damageFee = parseFloat(damageAssessment.feeCalculation.amount) || 0;
      const lateFee = parseFloat(lateCalculation?.lateFee || 0);
      const totalFees = damageFee + lateFee;

      // Determine fee type description
      let feeTypeDescription = "";
      if (damageAssessment.feeCalculation.type === "repair") {
        feeTypeDescription = "Repair Cost";
      } else if (damageAssessment.feeCalculation.type === "replacement") {
        feeTypeDescription = "Replacement Cost";
      } else {
        feeTypeDescription = "Damage Assessment Fee";
      }

      const variables = {
        rentalId: rental.id,
        itemName: rental.item.name,
        ownerName: `${owner.firstName} ${owner.lastName}`,
        ownerEmail: owner.email,
        renterName: `${renter.firstName} ${renter.lastName}`,
        renterEmail: renter.email,
        damageDescription: damageAssessment.description,
        canBeFixed: damageAssessment.canBeFixed ? "Yes" : "No",
        repairCost: damageAssessment.repairCost
          ? damageAssessment.repairCost.toFixed(2)
          : "N/A",
        needsReplacement: damageAssessment.needsReplacement ? "Yes" : "No",
        replacementCost: damageAssessment.replacementCost
          ? damageAssessment.replacementCost.toFixed(2)
          : "N/A",
        feeTypeDescription,
        damageFee: damageFee.toFixed(2),
        lateFee: lateFee.toFixed(2),
        totalFees: totalFees.toFixed(2),
        hasProofOfOwnership:
          damageAssessment.proofOfOwnership &&
          damageAssessment.proofOfOwnership.length > 0
            ? "Yes"
            : "No",
      };

      const htmlContent = await this.templateManager.renderTemplate(
        "damageReportToCS",
        variables
      );

      const result = await this.emailClient.sendEmail(
        csEmail,
        "Damage Report Filed - Action Required",
        htmlContent
      );

      if (result.success) {
        logger.info(
          `Damage report notification sent to customer service for rental ${rental.id}`
        );
      }

      return result;
    } catch (error) {
      logger.error(
        "Failed to send damage report notification to customer service:",
        error
      );
      return { success: false, error: error.message };
    }
  }

  /**
   * Send lost item notification to customer service
   * @param {Object} rental - Rental object
   * @param {number} rental.id - Rental ID
   * @param {Date} rental.endDateTime - Scheduled return date
   * @param {Date} rental.itemLostReportedAt - When loss was reported
   * @param {Object} rental.item - Item object
   * @param {string} rental.item.name - Item name
   * @param {number} rental.item.replacementCost - Item replacement cost
   * @param {Object} owner - Owner user object
   * @param {string} owner.firstName - Owner's first name
   * @param {string} owner.lastName - Owner's last name
   * @param {string} owner.email - Owner's email
   * @param {Object} renter - Renter user object
   * @param {string} renter.firstName - Renter's first name
   * @param {string} renter.lastName - Renter's last name
   * @param {string} renter.email - Renter's email
   * @returns {Promise<{success: boolean, messageId?: string, error?: string}>}
   */
  async sendLostItemToCustomerService(rental, owner, renter) {
    if (!this.initialized) {
      await this.initialize();
    }

    try {
      const csEmail = process.env.CUSTOMER_SUPPORT_EMAIL;
      if (!csEmail) {
        logger.warn("No customer service email configured");
        return { success: false, error: "No customer service email configured" };
      }

      // Format dates
      const reportedAt = new Date(rental.itemLostReportedAt).toLocaleString();
      const scheduledReturnDate = new Date(rental.endDateTime).toLocaleString();

      const variables = {
        rentalId: rental.id,
        itemName: rental.item.name,
        ownerName: `${owner.firstName} ${owner.lastName}`,
        ownerEmail: owner.email,
        renterName: `${renter.firstName} ${renter.lastName}`,
        renterEmail: renter.email,
        reportedAt,
        scheduledReturnDate,
        replacementCost: parseFloat(rental.item.replacementCost).toFixed(2),
      };

      const htmlContent = await this.templateManager.renderTemplate(
        "lostItemToCS",
        variables
      );

      const result = await this.emailClient.sendEmail(
        csEmail,
        "Lost Item Claim Filed - Action Required",
        htmlContent
      );

      if (result.success) {
        logger.info(
          `Lost item notification sent to customer service for rental ${rental.id}`
        );
      }

      return result;
    } catch (error) {
      logger.error(
        "Failed to send lost item notification to customer service:",
        error
      );
      return { success: false, error: error.message };
    }
  }
}

module.exports = CustomerServiceEmailService;
