<?php

namespace WarrantyCart\Notifications;

use Dompdf\Dompdf;
use WarrantyCart\Notifications\Emails\OrderCompletion;
use WarrantyCart\Notifications\Emails\WarrantyExpired;
use WarrantyCart\Notifications\Emails\WarrantyReminder;
use WC_Email;
use WC_Emails;
use WC_Order;

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

/**
 * Notifications Manager Class
 *
 * Manages warranty notifications and email sending.
 */
class Manager {

	/**
	 * Constructor
	 */
	public function __construct() {
		add_filter( 'woocommerce_email_classes', array( $this, 'register_emails' ) );
		add_action( 'woocommerce_order_status_completed', array( $this, 'send_order_completion_notification' ), 10, 2 );
		add_action( 'init', array( $this, 'load_pdf_library' ) );
	}

	/**
	 * Register warranty emails with WooCommerce
	 *
	 * @param array<string, WC_Email> $emails Existing emails.
	 *
	 * @return array<string, WC_Email>
	 */
	public function register_emails( array $emails ): array {
		$email_classes = array(
			OrderCompletion::class,
			WarrantyReminder::class,
			WarrantyExpired::class,
		);

		$email_classes = apply_filters( 'warranty_cart_email_classes', $email_classes );

		foreach ( $email_classes as $email_class ) {
			$email = new $email_class();

			if ( ! $email instanceof WC_Email ) {
				continue;
			}

			// Register to wc email lists
			$emails[ $email->id ] = $email;
		}

		/**
		 * Filter registered warranty emails.
		 *
		 * @param array<string, WC_Email> $emails        Registered emails.
		 * @param array                   $email_classes Email classes that were registered.
		 */
		return apply_filters( 'warranty_cart_registered_emails', $emails, $email_classes );
	}

	/**
	 * Send order completion notification
	 *
	 * @param int      $order_id Order ID.
	 * @param WC_Order $order    The Order instance.
	 */
	public function send_order_completion_notification( int $order_id, WC_Order $order ): void {
		// Check if order contains warranty products
		if ( ! $this->order_contains_warranties( $order ) ) {
			return;
		}

		/**
		 * Action before sending order completion notification
		 *
		 * @param int      $order_id Order ID.
		 * @param WC_Order $order    Order object.
		 */
		do_action( 'warranty_cart_before_send_order_completion_notification', $order_id, $order );

		$wc_emails = new WC_Emails();
		$emails    = $wc_emails->get_emails();

		// Send warranty order completion email
		if ( isset( $emails['warranty_order_completed'] ) ) {
			$email_class = $emails['warranty_order_completed'];
			if ( ! $email_class instanceof OrderCompletion ) {
				return;
			}

			$email_class->trigger( $order_id );
		}

		// Log notification
		$this->log_notification( 'order_completed', $order_id );

		/**
		 * Action after sending order completion notification
		 *
		 * @param int      $order_id Order ID.
		 * @param WC_Order $order    Order object.
		 */
		do_action( 'warranty_cart_after_send_order_completion_notification', $order_id, $order );
	}

	/**
	 * Send warranty reminder email
	 *
	 * Sends a reminder email to customers about upcoming warranty expiration.
	 *
	 * @param int    $order_id        Order ID.
	 * @param string $expiration_date Expiration date.
	 * @param int    $days_remaining  Days until expiration.
	 */
	public function send_warranty_reminder( int $order_id, string $expiration_date = '', int $days_remaining = 30 ): void {
		/**
		 * Action before sending warranty reminder
		 *
		 * @param int    $order_id        Order ID.
		 * @param string $expiration_date Expiration date.
		 * @param int    $days_remaining  Days until expiration.
		 */
		do_action( 'warranty_cart_before_send_warranty_reminder', $order_id, $expiration_date, $days_remaining );

		$wc_emails = new WC_Emails();
		$emails    = $wc_emails->get_emails();

		if ( isset( $emails['warranty_reminder'] ) ) {
			$email_class = $emails['warranty_reminder'];
			if ( ! $email_class instanceof WarrantyReminder ) {
				return;
			}

			$email_class->trigger( $order_id, $expiration_date, $days_remaining );
			$this->log_notification( 'warranty_reminder', $order_id );
		}

		/**
		 * Action after sending warranty reminder
		 *
		 * @param int    $order_id        Order ID.
		 * @param string $expiration_date Expiration date.
		 * @param int    $days_remaining  Days until expiration.
		 */
		do_action( 'warranty_cart_after_send_warranty_reminder', $order_id, $expiration_date, $days_remaining );
	}

	/**
	 * Send warranty expired email
	 *
	 * Sends a notification email to customers when their warranty has expired.
	 *
	 * @param int    $order_id        Order ID.
	 * @param string $expiration_date Expiration date.
	 */
	public function send_warranty_expired( int $order_id, string $expiration_date = '' ): void {
		/**
		 * Action before sending warranty expired notification
		 *
		 * @param int    $order_id        Order ID.
		 * @param string $expiration_date Expiration date.
		 */
		do_action( 'warranty_cart_before_send_warranty_expired', $order_id, $expiration_date );

		$wc_emails = new WC_Emails();
		$emails    = $wc_emails->get_emails();

		if ( isset( $emails['warranty_expired'] ) ) {
			$email_class = $emails['warranty_expired'];
			if ( ! $email_class instanceof WarrantyExpired ) {
				return;
			}

			$email_class->trigger( $order_id, $expiration_date );
			$this->log_notification( 'warranty_expired', $order_id );
		}

		/**
		 * Action after sending warranty expired notification
		 *
		 * @param int    $order_id        Order ID.
		 * @param string $expiration_date Expiration date.
		 */
		do_action( 'warranty_cart_after_send_warranty_expired', $order_id, $expiration_date );
	}

	/**
	 * Check if order contains warranty products
	 *
	 * Determines whether an order includes any warranty products.
	 *
	 * @param WC_Order $order Order object.
	 *
	 * @return bool True if order contains warranties, false otherwise.
	 */
	private function order_contains_warranties( WC_Order $order ): bool {
		foreach ( $order->get_items() as $item ) {
			$product = $item->get_product();
			if ( $product && has_term( 'warranties', 'product_cat', $product->get_id() ) ) {
				return true;
			}
		}

		return false;
	}

	/**
	 * Log notification
	 *
	 * Records notification events for debugging and monitoring.
	 *
	 * @param string     $type         Event type (e.g., 'order_completed').
	 * @param int|string $reference_id Reference ID (usually order ID).
	 */
	private function log_notification( string $type, $reference_id ): void {
		warranty_cart()->log(
			"Email sent: {$type}",
			'info',
			array( 'reference_id' => $reference_id )
		);
	}

	/**
	 * Load PDF library
	 *
	 * Initializes the DomPDF library for PDF certificate generation.
	 */
	public function load_pdf_library(): void {
		if ( ! class_exists( Dompdf::class ) ) {
			require_once WARRANTY_CART_PATH . 'vendor/dompdf/dompdf/src/Dompdf.php';
		}
	}
}
