<?php

declare(strict_types=1);

namespace SecurWP\Modules\Scanner\Queue;

use SecurWP\Modules\Scanner\Queue\ScanQueue;


use SecurWP\Modules\Scanner\Queue\ScanWorker;

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

class ScanCron {
    
    const HOOK = 'securwp_scan_cron_check';
    const STUCK_THRESHOLD = 90; // seconds - must exceed max tick duration on slow shared hosting
    
    /**
     * Schedule the cron job.
     */
    public static function schedule() {
        add_filter( 'cron_schedules', [ __CLASS__, 'add_cron_interval' ] );
        add_action( self::HOOK, [ __CLASS__, 'check_and_resume' ] );
        add_action( 'securwp_scheduled_scan_job', [ __CLASS__, 'handle_scheduled_scan' ] );

        if ( ! wp_next_scheduled( self::HOOK ) ) {
            $scheduled = wp_schedule_event( time() + 60, 'every_minute', self::HOOK );
            if ( ! $scheduled ) {
                wp_schedule_single_event( time() + 60, self::HOOK );
            }
        }
    }
    
    /**
     * Unschedule the cron job.
     */
    public static function unschedule() {
        $timestamp = wp_next_scheduled( self::HOOK );
        
        if ( $timestamp ) {
            wp_unschedule_event( $timestamp, self::HOOK );
        }
    }
    
    /**
     * Add custom cron interval.
     * 
     * @param array $schedules Existing schedules
     * @return array Modified schedules
     */
    public static function add_cron_interval( $schedules ) {
        $schedules['every_minute'] = [
            'interval' => 60,
            'display'  => 'Every Minute',
        ];
        
        return $schedules;
    }

    /**
     * Handle the scheduled scan event.
     */
    public static function handle_scheduled_scan() {
        if ( ScanQueue::is_active() ) {
            return;
        }

        $key_error = \SecurWP\Modules\Cloud\Service\CloudSettings::get_key_error();
        if ( $key_error ) {
            securwp_log( 'SecurWP: Scheduled scan skipped - encryption key issue (' . ( $key_error['code'] ?? 'unknown' ) . '). Resolve via the SecurWP admin panel.' );
            return;
        }
        $cloud_settings = \SecurWP\Modules\Cloud\Service\CloudSettings::get_all();
        if ( empty( $cloud_settings['site_token'] ) || empty( $cloud_settings['site_secret'] ) ) {
            return;
        }

        if ( ! class_exists( '\SecurWP\Modules\Cloud\Service\Entitlements' ) ) {
            require_once dirname( dirname( __DIR__ ) ) . '/Cloud/Service/Entitlements.php';
        }

        if ( ! class_exists( '\SecurWP\Modules\Cloud\Service\Entitlements' ) || ! \SecurWP\Modules\Cloud\Service\Entitlements::allowsScheduledScans() ) {
            return;
        }

        if ( ! class_exists( 'SecurWP\\Modules\\Scanner\\Service\\ScannerSettings' ) ) {
            require_once dirname( __DIR__ ) . '/Service/ScannerSettings.php';
        }
        $intensity = \SecurWP\Modules\Scanner\Service\ScannerSettings::get( 'scanIntensity' );
        $type = ( $intensity === 'deep' ) ? 'deep' : 'standard';

        $scan_id = 'scan_' . wp_generate_uuid4();

        if ( ! class_exists( '\\SecurWP\\Modules\\Cloud\\Services\\CloudScanner' ) ) {
             require_once dirname( dirname( __DIR__ ) ) . '/Cloud/Services/CloudScanner.php';
        }
        if ( class_exists( '\\SecurWP\\Modules\\Cloud\\Services\\CloudScanner' ) ) {
             $cloud = new \SecurWP\Modules\Cloud\Services\CloudScanner();
             $preflight = ScanWorker::run_preflight_check( $scan_id, $cloud );
             
             if ( is_wp_error( $preflight ) ) {
                 securwp_log( 'SecurWP: Scheduled scan ABORTED (Preflight Failed): ' . $preflight->get_error_message() );
                 return;
             }

             set_transient( 'securwp_scan_preflight_' . $scan_id, true, HOUR_IN_SECONDS );
        }

        $queue = ScanQueue::create( $type, 'scheduled', $scan_id );

        if ( ! $queue ) {
            securwp_log( 'SecurWP: Scheduled scan ABORTED - queue creation failed (scan may already be active).' );
            return;
        }

        ScanWorker::dispatch_next();
    }
    
    /**
     * Check if scan is stuck and resume if needed.
     */
    public static function check_and_resume() {
        if ( ! ScanQueue::is_active() ) {
            return;
        }

        if ( ! class_exists( TaskScheduler::class ) ) {
            require_once __DIR__ . '/TaskScheduler.php';
        }

        $queue = ScanQueue::get();
        $scan_id = is_array( $queue ) ? (string) ( $queue['id'] ?? '' ) : '';
        if ( '' === $scan_id ) {
            return;
        }

        TaskScheduler::ensure_progress( $scan_id );
    }
    
    /**
     * Initialize the cron system.
     * Should be called on plugin activation.
     */
    public static function init() {
        self::schedule();
    }
    
    /**
     * Clean up on plugin deactivation.
     */
    public static function cleanup() {
        self::unschedule();
        
        // Cancel any running scan
        $queue = ScanQueue::get();
        if ( $queue ) {
            ScanQueue::fail(
                'Plugin deactivated',
                [
                    'error_code' => 'plugin_deactivated',
                    'stage'      => 'plugin_lifecycle',
                    'retryable'  => false,
                    'status_code'=> 409,
                ]
            );
            ScanQueue::cleanup_task_queue( (string) ( $queue['id'] ?? '' ) );
        }
    }
}
