<?php

namespace AIPT\Api\AutomationJobs;

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

/**
 * Job Execution Handler
 * 
 * Handles dynamic job execution hooks for WordPress cron
 * 
 * @since 2.3.0
 */
class JobExecutionHandler {
    
    /**
     * Initialize job execution hooks
     *
     * This method should be called during plugin initialization
     * to set up dynamic job execution hooks
     */
    public static function init() {

        add_action('init', [self::class, 'register_dynamic_hooks'], 20);

        add_action('wp_loaded', [self::class, 'register_catch_all_hook'], 30);
    }
    
    /**
     * Register dynamic job execution hooks
     * 
     * This creates hooks for individual job execution
     */
    public static function register_dynamic_hooks() {

        try {
            $job_manager = new AutomationJobManager();

            $preparing_jobs = $job_manager->getJobs(['status' => 'preparing'], 50);
            $ready_jobs = $job_manager->getJobs(['status' => 'ready'], 50);
            $running_jobs = $job_manager->getJobs(['status' => 'running'], 50);
            $paused_jobs = $job_manager->getJobs(['status' => 'paused'], 50);

            $active_jobs = array_merge($preparing_jobs, $ready_jobs, $running_jobs, $paused_jobs);
            
            foreach ($active_jobs as $job) {
                $hook_name = 'aipt_execute_job_' . $job->id;
                

                if (!has_action($hook_name)) {
                    add_action($hook_name, [self::class, 'execute_job_callback'], 10, 1);
                }
            }
            
        } catch (\Exception $e) {

        }
    }
    
    /**
     * Job execution callback
     * 
     * This is called by WordPress cron for individual job execution
     * 
     * @param int $job_id Job ID to execute
     */
    public static function execute_job_callback($job_id) {
        try {

            $job_manager = new AutomationJobManager();
            $logger = new JobLogger();
            $executor = new JobExecutor($job_manager, $logger);
            

            $executor->executeJob($job_id);
            
        } catch (\Exception $e) {

            

            try {
                $job_manager = new AutomationJobManager();
                $job_manager->updateJobStatus($job_id, 'failed', $e->getMessage());
            } catch (\Exception $update_error) {
            }
        }
    }
    
    /**
     * Register job execution hook for a specific job
     * 
     * @param int $job_id Job ID
     */
    public static function register_job_hook($job_id) {
        $hook_name = 'aipt_execute_job_' . $job_id;
        
        if (!has_action($hook_name)) {
            add_action($hook_name, [self::class, 'execute_job_callback'], 10, 1);
        }
    }
    
    /**
     * Unregister job execution hook for a specific job
     *
     * @param int $job_id Job ID
     */
    public static function unregister_job_hook($job_id) {
        $hook_name = 'aipt_execute_job_' . $job_id;
        remove_action($hook_name, [self::class, 'execute_job_callback'], 10);
    }

    /**
     * Register catch-all hook for job execution
     *
     * This ensures all job execution hooks are properly registered
     */
    public static function register_catch_all_hook() {

        add_action('aipt_execute_any_job', [self::class, 'execute_job_callback'], 10, 1);

        global $wpdb;

        try {
            $jobs_table = $wpdb->prefix . 'aipt_automation_jobs';

            if ($wpdb->get_var("SHOW TABLES LIKE '{$jobs_table}'") !== $jobs_table) {
                return;
            }

            $active_jobs = $wpdb->get_results(
                "SELECT id FROM {$jobs_table} WHERE status IN ('preparing', 'ready', 'running', 'paused')",
                ARRAY_A
            );

            foreach ($active_jobs as $job) {
                $hook_name = 'aipt_execute_job_' . $job['id'];
                if (!has_action($hook_name)) {
                    add_action($hook_name, [self::class, 'execute_job_callback'], 10, 1);
                }
            }

        } catch (\Exception $e) {
        }
    }
}
