<?php
/**
 * ============================================
 * FILE: includes/Emails/EmailManager.php
 *
 * This is the central brain of the email system.
 * It manages all email classes and coordinates email sending.
 * ============================================
 */

namespace RadiusTheme\RadiusBooking\Emails;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}
/**
 * EmailManager Class
 *
 * Purpose: Single point of control for all email operations
 * Pattern: Singleton (only one instance exists)
 *
 * Responsibilities:
 * 1. Load all email-related classes
 * 2. Register all email types
 * 3. Store references to all email instances
 * 4. Provide access to specific emails
 * 5. Initialize default settings
 * 6. Register WordPress hooks
 */
class EmailManager {


	/**
	 * ========================================
	 * REGISTERED EMAILS STORAGE
	 * ========================================
	 *
	 * This array stores all email class instances
	 *
	 * Structure:
	 * array(
	 *     'appointment_confirmed_customer' => AppointmentConfirmedCustomer object,
	 *     'appointment_pending_employee' => AppointmentPendingEmployee object,
	 *     ... etc
	 * )
	 *
	 * Access:
	 * $this->registered_emails['appointment_confirmed_customer']
	 *
	 * @return array Array of registered email instances
	 * @var array
	 */
	private $registered_emails = array();


	/**
	 * ========================================
	 * CONSTRUCTOR (Private)
	 * ========================================
	 *
	 * This runs ONCE when the singleton is first created
	 *
	 * Flow:
	 * 1. Load all required PHP class files
	 * 2. Register WordPress hooks (actions/filters)
	 *
	 * Private: Prevents external code from creating new instances
	 */
	public function __construct() {
		$this->load_dependencies();
		$this->register_hooks();
		$this->initialize_emails();
	}


	/**
	 * ========================================
	 * LOAD DEPENDENCIES
	 * ========================================
	 *
	 * Loads all required PHP files for the email system
	 *
	 * Flow:
	 * 1. Check if Action Scheduler exists
	 * 2. Load core classes (BaseEmail, EmailSender, etc.)
	 * 3. Load individual email classes (AppointmentConfirmed, etc.)
	 */
	private function load_dependencies() {
		// Safety check: Action Scheduler is required
		if ( ! class_exists( 'ActionScheduler' ) ) {
			add_action( 'admin_notices', array( $this, 'action_scheduler_notice' ) );
			return; // Stop loading if Action Scheduler missing
		}
		// Load individual email class files
		$this->load_email_classes();
	}
	/**
	 * ========================================
	 * LOAD EMAIL CLASS FILES
	 * ========================================
	 *
	 * Loads individual email class PHP files
	 *
	 * Process:
	 * 1. Get list of all email classes
	 * 2. Loop through each class name
	 * 3. Convert class name to file path
	 * 4. Require the file if it exists
	 *
	 * Example:
	 * Class: RadiusTheme\RadiusBooking\Emails\Customer\AppointmentConfirmed
	 * File:  includes/Emails/Customer/AppointmentConfirmed.php
	 */
	private function load_email_classes() {
		$email_classes = $this->get_email_classes();

		foreach ( $email_classes as $class ) {
			// Verify the class is available (autoloaded or already loaded).
			// Instances are created later in initialize_emails() to avoid
			// registering email hooks twice.
			class_exists( $class );
		}
	}


	/**
	 * ========================================
	 * ACTION SCHEDULER MISSING NOTICE
	 * ========================================
	 *
	 * Shows admin notice if Action Scheduler not found
	 */
	public function action_scheduler_notice() {
		?>
		<div class="notice notice-error">
			<p>
				<strong>Radius Booking Email System:</strong>
				This plugin requires Action Scheduler. Please install it first.
			</p>
		</div>
		<?php
	}
	/**
	 * ========================================
	 * REGISTER WordPress HOOKS
	 * ========================================
	 *
	 * Connects the email system to WordPress
	 *
	 * Hooks registered:
	 *
	 * 1. init - Initialize all email classes
	 * 2. plugins_loaded - Load translations
	 * 3. rtrb_send_queued_email - Process queued emails (Action Scheduler)
	 * 4. rtrb_send_reminder_email - Process reminder emails (Action Scheduler)
	 */
	private function register_hooks() {
		// Register Action Scheduler hooks for background processing
		add_action( 'rtrb_send_queued_email', array( $this, 'process_queued_email' ), 10, 2 );
		add_action( 'rtrb_send_reminder_email', array( $this, 'process_reminder_email' ), 10, 2 );
	}


	/**
	 * ========================================
	 * INITIALIZE EMAILS
	 * ========================================
	 *
	 * This is THE MOST IMPORTANT METHOD
	 *
	 * What it does:
	 * 1. Gets list of all email class names
	 * 2. Creates an instance of each email class
	 * 3. Stores the instance in $registered_emails array
	 * 4. Initializes default settings if not already saved
	 *
	 * When this runs:
	 * - On 'init' WordPress hook
	 * - Every page load (but classes are already loaded)
	 *
	 * Example flow:
	 * 1. Get class: RadiusTheme\RadiusBooking\Emails\Customer\AppointmentConfirmed
	 * 2. Create instance: new AppointmentConfirmed()
	 * 3. Get email ID: $email->get_id() returns 'appointment_confirmed_customer'
	 * 4. Store: $this->registered_emails['appointment_confirmed_customer'] = $email
	 * 5. Check settings: If no settings exist, create defaults
	 */
	public function initialize_emails() {
		$emails = $this->get_email_classes();

		foreach ( $emails as $email_class ) {
			// Check if class exists (file was loaded successfully)
			if ( class_exists( $email_class ) ) {

				// Create new instance of the email class
				// Example: new AppointmentConfirmed()
				$email = new $email_class();

				// Get the unique ID for this email
				// Example: 'appointment_confirmed_customer'
				$email_id = $email->get_id();

				// Store in our registry with ID as key
				$this->registered_emails[ $email_id ] = $email;

				// Initialize default settings if first time
				$this->maybe_initialize_settings( $email );
			}
		}
		// Allow other plugins to hook in after emails are registered
		do_action( 'rtrb_emails_initialized', $this->registered_emails );
	}


	/**
	 * ========================================
	 * INITIALIZE DEFAULT SETTINGS
	 * ========================================
	 *
	 * Saves default email settings to database if not already saved
	 *
	 * How it works:
	 * 1. Build option name: 'rtrb_email_' + email_id
	 * 2. Check if option exists in database
	 * 3. If not exists, save default settings from email class
	 *
	 * Example:
	 * Email ID: 'appointment_confirmed_customer'
	 * Option name: 'rtrb_email_appointment_confirmed_customer'
	 * Default settings: array(
	 *     'enabled' => true,
	 *     'subject' => 'Your appointment is confirmed',
	 *     'heading' => 'Appointment Confirmed!',
	 *     ... etc
	 * )
	 *
	 * Saved in: wp_options table
	 *
	 * @param object $email Email class instance
	 */
	public function maybe_initialize_settings( $email ) {
		$option_key = 'rtrb_email_' . $email->get_id();

		// Check if settings already exist
		if ( false === get_option( $option_key ) ) {
			// Get default settings from the email class
			$default_settings = $email->get_default_settings();

			// Save to database
			// false = don't autoload (not needed on every page)
			update_option( $option_key, $default_settings, false );
		}
	}


	/**
	 * ========================================
	 * GET EMAIL CLASSES LIST
	 * ========================================
	 *
	 * Returns array of all email class names
	 *
	 * This is where you ADD NEW EMAIL TYPES
	 *
	 * Format: Full namespace + class name
	 *
	 * Structure:
	 * Namespace\Type\ClassName
	 *
	 * Customer emails: RadiusTheme\RadiusBooking\Emails\Customer\*
	 * Employee emails: RadiusTheme\RadiusBooking\Emails\Employee\*
	 */
	public function get_email_classes() {
		// Define structure by recipient type
		$classes = array(
			'Customer' => array(
				'AppointmentConfirmed',
				'AppointmentCancelled',
				'AppointmentPending',
				'AppointmentCompleted',
				'AppointmentReminder',
				'MeetingConfirmed',
				'MeetingCancelled',
				'MeetingReminder',
				'EventRegistrationConfirmed',
				'EventRegistrationCancelled',
				'EventReminder',
			),
			'Employee' => array(
				'AppointmentConfirmed',
				'AppointmentRejected',
				'AppointmentPending',
				'AppointmentCancelled',
				'AppointmentReminder',
				'MeetingConfirmed',
				'MeetingCancelled',
				'MeetingReminder',
				'EventRegistrationConfirmed',
				'EventRegistrationCancelled',
				'EventReminder',
			),
			'Admin'    => array(
				'NewAppointment',
				'NewMeeting',
				'NewEvent',
			),
		);

		$baseNamespace = 'RadiusTheme\\RadiusBooking\\Emails\\';
		$emailClasses  = array();

		// Build dynamically
		foreach ( $classes as $role => $emails ) {
			foreach ( $emails as $email ) {
				$emailClasses[] = $baseNamespace . $role . '\\' . $email;
			}
		}

		return $emailClasses;
	}



	/**
	 * ========================================
	 * GET ALL REGISTERED EMAILS
	 * ========================================
	 *
	 * Returns the complete registry of email instances
	 *
	 * Usage:
	 * $all_emails = EmailManager::instance()->get_registered_emails();
	 * foreach ($all_emails as $id => $email) {
	 *     echo $email->get_title();
	 * }
	 *
	 * @return array Array of email instances
	 */
	public function get_registered_emails() {
		return $this->registered_emails;
	}


	/**
	 * ========================================
	 * GET SPECIFIC EMAIL BY ID
	 * ========================================
	 *
	 * Retrieves a single email instance by its ID
	 *
	 * Usage:
	 * $email = EmailManager::instance()->get_email('appointment_confirmed_customer');
	 * if ($email) {
	 *     $email->send($booking_id);
	 * }
	 *
	 * @param string $email_id The email ID
	 * @return object|null Email instance or null if not found
	 */
	public function get_email( $email_id ) {
		return isset( $this->registered_emails[ $email_id ] )
				? $this->registered_emails[ $email_id ]
				: null;
	}


	/**
	 * ========================================
	 * PROCESS QUEUED EMAIL
	 * ========================================
	 *
	 * Called by Action Scheduler to send queued emails
	 *
	 * Flow:
	 * 1. Action Scheduler triggers this method
	 * 2. Get the email instance by ID
	 * 3. Call the email's send() method
	 *
	 * @param string $email_id Email identifier
	 * @param array $email_data Email data (to, merge_tags, etc.)
	 */
	public function process_queued_email( $email_id, $email_data ) {
		$email = $this->get_email( $email_id );

		if ( $email ) {
			return $email->send( $email_data );
		}

		return false;
	}


	/**
	 * ========================================
	 * PROCESS REMINDER EMAIL
	 * ========================================
	 *
	 * Called by Action Scheduler to send reminder emails
	 * Same as process_queued_email but for reminders
	 *
	 * @param string $email_id string Email identifier
	 * @param array $email_data Email data (to, merge_tags, etc.)
	 */
	public function process_reminder_email( $email_id, $email_data ) {
		return $this->process_queued_email( $email_id, $email_data );
	}
}