<?php

namespace UltraguardPro\modules\auto_updater;

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

use UltraguardPro\Plugin;
use UltraguardPro\modules\core\AbstractModule;

class AutoUpdaterModule extends AbstractModule {

    public function __construct( Plugin $plugin ) {
        parent::__construct( $plugin );
        $this->plugin->settings->register_module_prefix( 'auto_updater_', 'auto_updater' );
    }

    public function get_id(): string {
        return 'auto_updater';
    }

    protected function requires_pro(): bool {
        return false;
    }

    public function boot(): void {
        $_db_tables = $this->plugin->modules->get_db_tables();
        if ( $_db_tables ) {
            $_db_tables->register_schema( new schema\AutoUpdaterSchema() );
        }

        if ( method_exists( $this->plugin->settings, 'register_settings_schema' ) ) {
            $this->plugin->settings->register_settings_schema( 'auto_updater', 'auto_updater_', [
                'auto_updater_plugins_enabled'       => [ 'type' => 'bool', 'default' => true ],
                'auto_updater_themes_enabled'        => [ 'type' => 'bool', 'default' => true ],
                'auto_updater_core_minor_enabled'    => [ 'type' => 'bool', 'default' => true ],
                'auto_updater_core_major_enabled'    => [ 'type' => 'bool', 'default' => false ],
                'auto_updater_schedule'              => [ 'type' => 'select', 'default' => 'daily', 'options' => [ 'disabled', 'daily', 'weekly' ] ],
                'auto_updater_schedule_time'         => [ 'type' => 'text', 'default' => '02:00' ],
                'auto_updater_schedule_day'          => [ 'type' => 'select', 'default' => 'sunday', 'options' => [ 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday' ] ],
                'auto_updater_security_only'         => [ 'type' => 'bool', 'default' => false ],
                'auto_updater_excluded_plugins'      => [ 'type' => 'textarea', 'default' => '' ],
                'auto_updater_excluded_themes'       => [ 'type' => 'textarea', 'default' => '' ],
                'auto_updater_email_summary'         => [ 'type' => 'bool', 'default' => true ],
                'auto_updater_alert_on_failure'      => [ 'type' => 'bool', 'default' => true ],
                'auto_updater_maintenance_mode'      => [ 'type' => 'bool', 'default' => true ],
            ] );
        }

        ( new ajax\AutoUpdaterAjax( $this->plugin ) )->register();
        add_action( 'ultraguard_register_admin_pages', [ $this, 'register_pages' ], 85, 1 );
        ( new AutoUpdaterDashboardContributor( $this->plugin ) )->register();
        $auto_update_prefix = 'auto_update_';
        add_filter( $auto_update_prefix . 'plugin', [ $this, 'filter_plugin_auto_updates' ], 10, 2 );
        add_filter( $auto_update_prefix . 'theme', [ $this, 'filter_theme_auto_updates' ], 10, 2 );
        add_filter( $auto_update_prefix . 'core', [ $this, 'filter_core_auto_updates' ], 10, 2 );
        add_action( 'upgrader_process_complete', [ $this, 'handle_upgrader_complete' ], 10, 2 );
        add_filter( 'cron_schedules', [ $this, 'register_cron_schedules' ] );
        add_action( 'wp_loaded', [ $this, 'maybe_setup_schedule' ] );
        add_action( 'ultraguard_auto_updater_check', [ $this, 'run_scheduled_updates' ] );
        ( new AutoUpdaterNotifications( $this->plugin ) )->register();
        add_action( 'ultraguard_after_enqueue_assets', [ $this, 'enqueue_assets' ] );

        do_action( 'ultraguard_pro/auto_updater/booted', $this );
    }

    public function register_pages( $admin ): void {
        $admin->register_page( [
            'id'              => 'auto-updater',
            'page_title'      => __( 'Auto Updater', 'ultraguard-security-suite' ),
            'menu_title'      => __( 'Auto Updater', 'ultraguard-security-suite' ),
            'capability'      => 'manage_options',
            'scheme_callback' => [ new pages\AutoUpdaterDashboard( $this->plugin ), 'get_scheme' ],
            'parent_id'       => '',
            'priority'        => 85,
            'group'           => 'Management',
            'icon'            => 'dashicons-update',
        ] );

        $admin->register_page( [
            'id'              => 'auto-updater-settings',
            'page_title'      => __( 'Auto Updater Settings', 'ultraguard-security-suite' ),
            'menu_title'      => __( 'Settings', 'ultraguard-security-suite' ),
            'capability'      => 'manage_options',
            'scheme_callback' => [ new pages\AutoUpdaterSettings( $this->plugin ), 'get_scheme' ],
            'parent_id'       => 'auto-updater',
            'priority'        => 86,
            'group'           => 'Management',
            'icon'            => 'dashicons-admin-settings',
        ] );
    }

    public function register_cron_schedules( array $schedules ): array {
        $schedules['weekly'] = [
            'interval' => WEEK_IN_SECONDS,
            'display'  => 'Once Weekly',
        ];

        return $schedules;
    }

    public function maybe_setup_schedule(): void {
        $hook     = 'ultraguard_auto_updater_check';
        $schedule = (string) $this->option( 'auto_updater_schedule', 'daily' );
        $current  = wp_get_schedule( $hook );

        if ( 'disabled' === $schedule ) {
            if ( $current ) {
                wp_clear_scheduled_hook( $hook );
            }
            return;
        }

        $wp_schedule = 'weekly' === $schedule ? 'weekly' : 'daily';
        if ( $current !== $wp_schedule ) {
            wp_clear_scheduled_hook( $hook );
            wp_schedule_event( time() + HOUR_IN_SECONDS, $wp_schedule, $hook );
        } elseif ( ! wp_next_scheduled( $hook ) ) {
            wp_schedule_event( time() + HOUR_IN_SECONDS, $wp_schedule, $hook );
        }
    }

    public function run_scheduled_updates(): void {
        ( new UpdateEngine( $this->plugin ) )->apply_all_pending_updates( 'scheduled' );
    }

    public function filter_plugin_auto_updates( $update, $item ) {
        return ( new UpdateEngine( $this->plugin ) )->filter_plugin_auto_updates( $update, $item );
    }

    public function filter_theme_auto_updates( $update, $item ) {
        return ( new UpdateEngine( $this->plugin ) )->filter_theme_auto_updates( $update, $item );
    }

    public function filter_core_auto_updates( $update, $item ) {
        return ( new UpdateEngine( $this->plugin ) )->filter_core_auto_updates( $update, $item );
    }

    public function handle_upgrader_complete( $upgrader, array $hook_extra ): void {
        ( new UpdateEngine( $this->plugin ) )->log_upgrader_result( $hook_extra );
    }

    public function enqueue_assets(): void {
        $ug_page = sanitize_key( wp_unslash( $_GET['ug_page'] ?? ''  ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only plugin screen detection.
        if ( ! in_array( $ug_page, [ 'auto-updater', 'auto-updater-settings' ], true ) ) {
            return;
        }

        $module_url = plugin_dir_url( __FILE__ );
        $version    = defined( 'ULTRAGUARD_PRO_VERSION' ) ? ULTRAGUARD_PRO_VERSION : '1.0.0';

        wp_enqueue_style(
            'ultraguard-auto-updater-page',
            $module_url . 'assets/css/auto-updater-page.css',
            [ 'admin-base', 'admin-components' ],
            $version
        );

        wp_enqueue_script(
            'ultraguard-auto-updater-page',
            $module_url . 'assets/js/auto-updater-page.js',
            [ 'jquery', 'ultraguard-core', 'ultraguard-managers' ],
            $version,
            true
        );

        wp_localize_script( 'ultraguard-auto-updater-page', 'ultraguardAutoUpdater', [
            'nonce'   => wp_create_nonce( 'ultraguard_admin_nonce' ),
            'ajaxUrl' => self_admin_url( 'admin-ajax.php' ),
            'i18n'    => [
                'running' => __( 'Applying updates...', 'ultraguard-security-suite' ),
                'failed'  => __( 'Unable to complete the requested update action.', 'ultraguard-security-suite' ),
            ],
        ] );
    }
}
