<?php
/**
 * Warranty Cron Jobs
 *
 * Handles scheduled tasks for warranty management including expiration checking and reminders.
 *
 * @package WarrantyCart
 */

namespace WarrantyCart\Core;

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

/**
 * Warranty Cron Jobs Class
 */
class WarrantyCron {

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

	/**
	 * Initialize hooks
	 */
	protected function init_hooks(): void {
		\add_action( 'warranty_cart_check_expirations', array( $this, 'check_expiring_warranties' ) );
		\add_action( 'warranty_cart_send_reminders', array( $this, 'send_expiration_reminders' ) );
	}

	/**
	 * Check for expiring warranties and update status
	 *
	 * @return void
	 */
	public function check_expiring_warranties(): void {
		global $wpdb;

		$table_name = $wpdb->prefix . 'warranty_cart_warranties';

		// Get current date
		$current_date = \current_time( 'Y-m-d' );

		try {
			// Find warranties that have expired
			$expired_warranties = $wpdb->get_results(
				$wpdb->prepare(
					"SELECT * FROM %s
					WHERE status = 'active'
					AND expiration_date < %s
					ORDER BY expiration_date ASC",
					$table_name,
					$current_date
				)
			);

			if ( empty( $expired_warranties ) ) {
				return; // No expired warranties
			}

			$expired_count      = 0;
			$notification_count = 0;
			$failed_count       = 0;

			foreach ( $expired_warranties as $warranty ) {
				try {
					// Update warranty status to expired
					$result = $wpdb->update(
						$table_name,
						array(
							'status'           => 'expired',
							'expired_notified' => 1,
							'updated_at'       => \current_time( 'mysql' ),
						),
						array( 'id' => $warranty->id ),
						array( '%s', '%d', '%s' ),
						array( '%d' )
					);

					if ( false !== $result ) {
						++$expired_count;

						// Send expiration notification
						$notification_sent = $this->send_expiration_notification( $warranty );

						if ( $notification_sent ) {
							++$notification_count;
						}

						// Trigger action for further processing
						\do_action( 'warranty_cart_warranty_expired', $warranty );
					} else {
						++$failed_count;
						\wc_get_logger()->error(
							\sprintf( 'Failed to update expired status for warranty #%d', $warranty->id ),
							array( 'source' => 'warranty-cart-cron' )
						);
					}
				} catch ( \Exception $e ) {
					++$failed_count;
					\wc_get_logger()->error(
						\sprintf( 'Exception processing expired warranty #%d: %s', $warranty->id, $e->getMessage() ),
						array( 'source' => 'warranty-cart-cron' )
					);
				}
			}

			// Log results
			if ( $expired_count > 0 ) {
				\wc_get_logger()->info(
					\sprintf( 'Marked %d warranties as expired (%d notifications sent, %d failed)', $expired_count, $notification_count, $failed_count ),
					array( 'source' => 'warranty-cart-cron' )
				);
			}

			if ( $failed_count > 0 ) {
				\wc_get_logger()->warning(
					\sprintf( 'Failed to process %d expired warranties', $failed_count ),
					array( 'source' => 'warranty-cart-cron' )
				);
			}
		} catch ( \Exception $e ) {
			\wc_get_logger()->error(
				\sprintf( 'Exception in check_expiring_warranties: %s', $e->getMessage() ),
				array( 'source' => 'warranty-cart-cron' )
			);
		}
	}

	/**
	 * Send expiration reminders for warranties expiring soon
	 *
	 * @return void
	 */
	public function send_expiration_reminders(): void {
		global $wpdb;

		$table_name = $wpdb->prefix . 'warranty_cart_warranties';

		// Get configurable reminder period (default 30 days)
		$reminder_days = (int) \apply_filters( 'warranty_cart_reminder_days', 30 );
		$reminder_days = max( 1, $reminder_days ); // Minimum 1 day

		// Calculate reminder date range
		$current_date  = \current_time( 'Y-m-d' );
		$reminder_date = \wp_date( 'Y-m-d', \strtotime( $current_date . " +{$reminder_days} days" ) );

		try {
			// Find warranties expiring within reminder period that haven't been reminded
			$warranties_needing_reminder = $wpdb->get_results(
				$wpdb->prepare(
					"SELECT * FROM %s
					WHERE status = 'active'
					AND reminder_sent = 0
					AND expiration_date <= %s
					AND expiration_date >= %s
					ORDER BY expiration_date ASC",
					$table_name,
					$reminder_date,
					$current_date
				)
			);

			if ( empty( $warranties_needing_reminder ) ) {
				return; // No reminders needed
			}

			$reminder_count = 0;
			$failed_count   = 0;

			foreach ( $warranties_needing_reminder as $warranty ) {
				try {
					// Send reminder email
					$email_sent = $this->send_expiration_reminder( $warranty );

					if ( $email_sent ) {
						// Mark as reminded
						$result = $wpdb->update(
							$table_name,
							array(
								'reminder_sent' => 1,
								'updated_at'    => \current_time( 'mysql' ),
							),
							array( 'id' => $warranty->id ),
							array( '%d', '%s' ),
							array( '%d' )
						);

						if ( false !== $result ) {
							++$reminder_count;
							// Trigger action for further processing
							\do_action( 'warranty_cart_warranty_reminder_sent', $warranty );
						} else {
							++$failed_count;
							\wc_get_logger()->error(
								\sprintf( 'Failed to update reminder status for warranty #%d', $warranty->id ),
								array( 'source' => 'warranty-cart-cron' )
							);
						}
					} else {
						++$failed_count;
					}
				} catch ( \Exception $e ) {
					++$failed_count;
					\wc_get_logger()->error(
						\sprintf( 'Exception sending reminder for warranty #%d: %s', $warranty->id, $e->getMessage() ),
						array( 'source' => 'warranty-cart-cron' )
					);
				}
			}

			// Log results
			if ( $reminder_count > 0 ) {
				\wc_get_logger()->info(
					\sprintf( 'Sent expiration reminders for %d warranties (failed: %d)', $reminder_count, $failed_count ),
					array( 'source' => 'warranty-cart-cron' )
				);
			}

			if ( $failed_count > 0 ) {
				\wc_get_logger()->warning(
					\sprintf( 'Failed to send reminders for %d warranties', $failed_count ),
					array( 'source' => 'warranty-cart-cron' )
				);
			}
		} catch ( \Exception $e ) {
			\wc_get_logger()->error(
				\sprintf( 'Exception in send_expiration_reminders: %s', $e->getMessage() ),
				array( 'source' => 'warranty-cart-cron' )
			);
		}
	}

	/**
	 * Send expiration notification email
	 *
	 * @param object $warranty Warranty data object.
	 *
	 * @return bool True if email was sent successfully, false otherwise.
	 */
	protected function send_expiration_notification( object $warranty ): bool {
		try {
			// Use existing email class
			$email_class = new \WarrantyCart\Notifications\Emails\WarrantyExpired();
			$result      = $email_class->trigger( $warranty->order_id, $warranty );

			if ( $result ) {
				\wc_get_logger()->info(
					\sprintf( 'Sent expiration notification for warranty #%d', $warranty->id ),
					array( 'source' => 'warranty-cart-cron' )
				);

				return true;
			} else {
				\wc_get_logger()->warning(
					\sprintf( 'Failed to send expiration notification for warranty #%d', $warranty->id ),
					array( 'source' => 'warranty-cart-cron' )
				);

				return false;
			}
		} catch ( \Exception $e ) {
			\wc_get_logger()->error(
				\sprintf( 'Exception sending expiration notification for warranty #%d: %s', $warranty->id, $e->getMessage() ),
				array( 'source' => 'warranty-cart-cron' )
			);

			return false;
		}
	}

	/**
	 * Send expiration reminder email
	 *
	 * @param object $warranty Warranty data object.
	 *
	 * @return bool True if email was sent successfully, false otherwise.
	 */
	protected function send_expiration_reminder( object $warranty ): bool {
		try {
			// Use existing email class
			$email_class = new \WarrantyCart\Notifications\Emails\WarrantyReminder();
			$result      = $email_class->trigger( $warranty->order_id, $warranty );

			if ( $result ) {
				\wc_get_logger()->info(
					\sprintf( 'Sent expiration reminder for warranty #%d', $warranty->id ),
					array( 'source' => 'warranty-cart-cron' )
				);

				return true;
			} else {
				\wc_get_logger()->warning(
					\sprintf( 'Failed to send expiration reminder for warranty #%d', $warranty->id ),
					array( 'source' => 'warranty-cart-cron' )
				);

				return false;
			}
		} catch ( \Exception $e ) {
			\wc_get_logger()->error(
				\sprintf( 'Exception sending expiration reminder for warranty #%d: %s', $warranty->id, $e->getMessage() ),
				array( 'source' => 'warranty-cart-cron' )
			);

			return false;
		}
	}

	/**
	 * Get warranty statistics for admin dashboard
	 *
	 * @return array Warranty statistics.
	 */
	public static function get_warranty_stats(): array {
		global $wpdb;

		$table_name = $wpdb->prefix . 'warranty_cart_warranties';

		$stats = $wpdb->get_row(
			$wpdb->prepare(
				"SELECT
					COUNT(*) as total_warranties,
					SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active_warranties,
					SUM(CASE WHEN status = 'expired' THEN 1 ELSE 0 END) as expired_warranties,
					SUM(CASE WHEN expiration_date < CURDATE() AND status = 'active' THEN 1 ELSE 0 END) as overdue_warranties,
					SUM(CASE WHEN expiration_date BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY) AND status = 'active' THEN 1 ELSE 0 END) as expiring_soon
				FROM %s",
				$table_name
			)
		);

		return array(
			'total_warranties'   => (int) ( $stats->total_warranties ?? 0 ),
			'active_warranties'  => (int) ( $stats->active_warranties ?? 0 ),
			'expired_warranties' => (int) ( $stats->expired_warranties ?? 0 ),
			'overdue_warranties' => (int) ( $stats->overdue_warranties ?? 0 ),
			'expiring_soon'      => (int) ( $stats->expiring_soon ?? 0 ),
		);
	}
}
