<?php
/**
 * Custom WooCommerce email template management.
 *
 * @package MailDoctor
 */

namespace MailDoctor;

use MailDoctor\Email\OverrideResolver;
use MailDoctor\Email\TemplateRepository;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

require_once __DIR__ . '/templates/trait-templates-init.php';
require_once __DIR__ . '/templates/trait-templates-sanitizers.php';
require_once __DIR__ . '/templates/trait-templates-repository.php';
require_once __DIR__ . '/templates/trait-templates-filters.php';
require_once __DIR__ . '/templates/trait-templates-maintenance.php';

/**
 * Main controller for WooCommerce email templates.
 */
class WPMD_Email_Templates {

	use WPMD_Email_Templates_Init;
	use WPMD_Email_Templates_Sanitizers;
	use WPMD_Email_Templates_Repository;
	use WPMD_Email_Templates_Filters;
	use WPMD_Email_Templates_Maintenance;

	/**
	 * Custom post type slug.
	 */
	public const CPT = 'wpmaildoc_template';

	/**
	 * Option key for enable toggle.
	 */
	public const OPTION_ENABLE = 'mail_doctor_enable_email_templates';

	/**
	 * Cache group for template payloads.
	 */
	public const CACHE_GROUP = 'mail_doctor_templates';

	/**
	 * Meta key definitions.
	 */
	public const META_EMAIL_TYPE = '_wpmaildoc_email_type';
	public const META_SUBJECT    = '_wpmaildoc_subject';
	public const META_HEADING    = '_wpmaildoc_heading';
	public const META_BODY       = '_wpmaildoc_body_html';
	public const META_ACTIVE     = '_wpmaildoc_is_active';
	public const META_CSS        = '_wpmaildoc_css';

	/**
	 * Track the current Woo email instance.
	 *
	 * @var \WC_Email|null
	 */
	protected static $current_email = null;

	/**
	 * Whether init() has already registered hooks.
	 */
	protected static bool $bootstrapped = false;

	/**
	 * Timestamp when init() executed.
	 */
	protected static ?int $init_ran_at = null;

	/**
	 * Timestamp when register_email_filters() executed.
	 */
	protected static ?int $filters_ran_at = null;

	/**
	 * Track the current order for rendering.
	 *
	 * @var \WC_Order|null
	 */
	protected static $current_order = null;

	/**
	 * Lazily-instantiated template repository.
	 *
	 * @var TemplateRepository|null
	 */
	protected static ?TemplateRepository $template_repository = null;

	/**
	 * Lazily-instantiated override resolver.
	 *
	 * @var OverrideResolver|null
	 */
	protected static ?OverrideResolver $override_resolver = null;

	/**
	 * Cache of prepared template payloads during a request.
	 *
	 * @var array<string, array<string, mixed>>
	 */
	protected static $prepared_templates = array();

	/**
	 * Register AJAX handlers after admin bootstrap.
	 *
	 * @return void
	 */
	public static function register_admin_ajax(): void {
		add_action( 'wp_ajax_mail_doctor_preview_template', array( __CLASS__, 'ajax_preview' ) );
		add_action( 'wp_ajax_mail_doctor_preview', array( __CLASS__, 'ajax_preview' ) );
		add_action( 'wp_ajax_mail_doctor_send_test', array( __CLASS__, 'ajax_send_test' ) );
	}

	/**
	 * Wrapper for legacy preview handler, ensuring functions exist.
	 *
	 * @return void
	 */
	public static function ajax_preview(): void {
		if ( function_exists( 'mail_doctor_ajax_preview' ) ) {
			mail_doctor_ajax_preview();
			return;
		}

		wp_send_json_error(
			array(
				'message' => esc_html__( 'Preview handler is unavailable.', 'mail-doctor' ),
			),
			500
		);
	}

	/**
	 * Wrapper for legacy send-test handler.
	 *
	 * @return void
	 */
	public static function ajax_send_test(): void {
		if ( function_exists( 'mail_doctor_ajax_send_test' ) ) {
			mail_doctor_ajax_send_test();
			return;
		}

		wp_send_json_error(
			array(
				'message' => esc_html__( 'Send-test handler is unavailable.', 'mail-doctor' ),
			),
			500
		);
	}

	/**
	 * Retrieve shared template repository instance.
	 */
	protected static function repository(): TemplateRepository {
		if ( ! self::$template_repository instanceof TemplateRepository ) {
			self::$template_repository = new TemplateRepository();
		}

		return self::$template_repository;
	}

	/**
	 * Retrieve shared override resolver instance.
	 */
	protected static function resolver(): OverrideResolver {
		if ( ! self::$override_resolver instanceof OverrideResolver ) {
			self::$override_resolver = new OverrideResolver( self::repository() );
		}

		return self::$override_resolver;
	}
}
