<?php
/**
 * ============================================
 * FILE: includes/Emails/Customer/EventRegistrationConfirmed.php
 * Customer Event Registration Confirmed Email
 * ============================================
 */

namespace RadiusTheme\RadiusBooking\Emails\Customer;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}
use RadiusTheme\RadiusBooking\Abstracts\BaseEmail;
use RadiusTheme\RadiusBooking\Models\Appointment;
use RadiusTheme\RadiusBooking\Models\Event;
use RadiusTheme\RadiusBooking\Models\EventRegistration;
use RadiusTheme\RadiusBooking\Models\EventTicketType;
use RadiusTheme\RadiusBooking\Resources\AppointmentResource;

/**
 * Class EventRegistrationConfirmed
 *
 * Handles the "Event Registration Confirmed" email notification sent to customers.
 *
 * @package RadiusTheme\RadiusBooking\Emails\Customer
 */
class EventRegistrationConfirmed extends BaseEmail {

	/**
	 * Constructor to initialize the email properties.
	 */
	public function __construct() {
		$this->id             = 'customer_event_registration_confirmed';
		$this->title          = __( 'Event Registration Confirmed - Customer', 'radius-booking' );
		$this->description    = __( 'Sent to customers when their event registration is confirmed', 'radius-booking' );
		$this->tooltip        = __( 'This email is sent automatically when a customer registers for an event', 'radius-booking' );
		$this->recipient_type = 'customer';
		$this->template_html  = 'customer/event-registration-confirmed.php';
		$this->status         = 'confirmed';

		parent::__construct();
	}

	/**
	 * Get the unique identifier for the email.
	 *
	 * @return string
	 */
	public function get_id() {
		return $this->id;
	}

	/**
	 * Get the trigger action for the email.
	 *
	 * @return string
	 */
	public function get_trigger_action() {
		return 'radius_booking_event_registered';
	}

	/**
	 * Get the default email notification settings for event registration confirmation.
	 *
	 * @return array The default email settings.
	 */
	public function get_default_settings() {
		return array(
			'enabled'            => true,
			'subject'            => __( 'Registration Confirmed - {event_name}', 'radius-booking' ),
			'heading'            => __( 'Your Registration is Confirmed!', 'radius-booking' ),
			'additional_content' => __( "Hi {customer_name},\n\nGreat news! Your registration for {event_name} has been confirmed.\n\nWe look forward to seeing you on {event_date} at {event_time}.", 'radius-booking' ),
			'footer_text'        => __( 'If you need to cancel your registration, please do so as soon as possible.', 'radius-booking' ),
			'button_text'        => '',
			'button_url'         => '',
			'use_queue'          => false,
			'cc_staff'           => false,
			'bcc_emails'         => array(),
			'attachments'        => array(),
		);
	}

	/**
	 * Prepare the email data for sending.
	 *
	 * @param array $args The arguments passed to the email trigger.
	 * @return array|false The prepared email data or false on failure.
	 */
	protected function prepare_email_data( $args ) {
		if ( empty( $args[0] ) ) {
			return false;
		}

		$registration_or_id = $args[0];

		// The hook passes an EventRegistration object; extract the appointment_id from it.
		if ( is_object( $registration_or_id ) && isset( $registration_or_id->appointment_id ) ) {
			$appointment_id = (int) $registration_or_id->appointment_id;
			$registration   = $registration_or_id;
		} else {
			$appointment_id = (int) $registration_or_id;
			$registration   = null;
		}

		$booking = $this->get_booking( $appointment_id );
		if ( ! $booking ) {
			return false;
		}

		$appointment = Appointment::find( $appointment_id );
		$event       = $this->get_event( $appointment );

		if ( ! $registration ) {
			$registration = $this->get_registration( $appointment );
		}

		$ticket_type = $registration ? $this->get_ticket_type( $registration ) : null;

		// Get recipient email
		$to       = $booking['customer']->customer_info['email'];
		$customer = $booking['customer']->customer_info;

		// Prepare merge tags
		$merge_tags = array(
			'customer_name'       => $customer['name'],
			'customer_email'      => $customer['email'],
			'staff_name'          => $booking['employee_name'],
			'event_name'          => $event ? $event->name : '',
			'event_date'          => $event ? date_i18n( 'l, F j, Y', strtotime( $event->start_date ) ) : '',
			'event_time'          => $event ? date_i18n( 'g:i A', strtotime( $event->start_time ) ) : '',
			'event_location'      => $event ? $this->get_event_location( $event ) : '',
			'ticket_name'         => $ticket_type ? $ticket_type->name : '',
			'registration_number' => $registration ? $registration->registration_number : '',
			'ticket_quantity'     => $registration ? $registration->quantity : 1,
			'all_tickets'         => $this->get_all_tickets( $appointment_id ),
			'selected_sessions'   => $this->get_selected_sessions( $registration, $event ),
			'status'              => $booking['status'],
			'booking_url'         => $this->get_booking_url( $booking['id'] ),
		);

		// Add CC if needed
		$cc = array();
		if ( $this->settings['cc_staff'] && ! empty( $booking['employee_email'] ) ) {
			$cc[] = $booking['employee_email'];
		}

		return array(
			'to'          => $to,
			'cc'          => $cc,
			'bcc'         => isset( $this->settings['bcc_emails'] ) ? $this->settings['bcc_emails'] : array(),
			'merge_tags'  => $merge_tags,
			'data'        => $booking,
			'attachments' => array(),
		);
	}

	/**
	 * Retrieve and transform the booking data for the given appointment ID.
	 *
	 * @param int|null $appointment_id The appointment ID.
	 * @return array|null The transformed booking data or null if not found.
	 */
	private function get_booking( $appointment_id = null ) {
		$appointment = Appointment::find( $appointment_id );

		return ( new AppointmentResource() )->transform( $appointment );
	}

	/**
	 * Get the event from the appointment.
	 *
	 * @param Appointment|null $appointment The appointment.
	 * @return Event|null The event or null.
	 */
	private function get_event( $appointment ) {
		if ( $appointment && ! empty( $appointment->event_id ) ) {
			return Event::find( $appointment->event_id );
		}

		return null;
	}

	/**
	 * Get the event registration from the appointment.
	 *
	 * @param Appointment|null $appointment The appointment.
	 * @return EventRegistration|null The registration or null.
	 */
	private function get_registration( $appointment ) {
		if ( ! $appointment ) {
			return null;
		}

		return EventRegistration::where( 'appointment_id', $appointment->id )->first();
	}

	/**
	 * Get the ticket type from the registration.
	 *
	 * @param EventRegistration $registration The registration.
	 * @return EventTicketType|null The ticket type or null.
	 */
	private function get_ticket_type( $registration ) {
		if ( ! empty( $registration->ticket_type_id ) ) {
			return EventTicketType::find( $registration->ticket_type_id );
		}

		return null;
	}

	/**
	 * Get the event location string.
	 *
	 * @param Event $event The event.
	 * @return string The location string.
	 */
	private function get_event_location( $event ) {
		if ( ! empty( $event->location_type ) ) {
			switch ( $event->location_type ) {
				case 'online':
					return ! empty( $event->location_value ) ? $event->location_value : __( 'Online', 'radius-booking' );
				case 'physical':
					return ! empty( $event->location_value ) ? $event->location_value : __( 'In Person', 'radius-booking' );
				default:
					return ! empty( $event->location_value ) ? $event->location_value : '';
			}
		}

		return '';
	}

	/**
	 * Get the booking URL for the customer.
	 *
	 * @param int $booking_id The booking ID.
	 * @return string The booking URL.
	 */
	private function get_booking_url( $booking_id ) {
		return get_site_url() . '/my-bookings/' . $booking_id;
	}

	/**
	 * Get selected session names from a registration.
	 *
	 * @param object|null $registration The registration.
	 * @param object|null $event        The event.
	 *
	 * @return string Comma-separated session names.
	 */
	/**
	 * Get all ticket registrations for an appointment.
	 *
	 * @param int $appointment_id The appointment ID.
	 * @return array Array of ticket details.
	 */
	private function get_all_tickets( $appointment_id ) {
		$regs    = EventRegistration::where( 'appointment_id', (int) $appointment_id )->get();
		$tickets = array();
		foreach ( $regs as $reg ) {
			$tt        = ! empty( $reg->ticket_type_id ) ? EventTicketType::find( (int) $reg->ticket_type_id ) : null;
			$tickets[] = array(
				'name'                => $tt ? $tt->name : 'Ticket',
				'quantity'            => (int) ( $reg->quantity ?? 1 ),
				'price'               => $tt ? (float) $tt->price : 0,
				'registration_number' => $reg->registration_number ?? '',
			);
		}
		return $tickets;
	}

	private function get_selected_sessions( $registration, $event ) {
		if ( ! $registration || ! $event ) {
			return '';
		}

		$attendee_data = $registration->attendee_info ?? array();
		if ( is_string( $attendee_data ) ) {
			$attendee_data = json_decode( $attendee_data, true ) ?: array();
		}

		$session_ids = $attendee_data['sessions'] ?? array();
		if ( empty( $session_ids ) ) {
			return '';
		}

		$sessions      = \RadiusTheme\RadiusBooking\Models\EventSession::where( 'event_id', (int) $event->id )->get();
		$session_names = array();
		foreach ( $sessions as $s ) {
			if ( in_array( (int) $s->id, $session_ids, true ) ) {
				$session_names[] = $s->name;
			}
		}

		return implode( ', ', $session_names );
	}
}
