<?php
/**
 * ============================================
 * FILE: includes/Emails/Admin/NewEvent.php
 * Admin New Event Registration Email
 * ============================================
 *
 * @package RadiusTheme\RadiusBooking\Emails\Admin
 */

namespace RadiusTheme\RadiusBooking\Emails\Admin;

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 NewEvent
 *
 * Handles the "New Event Registration" email notification sent to admin when
 * a new event booking is created.
 *
 * @package RadiusTheme\RadiusBooking\Emails\Admin
 */
class NewEvent extends BaseEmail {

	/**
	 * Constructor to initialize the email properties.
	 */
	public function __construct() {
		$this->id             = 'admin_new_event';
		$this->title          = __( 'New Event Registration - Admin', 'radius-booking' );
		$this->description    = __( 'Sent to admin when a new event registration is created', 'radius-booking' );
		$this->tooltip        = __( 'This email is sent automatically to the admin when any new event registration is created in the system', 'radius-booking' );
		$this->recipient_type = 'admin';
		$this->template_html  = 'admin/new-event.php';
		$this->status         = 'created';
		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_booking_created';
	}

	/**
	 * Get the default email notification settings for new event bookings.
	 *
	 * @return array
	 */
	public function get_default_settings() {
		return array(
			'enabled'            => true,
			'subject'            => __( 'New Event Registration - {event_name}', 'radius-booking' ),
			'heading'            => __( 'New Event Registration', 'radius-booking' ),
			'additional_content' => __( "Hello Admin,\n\nA new event registration has been created in the system.\n\nPlease review the details below.", 'radius-booking' ),
			'footer_text'        => __( 'You can manage this event registration from the admin dashboard.', 'radius-booking' ),
			'button_text'        => '',
			'button_url'         => '',
			'use_queue'          => false,
			'admin_emails'       => array( get_option( 'admin_email' ) ),
			'bcc_emails'         => array(),
			'attachments'        => array(),
			'include_calendar'   => false,
		);
	}

	/**
	 * Prepare email data for sending the new event notification.
	 *
	 * @param array $args The arguments passed to the trigger action.
	 *
	 * @return array|false The prepared email data or false if booking not found
	 *                     or booking is not an event.
	 */
	protected function prepare_email_data( $args ) {
		$booking_id     = is_object( $args[0] ) ? $args[0]->id : $args[0];
		$appointment_id = is_object( $args[0] ) ? $args[0]->get_appointment_id() : null;
		$booking        = $this->get_booking( $appointment_id );

		if ( ! $booking ) {
			return false;
		}

		// Only handle event bookings. The stored booking_type for an event is
		// 'event' (set explicitly in EventRegistrationService); service rows
		// fall through to the DB column default 'service_booking'.
		$booking_type = $booking['booking_type'] ?? 'service_booking';
		if ( 'event' !== $booking_type ) {
			return false;
		}

		// Get admin emails from settings or default to site admin.
		$admin_emails = isset( $this->settings['admin_emails'] ) && ! empty( $this->settings['admin_emails'] )
			? $this->settings['admin_emails']
			: array( get_option( 'admin_email' ) );

		$to = is_array( $admin_emails ) ? implode( ',', $admin_emails ) : $admin_emails;

		$customer     = $booking['customer']->customer_info;
		$get_currency = get_rtrb_currency_symbol();

		$event   = ! empty( $booking['event_id'] ) ? Event::find( $booking['event_id'] ) : null;
		$tickets = $this->get_all_tickets( $appointment_id );

		$ticket_count = 0;
		foreach ( $tickets as $t ) {
			$ticket_count += (int) $t['quantity'];
		}

		// Event total. Order: dynamic-pricing snapshot → original ticket sum
		// (price × quantity) → payment.total_amount as a last resort.
		// Avoid using payment.total_amount as the primary source because it is
		// post-discount and post-tax — making the displayed total inconsistent
		// with the per-ticket prices listed alongside it.
		if ( ! empty( $booking['dynamic_pricing']['final_price'] ) ) {
			$payment_total = (float) $booking['dynamic_pricing']['final_price'];
		} elseif ( ! empty( $tickets ) ) {
			$payment_total = 0;
			foreach ( $tickets as $t ) {
				$payment_total += (float) $t['price'] * (int) $t['quantity'];
			}
		} else {
			$payment_total = isset( $booking['payment']->total_amount ) ? (float) $booking['payment']->total_amount : 0;
		}

		$merge_tags = array(
			'admin_name'         => 'Admin',
			'site_name'          => get_bloginfo( 'name' ),
			'customer_name'      => $customer['name'] ?? '',
			'customer_email'     => $customer['email'] ?? '',
			'customer_phone'     => $customer['phone'] ?? '',
			'event_name'         => $booking['event_name'] ?? ( $event ? $event->name : '' ),
			'event_date'         => $event && ! empty( $event->start_date ) ? date_i18n( 'l, F j, Y', strtotime( $event->start_date ) ) : '',
			'event_end_date'     => $event && ! empty( $event->end_date ) ? date_i18n( 'l, F j, Y', strtotime( $event->end_date ) ) : '',
			'event_time'         => $event && ! empty( $event->start_time ) ? date_i18n( 'g:i A', strtotime( $event->start_time ) ) : '',
			'event_end_time'     => $event && ! empty( $event->end_time ) ? date_i18n( 'g:i A', strtotime( $event->end_time ) ) : '',
			'event_location'     => $event ? $this->get_event_location( $event ) : '',
			'event_location_type' => $event ? ( $event->location_type ?? '' ) : '',
			'timezone'           => $event && ! empty( $event->timezone ) ? $event->timezone : wp_timezone_string(),
			'booking_id'         => $booking['customer']->id ?? '',
			'ticket_count'       => $ticket_count,
			'total_price'        => $get_currency . number_format( (float) $payment_total, 2 ),
			'status'             => $booking['status'] ?? 'Pending',
			'notes'              => $booking['notes'] ?? '',
			'booking_url'        => admin_url( 'admin.php?page=radius-bookings&booking_id=' . ( $booking['customer']->id ?? '' ) ),
			'all_bookings_url'   => admin_url( 'admin.php?page=radius-bookings' ),
		);

		// Attach tickets and event onto the booking array so the template can
		// render them without re-querying.
		$booking['event_tickets'] = $tickets;
		$booking['event_object']  = $event;

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

	/**
	 * Retrieve booking details and transform them into a resource format.
	 *
	 * @param int|null $appointment_id The ID of the appointment.
	 *
	 * @return array|null The transformed booking data.
	 */
	private function get_booking( $appointment_id ) {
		$appointment = Appointment::find( $appointment_id );
		if ( ! $appointment ) {
			return null;
		}
		return ( new AppointmentResource() )->transform( $appointment );
	}

	/**
	 * 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 ) {
		if ( ! $appointment_id ) {
			return array();
		}
		$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', 'radius-booking' ),
				'quantity'            => (int) ( $reg->quantity ?? 1 ),
				'price'               => $tt ? (float) $tt->price : 0,
				'registration_number' => $reg->registration_number ?? '',
			);
		}
		return $tickets;
	}

	/**
	 * 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 '';
	}
}
