<?php

/**
 * Email Manager
 * 
 * Manages custom email notifications and disables WooCommerce default emails
 * 
 * @package WooNooW\Core\Notifications
 */

namespace WooNooW\Core\Notifications;

class EmailManager
{

	/**
	 * Instance
	 */
	private static $instance = null;

	/**
	 * Get instance
	 */
	public static function instance()
	{
		if (null === self::$instance) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Constructor
	 */
	private function __construct()
	{
		$this->init_hooks();
	}

	/**
	 * Initialize hooks
	 */
	private function init_hooks()
	{
		// Disable WooCommerce emails to prevent duplicates
		add_action('woocommerce_email', [$this, 'disable_wc_emails'], 1);

		// Hook into WooCommerce order status changes
		add_action('woocommerce_order_status_pending_to_processing', [$this, 'send_order_processing_email'], 10, 2);
		add_action('woocommerce_order_status_pending_to_completed', [$this, 'send_order_completed_email'], 10, 2);
		add_action('woocommerce_order_status_processing_to_completed', [$this, 'send_order_completed_email'], 10, 2);
		add_action('woocommerce_order_status_completed', [$this, 'send_order_completed_email'], 10, 2);
		add_action('woocommerce_order_status_pending_to_on-hold', [$this, 'send_order_on_hold_email'], 10, 2);
		add_action('woocommerce_order_status_failed_to_processing', [$this, 'send_order_processing_email'], 10, 2);
		add_action('woocommerce_order_status_cancelled', [$this, 'send_order_cancelled_email'], 10, 2);
		add_action('woocommerce_order_status_refunded', [$this, 'send_order_refunded_email'], 10, 2);
		add_action('woocommerce_order_fully_refunded', [$this, 'send_order_refunded_email'], 10, 2);

		// New order notification for admin
		add_action('woocommerce_new_order', [$this, 'send_new_order_admin_email'], 10, 1);

		// Customer note
		add_action('woocommerce_new_customer_note', [$this, 'send_customer_note_email'], 10, 1);

		// New customer account
		add_action('woocommerce_created_customer', [$this, 'send_new_customer_email'], 10, 3);

		// Password reset - intercept WordPress default email and use our template
		add_filter('retrieve_password_message', [$this, 'handle_password_reset_email'], 10, 4);

		// Low stock / Out of stock
		add_action('woocommerce_low_stock', [$this, 'send_low_stock_email'], 10, 1);
		add_action('woocommerce_no_stock', [$this, 'send_out_of_stock_email'], 10, 1);
		add_action('woocommerce_product_set_stock', [$this, 'check_stock_levels'], 10, 1);
	}

	/**
	 * Check if WooNooW notification system is enabled
	 * 
	 * @return bool
	 */
	public static function is_enabled()
	{
		// Check global notification system mode
		$system_mode = get_option('woonoow_notification_system_mode', 'woonoow');
		return $system_mode === 'woonoow';
	}

	/**
	 * Disable WooCommerce default emails
	 * 
	 * @param WC_Emails $email_class
	 */
	public function disable_wc_emails($email_class)
	{
		// Only disable WC emails if WooNooW system is enabled
		if (!self::is_enabled()) {
			return; // Keep WC emails if WooNooW system disabled
		}

		// Disable all WooCommerce transactional emails
		$emails_to_disable = [
			'WC_Email_New_Order',                    // Admin: New order
			'WC_Email_Cancelled_Order',              // Admin: Cancelled order
			'WC_Email_Failed_Order',                 // Admin: Failed order
			'WC_Email_Customer_On_Hold_Order',       // Customer: Order on-hold
			'WC_Email_Customer_Processing_Order',    // Customer: Processing order
			'WC_Email_Customer_Completed_Order',     // Customer: Completed order
			'WC_Email_Customer_Refunded_Order',      // Customer: Refunded order
			'WC_Email_Customer_Invoice',             // Customer: Invoice
			'WC_Email_Customer_Note',                // Customer: Note added
			'WC_Email_Customer_Reset_Password',      // Customer: Reset password
			'WC_Email_Customer_New_Account',         // Customer: New account
		];

		foreach ($emails_to_disable as $email_id) {
			add_filter('woocommerce_email_enabled_' . strtolower(str_replace('WC_Email_', '', $email_id)), '__return_false');
		}
	}

	/**
	 * Send order processing email
	 * 
	 * @param int $order_id
	 * @param WC_Order $order
	 */
	public function send_order_processing_email($order_id, $order = null)
	{
		if (defined('WP_DEBUG') && WP_DEBUG) {
		}

		if (!$order) {
			$order = wc_get_order($order_id);
		}

		if (!$order) {
			if (defined('WP_DEBUG') && WP_DEBUG) {
			}
			return;
		}

		// Check if event is enabled
		if (!$this->is_event_enabled('order_processing', 'email', 'customer')) {
			if (defined('WP_DEBUG') && WP_DEBUG) {
			}
			return;
		}

		if (defined('WP_DEBUG') && WP_DEBUG) {
		}

		// Send email
		$this->send_email('order_processing', 'customer', $order);
	}

	/**
	 * Send order completed email
	 * 
	 * @param int $order_id
	 * @param WC_Order $order
	 */
	public function send_order_completed_email($order_id, $order = null)
	{
		if (!$order) {
			$order = wc_get_order($order_id);
		}

		if (!$order) {
			return;
		}

		// Check if event is enabled
		if (!$this->is_event_enabled('order_completed', 'email', 'customer')) {
			return;
		}

		// Send email
		$this->send_email('order_completed', 'customer', $order);
	}

	/**
	 * Send order on-hold email
	 * 
	 * @param int $order_id
	 * @param WC_Order $order
	 */
	public function send_order_on_hold_email($order_id, $order = null)
	{
		if (!$order) {
			$order = wc_get_order($order_id);
		}

		if (!$order) {
			return;
		}

		// Check if event is enabled
		if (!$this->is_event_enabled('order_processing', 'email', 'customer')) {
			return;
		}

		// Send email (use processing template for on-hold)
		$this->send_email('order_processing', 'customer', $order);
	}

	/**
	 * Send order cancelled email
	 * 
	 * @param int $order_id
	 * @param WC_Order $order
	 */
	public function send_order_cancelled_email($order_id, $order = null)
	{
		if (!$order) {
			$order = wc_get_order($order_id);
		}

		if (!$order) {
			return;
		}

		// Send to admin
		if ($this->is_event_enabled('order_cancelled', 'email', 'staff')) {
			$this->send_email('order_cancelled', 'staff', $order);
		}
	}

	/**
	 * Send order refunded email
	 * 
	 * @param int $order_id
	 * @param WC_Order $order
	 */
	public function send_order_refunded_email($order_id, $order = null)
	{
		if (!$order) {
			$order = wc_get_order($order_id);
		}

		if (!$order) {
			return;
		}

		// Check if event is enabled
		if (!$this->is_event_enabled('order_refunded', 'email', 'customer')) {
			return;
		}

		// Send email
		$this->send_email('order_refunded', 'customer', $order);
	}

	/**
	 * Send new order admin email
	 * 
	 * @param int $order_id
	 */
	public function send_new_order_admin_email($order_id)
	{
		$order = wc_get_order($order_id);

		if (!$order) {
			return;
		}

		// Check if event is enabled
		if (!$this->is_event_enabled('order_placed', 'email', 'staff')) {
			return;
		}

		// Send email
		$this->send_email('order_placed', 'staff', $order);
	}

	/**
	 * Send customer note email
	 * 
	 * @param array $args
	 */
	public function send_customer_note_email($args)
	{
		$order = wc_get_order($args['order_id']);

		if (!$order) {
			return;
		}

		// Check if event is enabled
		if (!$this->is_event_enabled('customer_note', 'email', 'customer')) {
			return;
		}

		// Send email with note data — key must match {customer_note} variable in template
		$this->send_email('customer_note', 'customer', $order, ['customer_note' => $args['customer_note']]);
	}

	/**
	 * Send new customer email
	 * 
	 * @param int $customer_id
	 * @param array $new_customer_data
	 * @param bool $password_generated
	 */
	public function send_new_customer_email($customer_id, $new_customer_data = [], $password_generated = false)
	{
		// Check if event is enabled
		if (!$this->is_event_enabled('new_customer', 'email', 'customer')) {
			return;
		}

		$customer = new \WC_Customer($customer_id);

		// Send email
		$this->send_email('new_customer', 'customer', $customer, [
			'password_generated' => $password_generated,
			'user_login' => $new_customer_data['user_login'] ?? '',
			'user_pass' => $new_customer_data['user_pass'] ?? '',
		]);
	}

	/**
	 * Handle password reset email - intercept WordPress default and use our template
	 * 
	 * @param string $message Email message (we replace this)
	 * @param string $key Reset key
	 * @param string $user_login User login
	 * @param WP_User $user_data User object
	 * @return string Empty string to prevent WordPress sending default email
	 */
	public function handle_password_reset_email($message, $key, $user_login, $user_data)
	{
		// Check if WooNooW notification system is enabled
		if (!self::is_enabled()) {
			return $message; // Use WordPress default
		}

		// Check if event is enabled
		if (!$this->is_event_enabled('password_reset', 'email', 'customer')) {
			return $message; // Use WordPress default
		}

		// Build reset URL - use SPA page from appearance settings
		// The SPA page (e.g., /store/) loads customer-spa which has /reset-password route
		$appearance_settings = get_option('woonoow_appearance_settings', []);
		$spa_page_id = $appearance_settings['general']['spa_page'] ?? 0;
		$use_browser_router = $appearance_settings['general']['use_browser_router'] ?? true;

		if ($spa_page_id > 0) {
			$spa_url = get_permalink($spa_page_id);
		} else {
			// Fallback to home URL if SPA page not configured
			$spa_url = home_url('/');
		}

		// Build SPA reset password URL
		// Use path format for BrowserRouter (SEO), hash format for HashRouter (legacy)
		if ($use_browser_router) {
			// Path format: /store/reset-password?key=KEY&login=LOGIN
			$reset_link = trailingslashit($spa_url) . 'reset-password?key=' . $key . '&login=' . rawurlencode($user_login);
		} else {
			// Hash format: /store/#/reset-password?key=KEY&login=LOGIN
			$reset_link = rtrim($spa_url, '/') . '#/reset-password?key=' . $key . '&login=' . rawurlencode($user_login);
		}

		// Create a pseudo WC_Customer for template rendering
		$customer = null;
		if (class_exists('WC_Customer')) {
			try {
				$customer = new \WC_Customer($user_data->ID);
			} catch (\Exception $e) {
				$customer = null;
			}
		}

		// Send our custom email
		$this->send_password_reset_email($user_data, $key, $reset_link, $customer);

		// Return empty string to prevent WordPress from sending its default plain-text email
		return '';
	}

	/**
	 * Send password reset email using our template
	 * 
	 * @param WP_User $user User object
	 * @param string $key Reset key
	 * @param string $reset_link Full reset link URL
	 * @param WC_Customer|null $customer WooCommerce customer object if available
	 */
	private function send_password_reset_email($user, $key, $reset_link, $customer = null)
	{
		// Get email renderer
		$renderer = EmailRenderer::instance();

		// Build extra data for template variables
		$extra_data = [
			'reset_key' => $key,
			'reset_link' => $reset_link,
			'user_login' => $user->user_login,
			'user_email' => $user->user_email,
			'customer_name' => $user->display_name ?: $user->user_login,
			'customer_email' => $user->user_email,
		];

		// Use WC_Customer if available for better template rendering
		$data = $customer ?: $user;

		// Render email
		$email = $renderer->render('password_reset', 'customer', $data, $extra_data);

		if (!$email) {
			if (defined('WP_DEBUG') && WP_DEBUG) {
			}
			return;
		}

		// Send email via wp_mail
		$headers = [
			'Content-Type: text/html; charset=UTF-8',
			'From: ' . get_bloginfo('name') . ' <' . get_option('admin_email') . '>',
		];

		$sent = wp_mail($email['to'], $email['subject'], $email['body'], $headers);

		if (defined('WP_DEBUG') && WP_DEBUG) {
		}

		// Log email sent
		do_action('woonoow_email_sent', 'password_reset', 'customer', $email);
	}

	/**
	 * Send low stock email
	 * 
	 * @param WC_Product $product
	 */
	public function send_low_stock_email($product)
	{
		// Check if event is enabled
		if (!$this->is_event_enabled('low_stock', 'email', 'staff')) {
			return;
		}

		// Pass low_stock_threshold so template can display it
		$low_stock_threshold = get_option('woocommerce_notify_low_stock_amount', 2);
		$this->send_email('low_stock', 'staff', $product, [
			'low_stock_threshold' => $low_stock_threshold,
		]);
	}

	/**
	 * Send out of stock email
	 * 
	 * @param WC_Product $product
	 */
	public function send_out_of_stock_email($product)
	{
		// Check if event is enabled
		if (!$this->is_event_enabled('out_of_stock', 'email', 'staff')) {
			return;
		}

		// Send email
		$this->send_email('out_of_stock', 'staff', $product);
	}

	/**
	 * Check stock levels when product stock is updated
	 * 
	 * @param WC_Product $product
	 */
	public function check_stock_levels($product)
	{
		$stock = $product->get_stock_quantity();
		$low_stock_threshold = get_option('woocommerce_notify_low_stock_amount', 2);

		if ($stock <= 0) {
			$this->send_out_of_stock_email($product);
		} elseif ($stock <= $low_stock_threshold) {
			$this->send_low_stock_email($product);
		}
	}

	/**
	 * Check if event is enabled
	 * 
	 * @param string $event_id
	 * @param string $channel_id
	 * @param string $recipient_type
	 * @return bool
	 */
	private function is_event_enabled($event_id, $channel_id, $recipient_type)
	{
		$settings = get_option('woonoow_notification_settings', []);

		// Check if event exists and channel is configured
		if (isset($settings['events'][$event_id]['channels'][$channel_id])) {
			return $settings['events'][$event_id]['channels'][$channel_id]['enabled'] ?? false;
		}

		// Default: enable email notifications if not explicitly configured
		// This allows the plugin to work out-of-the-box with default templates
		if ($channel_id === 'email') {
			if (defined('WP_DEBUG') && WP_DEBUG) {
			}
			return true; // Enable by default
		}

		return false;
	}

	/**
	 * Send email
	 * 
	 * @param string $event_id
	 * @param string $recipient_type
	 * @param mixed $data
	 * @param array $extra_data
	 */
	private function send_email($event_id, $recipient_type, $data, $extra_data = [])
	{
		if (defined('WP_DEBUG') && WP_DEBUG) {
		}

		// Get email renderer
		$renderer = EmailRenderer::instance();

		// Render email
		$email = $renderer->render($event_id, $recipient_type, $data, $extra_data);

		if (!$email) {
			if (defined('WP_DEBUG') && WP_DEBUG) {
			}
			return;
		}

		if (defined('WP_DEBUG') && WP_DEBUG) {
		}

		// Send email via wp_mail
		$headers = [
			'Content-Type: text/html; charset=UTF-8',
			'From: ' . get_bloginfo('name') . ' <' . get_option('admin_email') . '>',
		];

		$sent = wp_mail($email['to'], $email['subject'], $email['body'], $headers);

		if (defined('WP_DEBUG') && WP_DEBUG) {
		}

		// Log email sent
		do_action('woonoow_email_sent', $event_id, $recipient_type, $email);
	}
}
