<?php

namespace UltraguardPro\modules\reputation_monitor;

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

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Reputation monitor intentionally queries live reputation data for admin summaries.

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

class ReputationMonitorModule extends AbstractModule {

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

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

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

    protected function allow_preview_mode(): bool {
        return true;
    }

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

        if ( method_exists( $this->plugin->settings, 'register_settings_schema' ) ) {
            $this->plugin->settings->register_settings_schema( 'reputation_monitor', 'reputation_monitor_', [
                'reputation_monitor_enabled'               => [ 'type' => 'bool', 'default' => true ],
                'reputation_monitor_google_api_key'        => [ 'type' => 'text', 'default' => '' ],
                'reputation_monitor_enable_spamhaus'       => [ 'type' => 'bool', 'default' => true ],
                'reputation_monitor_enable_mxtoolbox'      => [ 'type' => 'bool', 'default' => false ],
                'reputation_monitor_mxtoolbox_api_key'     => [ 'type' => 'text', 'default' => '' ],
                'reputation_monitor_enable_mcafee'         => [ 'type' => 'bool', 'default' => true ],
                'reputation_monitor_enable_norton'         => [ 'type' => 'bool', 'default' => true ],
                'reputation_monitor_enable_bing'           => [ 'type' => 'bool', 'default' => true ],
                'reputation_monitor_frequency'             => [ 'type' => 'select', 'default' => 'hourly', 'options' => [ 'every_30_minutes', 'hourly', 'every_3_hours', 'every_6_hours', 'every_12_hours', 'daily' ] ],
                'reputation_monitor_email_alert'           => [ 'type' => 'bool', 'default' => true ],
                'reputation_monitor_weekly_report'         => [ 'type' => 'bool', 'default' => false ],
                'reputation_monitor_alert_recipients'      => [ 'type' => 'array', 'default' => [] ],
                'reputation_monitor_webhook_alert'         => [ 'type' => 'bool', 'default' => false ],
                'reputation_monitor_webhook_url'           => [ 'type' => 'text', 'default' => '' ],
            ] );
        }

        ( new ajax\ReputationMonitorAjax( $this->plugin ) )->register();
        add_action( 'ultraguard_register_admin_pages', [ $this, 'register_pages' ], 115, 1 );
        ( new ReputationMonitorDashboardContributor( $this->plugin ) )->register();
        add_action( 'ultraguard_after_enqueue_assets', [ $this, 'enqueue_assets' ] );

        if ( ! $this->is_preview_mode() ) {
            add_filter( 'cron_schedules', [ $this, 'register_cron_schedules' ] );
            add_action( 'wp_loaded', [ $this, 'maybe_setup_schedule' ] );
            add_action( 'ultraguard_reputation_check', [ $this, 'run_hourly_check' ] );
            add_action( 'ultraguard_reputation_weekly_report', [ $this, 'send_weekly_report' ] );
            ( new ReputationMonitorNotifications( $this->plugin ) )->register();
            add_action( 'ultraguard_pro/reputation_monitor/check_complete', [ $this, 'handle_check_complete' ], 10, 1 );
        }

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

    private function ensure_schema_ready( schema\ReputationMonitorSchema $schema ): void {
        global $wpdb;

        foreach ( array_keys( $schema->get_schemas() ) as $table_name ) {
            $exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- query uses prepare(); table name is supplied as a value placeholder.
            if ( $exists === $table_name ) {
                continue;
            }

            $schema->install();
            DatabaseSchema::flush_cache();
            break;
        }
    }

    public function register_pages( $admin ): void {
        $admin->register_page( [
            'id'              => 'reputation-monitor',
            'page_title'      => __( 'Blacklist & Reputation Monitor', 'ultraguard-security-suite' ),
            'menu_title'      => __( 'Reputation Monitor', 'ultraguard-security-suite' ),
            'capability'      => 'manage_options',
            'scheme_callback' => [ new pages\ReputationMonitorDashboard( $this->plugin ), 'get_scheme' ],
            'parent_id'       => '',
            'priority'        => 115,
            'group'           => 'Monitoring',
            'icon'            => 'dashicons-search',
        ] );

        $admin->register_page( [
            'id'              => 'reputation-monitor-settings',
            'page_title'      => __( 'Reputation Monitor Settings', 'ultraguard-security-suite' ),
            'menu_title'      => __( 'Settings', 'ultraguard-security-suite' ),
            'capability'      => 'manage_options',
            'scheme_callback' => [ new pages\ReputationMonitorSettings( $this->plugin ), 'get_scheme' ],
            'parent_id'       => 'reputation-monitor',
            'priority'        => 116,
            'group'           => 'Monitoring',
            'icon'            => 'dashicons-admin-settings',
        ] );
    }

    public function register_cron_schedules( array $schedules ): array {
        $schedules['every_30_minutes'] = [
            'interval' => 30 * MINUTE_IN_SECONDS,
            'display'  => __( 'Every 30 Minutes', 'ultraguard-security-suite' ),
        ];
        $schedules['every_3_hours'] = [
            'interval' => 3 * HOUR_IN_SECONDS,
            'display'  => __( 'Every 3 Hours', 'ultraguard-security-suite' ),
        ];
        $schedules['every_6_hours'] = [
            'interval' => 6 * HOUR_IN_SECONDS,
            'display'  => __( 'Every 6 Hours', 'ultraguard-security-suite' ),
        ];
        $schedules['every_12_hours'] = [
            'interval' => 12 * HOUR_IN_SECONDS,
            'display'  => __( 'Every 12 Hours', 'ultraguard-security-suite' ),
        ];
        if ( ! isset( $schedules['weekly'] ) ) {
            $schedules['weekly'] = [
                'interval' => WEEK_IN_SECONDS,
                'display'  => __( 'Once Weekly', 'ultraguard-security-suite' ),
            ];
        }

        return $schedules;
    }

    public function maybe_setup_schedule(): void {
        $hook        = 'ultraguard_reputation_check';
        $report_hook = 'ultraguard_reputation_weekly_report';
        $enabled     = $this->option_enabled( 'reputation_monitor_enabled' );
        $schedule    = (string) $this->option( 'reputation_monitor_frequency', 'hourly' );
        $allowed     = [ 'every_30_minutes', 'hourly', 'every_3_hours', 'every_6_hours', 'every_12_hours', 'daily' ];

        if ( ! in_array( $schedule, $allowed, true ) ) {
            $schedule = 'hourly';
        }

        $current = wp_get_schedule( $hook );
        if ( ! $enabled ) {
            if ( $current ) {
                wp_clear_scheduled_hook( $hook );
            }
            wp_clear_scheduled_hook( $report_hook );
            return;
        }

        if ( $current !== $schedule ) {
            wp_clear_scheduled_hook( $hook );
            wp_schedule_event( time() + MINUTE_IN_SECONDS, $schedule, $hook );
        } elseif ( ! wp_next_scheduled( $hook ) ) {
            wp_schedule_event( time() + MINUTE_IN_SECONDS, $schedule, $hook );
        }

        if ( $this->option_enabled( 'reputation_monitor_weekly_report' ) ) {
            if ( ! wp_next_scheduled( $report_hook ) ) {
                wp_schedule_event( time() + DAY_IN_SECONDS, 'weekly', $report_hook );
            }
        } else {
            wp_clear_scheduled_hook( $report_hook );
        }
    }

    public function run_hourly_check(): void {
        if ( ! $this->option_enabled( 'reputation_monitor_enabled' ) ) {
            return;
        }

        ( new ReputationCheckEngine( $this->plugin ) )->run_all_checks();
    }

    public function handle_check_complete( array $summary ): void {
        if ( ! empty( $summary['overall_status'] ) && 'clean' !== $summary['overall_status'] ) {
            \UltraguardPro\core\Logger::warning(
                'Blacklist check completed with non-clean status.',
                [ 'summary' => $summary ]
            );
        }
    }

    public function send_weekly_report(): void {
        if ( ! $this->option_enabled( 'reputation_monitor_enabled' ) || ! $this->option_enabled( 'reputation_monitor_weekly_report' ) ) {
            return;
        }

        $email = sanitize_email( (string) get_option( 'admin_email', '' ) );
        if ( ! is_email( $email ) ) {
            return;
        }

        $engine  = new ReputationCheckEngine( $this->plugin );
        $summary = $engine->run_quick_summary();

        MailManager::notification( [
            'to'        => $email,
            'subject'   => __( 'UltraGuard Weekly Reputation Report', 'ultraguard-security-suite' ),
            'title'     => __( 'Weekly Reputation Summary', 'ultraguard-security-suite' ),
            'message'   => __( 'Here is your weekly domain and blacklist reputation summary from UltraGuard.', 'ultraguard-security-suite' ),
            'tone'      => 'danger' === ( $summary['overall_status'] ?? 'clean' ) ? 'danger' : 'info',
            'details'   => [
                __( 'Overall status', 'ultraguard-security-suite' )     => strtoupper( (string) ( $summary['overall_status'] ?? 'clean' ) ),
                __( 'Sources monitoring', 'ultraguard-security-suite' ) => (int) ( $summary['sources_monitoring'] ?? 0 ),
                __( 'Currently blacklisted', 'ultraguard-security-suite' ) => (int) ( $summary['currently_blacklisted'] ?? 0 ),
                __( 'Clean since', 'ultraguard-security-suite' )        => (string) ( $summary['clean_since'] ?? __( 'Unknown', 'ultraguard-security-suite' ) ),
                __( 'Total checks run', 'ultraguard-security-suite' )   => (int) ( $summary['total_checks_run'] ?? 0 ),
            ],
            'cta_url'   => admin_url( 'admin.php?page=ultraguard-security-suite-dashboard&ug_page=reputation-monitor' ),
            'cta_label' => __( 'Open Reputation Monitor', 'ultraguard-security-suite' ),
        ] );
    }

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

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

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

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

        wp_localize_script( 'ultraguard-reputation-monitor-page', 'ultraguardReputationMonitor', [
            'nonce'   => wp_create_nonce( 'ultraguard_admin_nonce' ),
            'ajaxUrl' => self_admin_url( 'admin-ajax.php' ),
            'i18n'    => [
                'checking' => __( 'Running reputation checks...', 'ultraguard-security-suite' ),
                'checked'  => __( 'Reputation check complete.', 'ultraguard-security-suite' ),
                'failed'   => __( 'Unable to complete the requested reputation action.', 'ultraguard-security-suite' ),
            ],
        ] );
    }
}
