<?php
/**
 * Handles deletion of fix items for the RANK AI plugin.
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly.
}

class Rank_Delete_Handler {

    /**
     * Initialize hooks.
     */
    public static function init() {
        // Register AJAX handler for deleting fix items
        add_action( 'wp_ajax_rank_delete_fix_item', array( __CLASS__, 'ajax_delete_fix_item' ) );
        // Register AJAX handler for deleting all fixes in a category
        add_action( 'wp_ajax_rank_delete_category_fixes', array( __CLASS__, 'ajax_delete_category_fixes' ) );
    }

    /**
     * AJAX handler for deleting a fix item.
     */
    public static function ajax_delete_fix_item() {
        // Tell PHP to stop execution when the client disconnects
        ignore_user_abort(false);
        
        // Set a reasonable timeout for this specific request
        set_time_limit(10);
        
        // Close the session to prevent blocking
        if (session_status() === PHP_SESSION_ACTIVE) {
            session_write_close();
        }
        
        check_ajax_referer('rank_ajax_nonce', 'nonce');
        
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Permission denied.', 403);
        }
        
        // Get and sanitize parameters
        $category = isset($_POST['category']) ? sanitize_key($_POST['category']) : '';
        $is_option = isset($_POST['is_option']) && $_POST['is_option'] === 'true';
        
        if (empty($category)) {
            wp_send_json_error('Missing required parameters', 400);
        }
        
        // Handle different types of fixes
        if ($is_option) {
            // Handle option-based fixes (broken links)
            $old_url = isset($_POST['old_url']) ? sanitize_text_field($_POST['old_url']) : '';
            if (empty($old_url)) {
                wp_send_json_error('Missing old URL parameter', 400);
            }
            
            $option_name = '';
            if ($category === 'broken_links_internal') {
                $option_name = 'rank_internal_url_replacements';
            } elseif ($category === 'broken_links_external') {
                $option_name = 'rank_external_url_replacements';
            }
            
            if (empty($option_name)) {
                wp_send_json_error('Invalid category for option-based fix', 400);
            }
            
            // Get current replacements
            $replacements = get_option($option_name, []);
            
            // Find the correct key - it might be a composite key or the broken URL itself
            $key_to_delete = null;
            
            // First, try direct match (for legacy data or simple keys)
            if (array_key_exists($old_url, $replacements)) {
                $key_to_delete = $old_url;
            } else {
                // Search for composite keys that contain this broken URL
                foreach ($replacements as $key => $data) {
                    // Check if this is a composite key containing the broken URL
                    if (strpos($key, '::context::') !== false) {
                        $broken_url_part = explode('::context::', $key)[0];
                        if ($broken_url_part === $old_url) {
                            $key_to_delete = $key;
                            break;
                        }
                    }
                    // Also check the stored broken_url field
                    if (is_array($data) && isset($data['broken_url']) && $data['broken_url'] === $old_url) {
                        $key_to_delete = $key;
                        break;
                    }
                }
            }
            
            // Delete the item if key was found
            if ($key_to_delete !== null && is_array($replacements)) {
                unset($replacements[$key_to_delete]);
                update_option($option_name, $replacements, false);
                wp_send_json_success();
            } else {
                wp_send_json_error('Old URL not found in replacements', 404);
            }
        } else {
            // Handle database-based fixes
            $post_id = isset($_POST['post_id']) ? absint($_POST['post_id']) : 0;
            $object_id = isset($_POST['object_id']) ? absint($_POST['object_id']) : 0;
            $issue_type = isset($_POST['issue_type']) ? sanitize_key($_POST['issue_type']) : $category;
            
            if ($post_id <= 0) {
                wp_send_json_error('Invalid post ID', 400);
            }
            
            // Map category to override_type
            $override_type = '';
            switch ($category) {
                case 'missing_meta_description':
                case 'short_meta_description':
                case 'long_meta_description':
                    $override_type = 'meta_description';
                    break;
                case 'missing_title_tag':
                case 'short_title_tag':
                case 'long_title_tag':
                    $override_type = 'title';
                    break;
                case 'missing_alt_tags':
                case 'image_alt':
                    $override_type = 'image_alt';
                    break;
                default:
                    wp_send_json_error('Invalid category for database-based fix', 400);
            }
            
            // Delete the item from the database
            $result = self::delete_seo_data($post_id, $object_id, $override_type, $issue_type);
            
            if ($result) {
                wp_send_json_success();
            } else {
                wp_send_json_error('Failed to delete database value', 500);
            }
        }
    }
    
    /**
     * Delete SEO data from the database.
     *
     * @param int    $post_id       The post ID.
     * @param int    $object_id     The object ID (for image_alt, this is the attachment ID).
     * @param string $override_type The type of override (meta_description, title, image_alt).
     * @param string $issue_type    The specific issue type.
     * @return bool True on success, false on failure.
     */
    public static function delete_seo_data($post_id, $object_id, $override_type, $issue_type = null) {
        global $wpdb;
        
        // Ensure RANK_TABLE_NAME is defined
        if (!defined('RANK_TABLE_NAME')) {
            error_log('RANK Plugin Error: RANK_TABLE_NAME constant not defined in Rank_Delete_Handler::delete_seo_data.');
            return false;
        }
        
        $table_name = $wpdb->prefix . RANK_TABLE_NAME;
        
        // Ensure $post_id is an integer
        $post_id = intval($post_id);
        if ($post_id <= 0) {
            error_log("Invalid Post ID for override type $override_type.");
            return false;
        }
        
        // Ensure $object_id is an integer
        $object_id = intval($object_id);
        
        // Sanitize override_type
        $allowed_types = array('meta_description', 'title', 'image_alt');
        if (!in_array($override_type, $allowed_types, true)) {
            error_log("Invalid Override Type: $override_type.");
            return false;
        }
        
        // Prepare the WHERE clause
        $where = array(
            'post_id' => $post_id,
            'override_type' => $override_type
        );
        
        // Add object_id to WHERE clause if it's an image_alt override
        if ($override_type === 'image_alt' && $object_id > 0) {
            $where['object_id'] = $object_id;
        }
        
        // Add issue_type to WHERE clause if provided
        if ($issue_type) {
            $where['issue_type'] = $issue_type;
        }
        
        // Delete the row from the database
        $result = $wpdb->delete($table_name, $where);
        
        if (false === $result) {
            error_log("Failed to delete SEO data. WPDB Error: " . $wpdb->last_error);
            return false;
        }
        
        
        return true;
    }
    
    /**
     * AJAX handler for deleting all fixes in a category.
     */
    public static function ajax_delete_category_fixes() {
        // Tell PHP to stop execution when the client disconnects
        ignore_user_abort(false);
        
        // Set a reasonable timeout for this specific request
        set_time_limit(30);
        
        // Close the session to prevent blocking
        if (session_status() === PHP_SESSION_ACTIVE) {
            session_write_close();
        }
        
        check_ajax_referer('rank_ajax_nonce', 'nonce');
        
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Permission denied.', 403);
        }
        
        // Get and sanitize parameters
        $category = isset($_POST['category']) ? sanitize_key($_POST['category']) : '';
        $issue_type = isset($_POST['issue_type']) ? sanitize_key($_POST['issue_type']) : $category;
        
        if (empty($category)) {
            wp_send_json_error('Missing required parameters', 400);
        }
        
        // Determine if this is an option-based category (broken links)
        $is_option = false;
        $option_name = '';
        
        if ($category === 'broken_links_internal') {
            $is_option = true;
            $option_name = 'rank_internal_url_replacements';
        } elseif ($category === 'broken_links_external') {
            $is_option = true;
            $option_name = 'rank_external_url_replacements';
        }
        
        if ($is_option) {
            // Delete all option-based fixes (broken links)
            if (empty($option_name)) {
                wp_send_json_error('Invalid category for option-based fix', 400);
            }
            
            // Simply delete the entire option
            $deleted = delete_option($option_name);
            
            // Invalidate frontend filter caches
            if ( class_exists('Rank_Frontend_Filters', false) ) {
                Rank_Frontend_Filters::invalidate_caches();
            }
            
            if ($deleted) {
                wp_send_json_success(array('message' => 'All fixes deleted successfully.'));
            } else {
                // Option might not exist, which is also success
                wp_send_json_success(array('message' => 'All fixes deleted successfully.'));
            }
        } else {
            // Handle database-based fixes
            // Map category to override_type
            $override_type = '';
            switch ($category) {
                case 'missing_meta_description':
                case 'short_meta_description':
                case 'long_meta_description':
                    $override_type = 'meta_description';
                    break;
                case 'missing_title_tag':
                case 'short_title_tag':
                case 'long_title_tag':
                    $override_type = 'title';
                    break;
                case 'missing_alt_tags':
                case 'image_alt':
                    $override_type = 'image_alt';
                    // Map image_alt category to missing_alt_tags issue_type for consistency
                    if ($issue_type === 'image_alt' || $issue_type === $category) {
                        $issue_type = 'missing_alt_tags';
                    }
                    break;
                default:
                    wp_send_json_error('Invalid category for database-based fix', 400);
            }
            
            // Delete all records for this override_type and issue_type
            $result = self::delete_all_seo_data_by_category($override_type, $issue_type);
            
            if ($result !== false) {
                wp_send_json_success(array(
                    'message' => 'All fixes deleted successfully.',
                    'deleted_count' => $result
                ));
            } else {
                wp_send_json_error('Failed to delete fixes', 500);
            }
        }
    }
    
    /**
     * Delete all SEO data for a specific category (override_type and issue_type).
     *
     * @param string $override_type The type of override (meta_description, title, image_alt).
     * @param string $issue_type    The specific issue type.
     * @return int|false Number of rows deleted, or false on failure.
     */
    public static function delete_all_seo_data_by_category($override_type, $issue_type = null) {
        global $wpdb;
        
        // Ensure RANK_TABLE_NAME is defined
        if (!defined('RANK_TABLE_NAME')) {
            error_log('RANK Plugin Error: RANK_TABLE_NAME constant not defined in Rank_Delete_Handler::delete_all_seo_data_by_category.');
            return false;
        }
        
        $table_name = $wpdb->prefix . RANK_TABLE_NAME;
        
        // Sanitize override_type
        $allowed_types = array('meta_description', 'title', 'image_alt');
        if (!in_array($override_type, $allowed_types, true)) {
            error_log("Invalid Override Type: $override_type.");
            return false;
        }
        
        // Build WHERE clause
        $where = array('override_type' => $override_type);
        
        // Add issue_type to WHERE clause if provided
        if ($issue_type) {
            $where['issue_type'] = $issue_type;
        }
        
        // Delete all matching rows
        $deleted = $wpdb->delete($table_name, $where);
        
        if (false === $deleted) {
            error_log("Failed to delete SEO data. WPDB Error: " . $wpdb->last_error);
            return false;
        }
        
        // Invalidate frontend filter caches
        if ( class_exists('Rank_Frontend_Filters', false) ) {
            Rank_Frontend_Filters::invalidate_caches();
        }
        
        return $deleted;
    }
}

// Initialize the class
// Use plugins_loaded hook instead of init to ensure the AJAX handler is registered early enough
add_action('plugins_loaded', array('Rank_Delete_Handler', 'init'));