<?php
/**
 * Base Email Class
 *
 * @package RadiusTheme\RadiusBooking\Abstracts
 */

namespace RadiusTheme\RadiusBooking\Abstracts;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
} // Exit if accessed directly

use RadiusTheme\RadiusBooking\Emails\EmailQueue;
use RadiusTheme\RadiusBooking\Emails\EmailSender;
use RadiusTheme\RadiusBooking\Emails\MergeTags;
use RadiusTheme\RadiusBooking\Emails\TemplateRenderer;

/**
 * Base Email Abstract Class
 */
abstract class BaseEmail {

	/**
	 * Email ID.
	 *
	 * @var string
	 */
	public $id;

	/**
	 * Email title.
	 *
	 * @var string
	 */
	public $title;

	/**
	 * Email description.
	 *
	 * @var string
	 */
	public $description;

	/**
	 * Email tooltip.
	 *
	 * @var string
	 */
	public $tooltip;

	/**
	 * Recipient type.
	 *
	 * @var string
	 */
	public $recipient_type;

	/**
	 * HTML template.
	 *
	 * @var string
	 */
	public $template_html;

	/**
	 * Email settings.
	 *
	 * @var array
	 */
	public $settings;

	/**
	 * Whether email is enabled.
	 *
	 * @var bool
	 */
	public $enabled = true;

	public $status;

	/**
	 * Constructor.
	 */
	public function __construct() {
		$this->settings = $this->get_settings();
		$this->register_hooks();
	}

	/**
	 * Get email ID.
	 *
	 * @return string
	 */
	abstract public function get_id();

	/**
	 * Get trigger action.
	 *
	 * @return string
	 */
	abstract public function get_trigger_action();

	/**
	 * Get default settings.
	 *
	 * @return array
	 */
	abstract public function get_default_settings();

	/**
	 * Prepare email data.
	 *
	 * @param array $args Arguments.
	 * @return array
	 */
	abstract protected function prepare_email_data( $args );

	/**
	 * Register hooks.
	 *
	 * @return void
	 */
	protected function register_hooks(): void {
		$trigger = $this->get_trigger_action();
		if ( $trigger ) {
			add_action( $trigger, array( $this, 'trigger' ), 10, 10 );
		}
	}

	/**
	 * Get email title.
	 *
	 * @return string
	 */
	public function get_title() {
		return $this->title;
	}

	/**
	 * Get email description.
	 *
	 * @return string
	 */
	public function get_description() {
		return $this->description;
	}

	/**
	 * Get email settings.
	 *
	 * @return array
	 */
	public function get_settings() {
		if ( null !== $this->settings ) {
			return $this->settings;
		}

		$option_key = 'rtrb_email_' . $this->get_id();
		$settings   = get_option( $option_key, $this->get_default_settings() );

		return wp_parse_args( $settings, $this->get_default_settings() );
	}

	/**
	 * Update email settings.
	 *
	 * @param array $new_settings New settings.
	 * @return bool
	 */
	public function update_settings( $new_settings ): bool {
		$option_key = 'rtrb_email_' . $this->get_id();
		$settings   = array_merge( $this->get_settings(), $new_settings );

		update_option( $option_key, $settings, false );
		$this->settings = $settings;

		return true;
	}

	/**
	 * Check if email is enabled.
	 *
	 * @return bool
	 */
	public function is_enabled(): bool {
		$settings = $this->get_settings();
		return isset( $settings['enabled'] ) && $settings['enabled'];
	}

	/**
	 * Trigger email.
	 *
	 * @param mixed ...$args Arguments.
	 * @return bool
	 */
	public function trigger( ...$args ) {
		if ( ! $this->is_enabled() ) {
			return false;
		}

		$email_data = $this->prepare_email_data( $args );
		if ( empty( $email_data ) || ! isset( $email_data['to'] ) ) {
			return false;
		}

		if ( ! $this->validate_email_data( $email_data ) ) {
			return false;
		}

		$email_data = apply_filters( 'rtrb_be_before_send_email', $email_data, $this );
		$email_data = apply_filters( 'rtrb_be_before_send_email_' . $this->get_id(), $email_data, $this );

		if ( $this->should_queue() ) {
			return EmailQueue::add( $this->get_id(), $email_data );
		} else {
			return $this->send( $email_data );
		}
	}

	/**
	 * Validate email data.
	 *
	 * @param array $email_data Email data.
	 * @return bool
	 */
	protected function validate_email_data( $email_data ): bool {
		if ( empty( $email_data['to'] ) ) {
			return false;
		}

		return true;
	}

	/**
	 * Check if email should be queued.
	 *
	 * @return bool
	 */
	protected function should_queue(): bool {
		$settings = $this->get_settings();
		return isset( $settings['use_queue'] ) && $settings['use_queue'];
	}

	/**
	 * Send email.
	 *
	 * @param array $email_data Email data.
	 * @return bool
	 */
	public function send( $email_data ) {
		$settings = $this->get_settings();

		$subject = MergeTags::replace( $settings['subject'], $email_data['merge_tags'] );

		$html_body = TemplateRenderer::render(
			$this->template_html,
			array(
				'settings'   => $settings,
				'booking'    => $email_data['data'],
				'merge_tags' => $email_data['merge_tags'],
				'email'      => $this,
			)
		);

		$html_body = MergeTags::replace( $html_body, $email_data['merge_tags'] );

		$result = EmailSender::send(
			$email_data['to'],
			$subject,
			$html_body,
			$email_data
		);

		do_action( 'rtrb_after_send_email', $result, $email_data, $this );
		do_action( 'rtrb_after_send_email_' . $this->get_id(), $result, $email_data, $this );

		return $result;
	}

	/**
	 * Get preview data for email template.
	 *
	 * @return array
	 */
	public function get_preview_data(): array {
		return array(
			'customer_name'  => 'John Doe',
			'customer_email' => 'john@example.com',
			'customer_phone' => '+1 (555) 123-4567',
			'service_name'   => 'Hair Cut & Styling',
			'staff_name'     => 'Sarah Johnson',
			'booking_id'     => 'BK-2025-001',
			'booking_date'   => 'Monday, October 20, 2025',
			'time'           => '2:00 PM',
			'duration'       => '60 minutes',
			'location'       => '123 Main St, Suite 200',
			'price'          => '$75.00',
			'status'         => 'Confirmed',
			'notes'          => 'Please arrive 10 minutes early',
		);
	}
}
