const path = require("path");
const {
  SchedulerClient,
  DeleteScheduleCommand,
} = require("@aws-sdk/client-scheduler");
const { queries, email, logger } = require("../shared");
const { conditionCheckExists } = require("./queries");

let schedulerClient = null;

/**
 * Get or create an EventBridge Scheduler client.
 */
function getSchedulerClient() {
  if (!schedulerClient) {
    schedulerClient = new SchedulerClient({
      region: process.env.AWS_REGION || "us-east-1",
    });
  }
  return schedulerClient;
}

/**
 * Delete a one-time EventBridge schedule after it has fired.
 * @param {string} scheduleName - Name of the schedule to delete
 */
async function deleteSchedule(scheduleName) {
  try {
    const client = getSchedulerClient();
    const groupName =
      process.env.SCHEDULE_GROUP_NAME || "condition-check-reminders";

    await client.send(
      new DeleteScheduleCommand({
        Name: scheduleName,
        GroupName: groupName,
      })
    );

    logger.info("Deleted schedule after execution", {
      scheduleName,
      groupName,
    });
  } catch (error) {
    // Log but don't fail - schedule may have already been deleted
    logger.warn("Failed to delete schedule", {
      scheduleName,
      error: error.message,
    });
  }
}

/**
 * Get email content based on check type.
 * @param {string} checkType - Type of condition check
 * @param {Object} rental - Rental with item, owner, renter details
 * @returns {Object} Email content (subject, title, message, recipient)
 */
function getEmailContent(checkType, rental) {
  const itemName = rental.item.name;
  const frontendUrl = process.env.FRONTEND_URL;

  const content = {
    pre_rental_owner: {
      recipient: rental.owner,
      subject: `Condition Check Reminder: ${itemName}`,
      title: "Pre-Rental Condition Check",
      message: `Please take photos of "${itemName}" before the rental begins tomorrow. This helps protect both you and the renter.`,
      deadline: email.formatEmailDate(rental.startDateTime),
    },
    rental_start_renter: {
      recipient: rental.renter,
      subject: `Document Item Condition: ${itemName}`,
      title: "Rental Start Condition Check",
      message: `Please take photos when you receive "${itemName}" to document its condition. This protects you in case of any disputes.`,
      deadline: email.formatEmailDate(
        new Date(new Date(rental.startDateTime).getTime() + 24 * 60 * 60 * 1000)
      ),
    },
    rental_end_renter: {
      recipient: rental.renter,
      subject: `Return Condition Check: ${itemName}`,
      title: "Rental End Condition Check",
      message: `Please take photos when returning "${itemName}" to document its condition before handoff.`,
      deadline: email.formatEmailDate(rental.endDateTime),
    },
    post_rental_owner: {
      recipient: rental.owner,
      subject: `Review Return: ${itemName}`,
      title: "Post-Rental Condition Check",
      message: `Please take photos and mark the return status for "${itemName}". This completes the rental process.`,
      deadline: email.formatEmailDate(
        new Date(new Date(rental.endDateTime).getTime() + 48 * 60 * 60 * 1000)
      ),
    },
  };

  return content[checkType];
}

/**
 * Process a condition check reminder.
 * @param {string} rentalId - UUID of the rental
 * @param {string} checkType - Type of condition check
 * @param {string} scheduleName - Name of the EventBridge schedule (for cleanup)
 * @returns {Promise<Object>} Result of the operation
 */
async function processReminder(rentalId, checkType, scheduleName) {
  logger.info("Processing condition check reminder", {
    rentalId,
    checkType,
    scheduleName,
  });

  try {
    // 1. Check if condition check already exists (skip if yes)
    const exists = await conditionCheckExists(rentalId, checkType);
    if (exists) {
      logger.info("Condition check already exists, skipping reminder", {
        rentalId,
        checkType,
      });

      // Still delete the schedule
      if (scheduleName) {
        await deleteSchedule(scheduleName);
      }

      return { success: true, skipped: true, reason: "condition_check_exists" };
    }

    // 2. Fetch rental details
    const rental = await queries.getRentalWithDetails(rentalId);
    if (!rental) {
      logger.error("Rental not found", { rentalId });
      return { success: false, error: "rental_not_found" };
    }

    // 3. Check rental status - only send for active rentals
    const validStatuses = ["confirmed", "active", "completed"];
    if (!validStatuses.includes(rental.status)) {
      logger.info("Rental status not valid for reminder", {
        rentalId,
        status: rental.status,
      });

      if (scheduleName) {
        await deleteSchedule(scheduleName);
      }

      return { success: true, skipped: true, reason: "invalid_rental_status" };
    }

    // 4. Get email content and send
    const emailContent = getEmailContent(checkType, rental);
    if (!emailContent) {
      logger.error("Unknown check type", { checkType });
      return { success: false, error: "unknown_check_type" };
    }

    // 5. Load and render the email template
    const templatePath = path.join(
      __dirname,
      "templates",
      "conditionCheckReminderToUser.html"
    );
    const template = await email.loadTemplate(templatePath);

    const htmlBody = email.renderTemplate(template, {
      title: emailContent.title,
      message: emailContent.message,
      itemName: rental.item.name,
      deadline: emailContent.deadline,
      recipientName: emailContent.recipient.firstName,
    });

    // 6. Send the email
    const result = await email.sendEmail(
      emailContent.recipient.email,
      emailContent.subject,
      htmlBody
    );

    if (!result.success) {
      logger.error("Failed to send reminder email", {
        rentalId,
        checkType,
        error: result.error,
      });
      return { success: false, error: result.error };
    }

    logger.info("Sent condition check reminder", {
      rentalId,
      checkType,
      to: emailContent.recipient.email,
      messageId: result.messageId,
    });

    // 7. Delete the one-time schedule
    if (scheduleName) {
      await deleteSchedule(scheduleName);
    }

    return { success: true, messageId: result.messageId };
  } catch (error) {
    logger.error("Error processing condition check reminder", {
      rentalId,
      checkType,
      error: error.message,
      stack: error.stack,
    });

    return { success: false, error: error.message };
  }
}

module.exports = {
  processReminder,
  getEmailContent,
  deleteSchedule,
};
