<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase, WordPress.Files.FileName.InvalidClassFileName
/**
 * Snooze Module.
 *
 * Registers the Snooze services in the container and wires up all
 * snooze-related WordPress hooks (action filters, render hooks,
 * AJAX endpoints, script enqueue).
 *
 * @package Autoship\Modules\Snooze
 * @since   2.13.0
 */

namespace Autoship\Modules\Snooze;

use Autoship\Core\CredentialsInterface;
use Autoship\Core\EnvironmentInterface;
use Autoship\Core\ModuleInterface;
use Autoship\Core\Plugin;
use Autoship\Core\ServiceContainer;
use Autoship\Modules\Snooze\Controllers\SnoozeAjaxController;
use Autoship\Services\Labels\LabelServiceInterface;
use Autoship\Services\Logging\LoggerInterface;
use Autoship\Services\QPilot\QPilotServiceFactory;
use Autoship\Services\Snooze\Implementations\SnoozeActionFilters;
use Autoship\Services\Snooze\Implementations\SnoozeFeatureFlags;
use Autoship\Services\Snooze\Implementations\SnoozeOptionsProvider;
use Autoship\Services\Snooze\Implementations\SnoozeRenderer;
use Autoship\Services\Snooze\Implementations\SnoozeSettings;
use Autoship\Services\Snooze\Interfaces\SnoozeFeatureFlagsInterface;
use Autoship\Services\Snooze\Interfaces\SnoozeOptionsProviderInterface;
use Autoship\Services\Snooze\Interfaces\SnoozeSettingsInterface;
use Autoship\Services\Templates\TemplateRendererInterface;

/**
 * Bootstraps the Snooze feature.
 */
class SnoozeModule implements ModuleInterface {

	/**
	 * @inheritDoc
	 */
	public function register( ServiceContainer $container ) {
		$container->register(
			SnoozeSettingsInterface::class,
			static function () {
				return new SnoozeSettings();
			}
		);

		$container->register(
			SnoozeFeatureFlagsInterface::class,
			static function () {
				return new SnoozeFeatureFlags();
			}
		);

		$container->register(
			SnoozeOptionsProviderInterface::class,
			static function () {
				$c           = Plugin::get_service_container();
				$environment = $c->get( EnvironmentInterface::class );
				$credentials = $c->get( CredentialsInterface::class );

				$qpilot = QPilotServiceFactory::create(
					$environment->get_api_url(),
					(string) $credentials->get_auth_token(),
					(int) $credentials->get_site_id()
				);

				return new SnoozeOptionsProvider(
					$c->get( LoggerInterface::class ),
					$credentials,
					$qpilot
				);
			}
		);

		$container->register(
			SnoozeActionFilters::class,
			static function () {
				$c = Plugin::get_service_container();
				return new SnoozeActionFilters(
					$c->get( SnoozeSettingsInterface::class ),
					$c->get( LabelServiceInterface::class )
				);
			}
		);

		$container->register(
			SnoozeRenderer::class,
			static function () {
				$c = Plugin::get_service_container();
				return new SnoozeRenderer(
					$c->get( SnoozeSettingsInterface::class ),
					$c->get( SnoozeOptionsProviderInterface::class ),
					$c->get( TemplateRendererInterface::class ),
					$c->get( EnvironmentInterface::class )
				);
			}
		);

		$container->register(
			SnoozeAjaxController::class,
			static function () {
				$c = Plugin::get_service_container();

				$environment = $c->get( EnvironmentInterface::class );
				$credentials = $c->get( CredentialsInterface::class );
				$token       = (string) $credentials->get_auth_token();
				$site_id     = (int) $credentials->get_site_id();

				$qpilot = QPilotServiceFactory::create(
					$environment->get_api_url(),
					$token,
					$site_id
				);

				return new SnoozeAjaxController(
					$c->get( SnoozeSettingsInterface::class ),
					$qpilot,
					$credentials,
					$c->get( LoggerInterface::class ),
					$environment
				);
			}
		);
	}

	/**
	 * @inheritDoc
	 */
	public function boot( ServiceContainer $container ) {
		/** @var SnoozeActionFilters $filters */
		$filters = $container->get( SnoozeActionFilters::class );

		/** @var SnoozeRenderer $renderer */
		$renderer = $container->get( SnoozeRenderer::class );

		/** @var SnoozeAjaxController $controller */
		$controller = $container->get( SnoozeAjaxController::class );

		/** @var SnoozeOptionsProviderInterface $options_provider */
		$options_provider = $container->get( SnoozeOptionsProviderInterface::class );

		// --------- Action filters ---------
		add_filter( 'autoship_get_account_scheduled_orders_actions', array( $filters, 'swap_pause_action' ), 2, 3 );
		add_filter( 'autoship_scheduled_orders_display_actions_filter', array( $filters, 'filter_snoozed_actions' ), 11, 4 );
		add_filter( 'autoship_scheduled_order_status_display', array( $filters, 'status_display' ), 10, 3 );

		// --------- Render hooks ---------
		// Orders list — inline snooze form + Resume Early panel after each row.
		add_action( 'autoship_after_autoship_scheduled_orders_template_row', array( $renderer, 'render_snooze_form_row' ), 20, 3 );
		add_action( 'autoship_after_autoship_scheduled_orders_template_row', array( $renderer, 'render_resume_early_panel_row' ), 21, 3 );

		// Order detail page — banner before the header (priority 7), snooze
		// form (12) and Resume Early panel (13) between schedule form and
		// items summary.
		add_action( 'autoship_before_scheduled_order_edit', array( $renderer, 'render_snooze_notification_banner' ), 7, 3 );
		add_action( 'autoship_before_scheduled_order_view', array( $renderer, 'render_snooze_notification_banner' ), 7, 3 );
		add_action( 'autoship_before_scheduled_order_edit', array( $renderer, 'render_snooze_form_detail' ), 12, 3 );
		add_action( 'autoship_before_scheduled_order_view', array( $renderer, 'render_snooze_form_detail' ), 12, 3 );
		add_action( 'autoship_before_scheduled_order_edit', array( $renderer, 'render_resume_early_panel_detail' ), 13, 3 );
		add_action( 'autoship_before_scheduled_order_view', array( $renderer, 'render_resume_early_panel_detail' ), 13, 3 );

		// --------- AJAX endpoints ---------
		add_action( 'wp_ajax_autoship_snooze_order', array( $controller, 'snooze_order' ) );
		add_action( 'wp_ajax_autoship_cancel_snooze', array( $controller, 'cancel_snooze' ) );

		// --------- Cache invalidation ---------
		// Drop cached QMC frequencies whenever a setting that affects the
		// resolved option list changes. Without this, a stale transient can
		// continue to serve old values for up to an hour after the merchant
		// flips the source or edits the QMC connection.
		$invalidate_cache = static function () use ( $options_provider ) {
			$options_provider->clear_cache();
		};
		add_action( 'update_option_autoship_snooze_frequency_source', $invalidate_cache );
		add_action( 'add_option_autoship_snooze_frequency_source', $invalidate_cache );
		add_action( 'update_option_autoship_snooze_plugin_frequencies', $invalidate_cache );
		add_action( 'update_option_autoship_site_id', $invalidate_cache );

		// --------- Script enqueue ---------
		add_action( 'wp_enqueue_scripts', array( $renderer, 'enqueue_scripts' ), 20 );
	}

	/**
	 * @inheritDoc
	 */
	public function deactivate( ServiceContainer $container ): void {
		// Clear cached frequencies and feature flags so a re-activation
		// always hits a fresh slate.
		$site_id = $container->get( CredentialsInterface::class )->get_site_id();
		if ( null !== $site_id ) {
			delete_transient( 'autoship_snooze_frequencies_' . $site_id );
		}
	}

	/**
	 * @inheritDoc
	 */
	public function uninstall( ServiceContainer $container ): void {
		$site_id = $container->get( CredentialsInterface::class )->get_site_id();
		if ( null !== $site_id ) {
			delete_transient( 'autoship_snooze_frequencies_' . $site_id );
		}

		// Drop snooze-specific options.
		delete_option( 'autoship_snooze_enabled' );
		delete_option( 'autoship_snooze_action_label' );
		delete_option( 'autoship_snooze_pause_behavior' );
		delete_option( 'autoship_snooze_frequency_source' );
		delete_option( 'autoship_snooze_allow_custom_date' );
		delete_option( 'autoship_snooze_max_duration_days' );
		delete_option( 'autoship_snooze_plugin_frequencies' );
	}
}
