<?php

if (!defined('WPINC')) {
    die;
}

class Aysa_Redirect_Processor {
    
    private $confidence_scorer;
    private $audit_logger;
    private $tracker_table;
    
    public function __construct() {
        global $wpdb;
        $this->confidence_scorer = new Aysa_Confidence_Scorer();
        $this->audit_logger = new Aysa_Audit_Logger();
        $this->tracker_table = esc_sql($wpdb->prefix . 'aysa_404_tracker');
    }
    
    public function process($job_data) {
        $error_url = $job_data['url'];
        
        $suggested_redirects = $this->find_redirect_suggestions($error_url);
        
        if (empty($suggested_redirects)) {
            return new WP_Error('no_suggestions', 'No redirect suggestions found for URL: ' . $error_url);
        }
        
        $best_suggestion = $suggested_redirects[0];
        $confidence_result = $this->confidence_scorer->calculate_redirect_confidence($job_data, $best_suggestion['url']);
        
        $automation_config = get_option('aysa_automation_config', array());
        $threshold = $automation_config['confidence_threshold'] ?? 0.7;
        
        if ($confidence_result['score'] >= $threshold) {
            return $this->create_automatic_redirect($error_url, $best_suggestion, $confidence_result);
        } else {
            return $this->queue_redirect_for_review($error_url, $suggested_redirects, $confidence_result);
        }
    }
    
    private function find_redirect_suggestions($error_url) {
        $suggestions = array();
        
        $url_parts = wp_parse_url($error_url);
        $path = $url_parts['path'] ?? '';
        
        $path_segments = array_filter(explode('/', trim($path, '/')));
        
        if (empty($path_segments)) {
            return $suggestions;
        }
        
        $suggestions = array_merge(
            $suggestions,
            $this->find_similar_posts($path_segments),
            $this->find_similar_pages($path_segments),
            $this->find_similar_categories($path_segments)
        );
        
        if (class_exists('WooCommerce')) {
            $suggestions = array_merge(
                $suggestions,
                $this->find_similar_products($path_segments)
            );
        }
        
        usort($suggestions, function($a, $b) {
            return $b['similarity'] <=> $a['similarity'];
        });
        
        return array_slice($suggestions, 0, 5);
    }
    
    private function find_similar_posts($path_segments) {
        global $wpdb;
        
        $suggestions = array();
        $search_terms = implode(' ', $path_segments);
        
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Reviewed release query uses WordPress or plugin-owned operational tables; current job, billing and idempotency state must not be cached because stale reads can duplicate or mis-order work.
        $posts = $wpdb->get_results($wpdb->prepare(
            "SELECT ID, post_title, post_name, post_type 
             FROM {$wpdb->posts} 
             WHERE post_status = 'publish' 
             AND post_type IN ('post', 'page')
             AND (post_title LIKE %s OR post_name LIKE %s)
             LIMIT 10",
            '%' . $wpdb->esc_like($search_terms) . '%',
            '%' . $wpdb->esc_like(implode('-', $path_segments)) . '%'
        ));
        
        foreach ($posts as $post) {
            $similarity = $this->calculate_text_similarity($path_segments, array($post->post_name, $post->post_title));
            
            if ($similarity > 0.3) {
                $suggestions[] = array(
                    'url' => get_permalink($post->ID),
                    'title' => $post->post_title,
                    'type' => $post->post_type,
                    'similarity' => $similarity
                );
            }
        }
        
        return $suggestions;
    }
    
    private function find_similar_pages($path_segments) {
        global $wpdb;
        
        $suggestions = array();
        
        foreach ($path_segments as $segment) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Reviewed release query uses WordPress or plugin-owned operational tables; current job, billing and idempotency state must not be cached because stale reads can duplicate or mis-order work.
            $pages = $wpdb->get_results($wpdb->prepare(
                "SELECT ID, post_title, post_name 
                 FROM {$wpdb->posts} 
                 WHERE post_type = 'page' 
                 AND post_status = 'publish'
                 AND post_name LIKE %s
                 LIMIT 5",
                '%' . $wpdb->esc_like($segment) . '%'
            ));
            
            foreach ($pages as $page) {
                $similarity = $this->calculate_text_similarity(array($segment), array($page->post_name));
                
                if ($similarity > 0.4) {
                    $suggestions[] = array(
                        'url' => get_permalink($page->ID),
                        'title' => $page->post_title,
                        'type' => 'page',
                        'similarity' => $similarity
                    );
                }
            }
        }
        
        return $suggestions;
    }
    
    private function find_similar_categories($path_segments) {
        $suggestions = array();
        
        $categories = get_categories(array(
            'hide_empty' => false,
            'number' => 50
        ));
        
        foreach ($categories as $category) {
            $similarity = $this->calculate_text_similarity($path_segments, array($category->slug, $category->name));
            
            if ($similarity > 0.4) {
                $suggestions[] = array(
                    'url' => get_category_link($category->term_id),
                    'title' => $category->name,
                    'type' => 'category',
                    'similarity' => $similarity
                );
            }
        }
        
        return $suggestions;
    }
    
    private function find_similar_products($path_segments) {
        global $wpdb;
        
        $suggestions = array();
        $search_terms = implode(' ', $path_segments);
        
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Reviewed release query uses WordPress or plugin-owned operational tables; current job, billing and idempotency state must not be cached because stale reads can duplicate or mis-order work.
        $products = $wpdb->get_results($wpdb->prepare(
            "SELECT ID, post_title, post_name 
             FROM {$wpdb->posts} 
             WHERE post_type = 'product' 
             AND post_status = 'publish'
             AND (post_title LIKE %s OR post_name LIKE %s)
             LIMIT 10",
            '%' . $wpdb->esc_like($search_terms) . '%',
            '%' . $wpdb->esc_like(implode('-', $path_segments)) . '%'
        ));
        
        foreach ($products as $product) {
            $similarity = $this->calculate_text_similarity($path_segments, array($product->post_name, $product->post_title));
            
            if ($similarity > 0.3) {
                $suggestions[] = array(
                    'url' => get_permalink($product->ID),
                    'title' => $product->post_title,
                    'type' => 'product',
                    'similarity' => $similarity
                );
            }
        }
        
        return $suggestions;
    }
    
    private function calculate_text_similarity($source_segments, $target_texts) {
        $max_similarity = 0;
        
        foreach ($target_texts as $target_text) {
            $target_segments = array_filter(explode('-', strtolower($target_text)));
            $target_segments = array_merge($target_segments, str_word_count(strtolower($target_text), 1));
            
            $common_segments = array_intersect($source_segments, $target_segments);
            $total_segments = array_unique(array_merge($source_segments, $target_segments));
            
            if (count($total_segments) > 0) {
                $similarity = count($common_segments) / count($total_segments);
                $max_similarity = max($max_similarity, $similarity);
            }
        }
        
        return $max_similarity;
    }
    
    private function create_automatic_redirect($source_url, $suggestion, $confidence_result) {
        $redirect_data = array(
            'source_url' => $source_url,
            'target_url' => $suggestion['url'],
            'redirect_type' => '301',
            'confidence_score' => $confidence_result['score'],
            'is_automated' => true,
            'created_at' => current_time('mysql')
        );
        
        $success = $this->save_redirect($redirect_data);
        
        if ($success) {
            $this->audit_logger->log_action(
                'redirect_creation',
                0,
                'redirect',
                array('source_url' => $source_url),
                $redirect_data,
                $confidence_result['score'],
                true
            );
            
            return array(
                'success' => true,
                'redirect_created' => true,
                'source_url' => $source_url,
                'target_url' => $suggestion['url'],
                'confidence_score' => $confidence_result['score'],
                'message' => 'Redirect created automatically'
            );
        } else {
            return new WP_Error('redirect_failed', 'Failed to create redirect');
        }
    }
    
    private function queue_redirect_for_review($source_url, $suggestions, $confidence_result) {
        $review_data = array(
            'source_url' => $source_url,
            'suggestions' => $suggestions,
            'confidence_score' => $confidence_result['score'],
            'confidence_factors' => $confidence_result['factors'],
            'created_at' => current_time('mysql')
        );
        
        $existing_reviews = get_option('aysa_pending_redirect_reviews', array());
        $existing_reviews[md5($source_url)] = $review_data;
        update_option('aysa_pending_redirect_reviews', $existing_reviews);
        
        return array(
            'success' => true,
            'queued_for_review' => true,
            'source_url' => $source_url,
            'suggestions_count' => count($suggestions),
            'confidence_score' => $confidence_result['score'],
            'message' => 'Redirect queued for manual review due to low confidence'
        );
    }
    
    private function save_redirect($redirect_data) {
        global $wpdb;
        
        $redirects_table = esc_sql($wpdb->prefix . 'aysa_redirects');
        
        $this->create_redirects_table();
        
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reviewed release query uses WordPress or plugin-owned operational tables; current job, billing and idempotency state must not be cached because stale reads can duplicate or mis-order work.
        return $wpdb->insert(
            $redirects_table,
            $redirect_data,
            array('%s', '%s', '%s', '%f', '%d', '%s')
        );
    }
    
    private function get_safe_charset_collate() {
        global $wpdb;
        $charset_collate = $wpdb->get_charset_collate();
        
        if (strpos($charset_collate, 'UTF-8') !== false) {
            $charset_collate = str_replace('UTF-8', 'utf8mb4', $charset_collate);
        }
        
        if (empty($charset_collate) || strpos($charset_collate, 'UTF-8') !== false) {
            $charset_collate = 'DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci';
        }
        
        return $charset_collate;
    }
    
    private function create_redirects_table() {
        global $wpdb;
        
        $table_name = esc_sql($wpdb->prefix . 'aysa_redirects');
        $charset_collate = $this->get_safe_charset_collate();
        aysa_debug_log('[AYSA DEBUG] Redirect Processor using charset: ' . $charset_collate);
        
        $sql = "CREATE TABLE IF NOT EXISTS {$table_name} (
            id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
            source_url varchar(255) NOT NULL,
            target_url varchar(255) NOT NULL,
            redirect_type varchar(10) DEFAULT '301',
            confidence_score decimal(3,2) NULL,
            is_automated tinyint(1) DEFAULT 0,
            is_active tinyint(1) DEFAULT 1,
            hit_count bigint(20) DEFAULT 0,
            created_at datetime DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            UNIQUE KEY source_url (source_url),
            KEY target_url (target_url),
            KEY is_active (is_active)
        ) $charset_collate;";
        
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($sql);
    }
    
    public function get_pending_reviews() {
        return get_option('aysa_pending_redirect_reviews', array());
    }
    
    public function approve_redirect_review($review_key, $selected_target_url) {
        $pending_reviews = get_option('aysa_pending_redirect_reviews', array());
        
        if (!isset($pending_reviews[$review_key])) {
            return new WP_Error('review_not_found', 'Pending review not found');
        }
        
        $review_data = $pending_reviews[$review_key];
        
        $redirect_data = array(
            'source_url' => $review_data['source_url'],
            'target_url' => $selected_target_url,
            'redirect_type' => '301',
            'confidence_score' => $review_data['confidence_score'],
            'is_automated' => false,
            'created_at' => current_time('mysql')
        );
        
        $success = $this->save_redirect($redirect_data);
        
        if ($success) {
            unset($pending_reviews[$review_key]);
            update_option('aysa_pending_redirect_reviews', $pending_reviews);
            
            return array(
                'success' => true,
                'message' => 'Redirect created from manual review'
            );
        } else {
            return new WP_Error('redirect_failed', 'Failed to create redirect');
        }
    }
    
    public function reject_redirect_review($review_key) {
        $pending_reviews = get_option('aysa_pending_redirect_reviews', array());
        
        if (!isset($pending_reviews[$review_key])) {
            return new WP_Error('review_not_found', 'Pending review not found');
        }
        
        unset($pending_reviews[$review_key]);
        update_option('aysa_pending_redirect_reviews', $pending_reviews);
        
        return array(
            'success' => true,
            'message' => 'Redirect review rejected'
        );
    }
}
