<?php
/**
 * Database Optimization Module
 *
 * Provides WooCommerce and WordPress database maintenance including cleanup
 * of expired sessions, orphaned data, revisions, transients, and more.
 *
 * @package Mamba\Modules\DB
 * @since   1.0.0
 */

namespace Mamba\Modules\DB;

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

use Mamba\Modules\DB\Services\DatabaseOptimizer;
use Mamba\Modules\DB\Services\Admin\DbActions;

/**
 * Class Module
 *
 * Main database module that registers cleanup tasks, AJAX handlers,
 * cron schedules, and renders the database optimization admin tab.
 *
 * @since 1.0.0
 */
final class Module {
        public function register(): void {
        // Register the DB tab using the action hook system
        add_action('mamba/admin/tab/db', [$this, 'renderTab'], 10, 1);

        // Register AJAX handlers
        add_action('wp_ajax_mamba_db_run_task', [DbActions::class, 'handleRunTask']);
        add_action('wp_ajax_mamba_db_get_counts', [DbActions::class, 'handleGetCounts']);
        add_action('wp_ajax_mamba_db_get_overview', [DbActions::class, 'handleGetOverview']);

        // Register settings save handler
        add_action('admin_post_mamba_db_save', [$this, 'handleSaveSettings']);

        // Register cron schedules
        add_filter('cron_schedules', [$this, 'addDbSchedules']);

        // Register cron hooks for each task
        $optimizer = new DatabaseOptimizer();
        foreach ($optimizer->getTaskIds() as $taskId) {
            add_action('mamba_db_task_' . $taskId, [$optimizer, 'executeTask'], 10, 1);
        }

        // Schedule tasks if enabled
        add_action('init', [$this, 'scheduleTasks']);
        
        // Enqueue scripts for DB tab
        add_action('admin_enqueue_scripts', [$this, 'enqueueDbScripts']);
    }

    public function renderTab(\Mamba\Support\Paths $paths): void {
        if (!current_user_can('manage_woocommerce')) {
            wp_die(esc_html(__('Insufficient permissions.', 'mamba-cache-for-woocommerce')));
        }

        include __DIR__ . '/views/TabDb.php';
    }
    
    /**
     * Enqueue scripts for DB tab
     */
    public function enqueueDbScripts(string $hook): void {
        // Only load on Mamba admin page with DB tab
        if (strpos($hook, 'mamba-cache-for-woocommerce') === false || !isset($_GET['tab']) || sanitize_key(wp_unslash($_GET['tab'])) !== 'db') {
            return;
        }
        
        // Localize MambaDB for DB tab JavaScript - use mamba-admin script which is loaded on all admin pages
        wp_localize_script('mamba-admin', 'MambaDB', [
            'ajaxurl' => admin_url('admin-ajax.php'),
            'nonce' => wp_create_nonce('mamba_db_optimize'),
        ]);
    }
    
    public function addDbSchedules(array $schedules): array {
        $schedules['every_6_hours'] = [
            'interval' => 6 * HOUR_IN_SECONDS,
            'display' => __('Every 6 hours', 'mamba-cache-for-woocommerce')
        ];
        $schedules['every_12_hours'] = [
            'interval' => 12 * HOUR_IN_SECONDS,
            'display' => __('Every 12 hours', 'mamba-cache-for-woocommerce')
        ];
        $schedules['every_2_days'] = [
            'interval' => 2 * DAY_IN_SECONDS,
            'display' => __('Every 2 days', 'mamba-cache-for-woocommerce')
        ];
        $schedules['weekly'] = [
            'interval' => WEEK_IN_SECONDS,
            'display' => __('Weekly', 'mamba-cache-for-woocommerce')
        ];
        
        return $schedules;
    }
    
    public function handleSaveSettings(): void {
        if (!current_user_can('manage_woocommerce')) {
            wp_die(esc_html(__('Insufficient permissions.', 'mamba-cache-for-woocommerce')));
        }
        
        check_admin_referer('mamba_db_save');
        
        $input = isset($_POST['task']) ? wp_unslash($_POST['task']) : [];
        $settings = get_option('mamba_db_optimizer_settings', []);
        $optimizer = new DatabaseOptimizer();
        
        foreach ($optimizer->getTasks() as $taskId => $task) {
            $taskInput = $input[$taskId] ?? [];
            $enabled = !empty($taskInput['enabled']);
            $interval = isset($taskInput['interval']) ? sanitize_text_field($taskInput['interval']) : ($task['default_interval'] ?? 'weekly');
            
            // Validate interval
            $valid_schedules = array_merge(
                array_keys(wp_get_schedules()),
                ['daily'] // WP core default, included in wp_get_schedules() already but harmless here
            );
            if (!in_array($interval, $valid_schedules, true)) {
                $interval = $task['default_interval'] ?? 'weekly';
            }
            
            $args = $this->sanitizeArgs($taskId, $taskInput['args'] ?? []);
            
            $settings[$taskId]['enabled'] = $enabled ? 1 : 0;
            $settings[$taskId]['interval'] = $interval;
            $settings[$taskId]['args'] = $args;
            
            $hook = 'mamba_db_task_' . $taskId;
            
            // Clear existing schedule with args (more precise)
            wp_clear_scheduled_hook($hook, [$taskId]);
            
            // Schedule if enabled
            if ($enabled) {
                $start = time() + MINUTE_IN_SECONDS;
                wp_schedule_event($start, $interval, $hook, [$taskId]);
            }
        }
        
        update_option('mamba_db_optimizer_settings', $settings);
        
        // Redirect back with success message
        $redirect = add_query_arg('saved', '1', wp_get_referer());
        wp_safe_redirect($redirect);
        exit;
    }
    
    private function sanitizeArgs(string $taskId, array $args): array {
        $task = (new DatabaseOptimizer())->getTask($taskId);
        if (!$task) {
            return [];
        }
        
        $sanitized = [];
        
        if (!empty($task['fields']['retention_days'])) {
            $allowed = array_map('intval', $task['fields']['retention_days']);
            $val = isset($args['retention_days']) ? intval($args['retention_days']) : ($allowed[0] ?? 30);
            $sanitized['retention_days'] = in_array($val, $allowed, true) ? $val : $allowed[0];
        }
        
        if (!empty($task['fields']['retention_hours'])) {
            $allowed = array_map('intval', $task['fields']['retention_hours']);
            $val = isset($args['retention_hours']) ? intval($args['retention_hours']) : ($allowed[0] ?? 24);
            $sanitized['retention_hours'] = in_array($val, $allowed, true) ? $val : $allowed[0];
        }
        
        if (!empty($task['fields']['months'])) {
            $allowed = array_map('intval', $task['fields']['months']);
            $val = isset($args['months']) ? intval($args['months']) : 6;
            $sanitized['months'] = in_array($val, $allowed, true) ? $val : 6;
        }
        
        if (!empty($task['fields']['statuses'])) {
            $allowed = array_map('sanitize_text_field', $task['fields']['statuses']);
            $selected = array_values(array_intersect($allowed, array_map('sanitize_text_field', (array)($args['statuses'] ?? []))));
            $sanitized['statuses'] = !empty($selected) ? $selected : $allowed;
        }
        
        return $sanitized;
    }
    
    public function scheduleTasks(): void {
        $optimizer = new DatabaseOptimizer();
        $settings = get_option('mamba_db_optimizer_settings', []);

        foreach ($optimizer->getTasks() as $taskId => $task) {
            $taskSettings = $settings[$taskId] ?? [];
            $enabled = !empty($taskSettings['enabled']);
            $interval = $taskSettings['interval'] ?? ($task['default_interval'] ?? 'weekly');
            
            // Validate interval
            $valid_schedules = array_merge(
                array_keys(wp_get_schedules()),
                ['daily'] // WP core default, included in wp_get_schedules() already but harmless here
            );
            if (!in_array($interval, $valid_schedules, true)) {
                $interval = $task['default_interval'] ?? 'weekly';
            }

            $hook = 'mamba_db_task_' . $taskId;
            $args = [$taskId];

            $next = wp_next_scheduled($hook, $args);

            if ($enabled) {
                if (!$next) {
                    // first run starts soon; don't delay a full interval
                    wp_schedule_event(time() + MINUTE_IN_SECONDS, $interval, $hook, $args);
                }
            } else {
                if ($next) {
                    wp_unschedule_event($next, $hook, $args);
                }
            }
        }
    }
    
}


