<?php
/**
 * Google Search Class
 * Performs Google searches using curl with proper headers and cookies
 * 
 * @package AIAutoTool
 * @since 2.3.0
 */

if ( ! defined( 'ABSPATH' ) ) exit; // Thoát nếu truy cập trực tiếp

if (!class_exists('AIAutoTool_Google_Search')) {
    class AIAutoTool_Google_Search {
        
        /**
         * Default cookies for Google search
         * These should be updated periodically or obtained from browser
         */
        private static $default_cookies = 'SEARCH_SAMESITE=CgQIkp8B; HSID=AZuNAgZMNNzyW1qNA; SSID=ATp9mt4lYL1HHhdSY; APISID=KfluP8kbHSCRuH8F/AX4-klfH822g88jv_; SAPISID=XmIfmd-6xMyGDWZj/AJweyR1-q17LfGggX; __Secure-1PAPISID=XmIfmd-6xMyGDWZj/AJweyR1-q17LfGggX; __Secure-3PAPISID=XmIfmd-6xMyGDWZj/AJweyR1-q17LfGggX; __Secure-BUCKET=CNcH; SID=g.a0003wii5A_Lg6t06Nf3Ua7tsSNg4OLhhyPjXy0UE_LqRBXOYBD1E_7b0HvQGJjFcX9FDWUg6QACgYKAckSARASFQHGX2MiGzGoE4gJCwdhCn4xoO16YRoVAUF8yKole7PxVCK3SPDu18IlEkcN0076; __Secure-1PSID=g.a0003wii5A_Lg6t06Nf3Ua7tsSNg4OLhhyPjXy0UE_LqRBXOYBD1VCLoe9_1tl_CTkGGq9YNegACgYKAYoSARASFQHGX2MiJPIj4KVAT9CMgRFVn_mN5xoVAUF8yKqqlI5Wov6ntujZTVnKOiH50076; __Secure-3PSID=g.a0003wii5A_Lg6t06Nf3Ua7tsSNg4OLhhyPjXy0UE_LqRBXOYBD1neg4LhaoM_2OhTi_SHFt4wACgYKAUwSARASFQHGX2MiCH4y4c98MeaGQMmoxxaTAhoVAUF8yKoGvxHR77ORBrAPPd2Jstrg0076; NID=526=TPjSpZKRcNJjyT_PacVzgpYix2NvcVlUX9ix1w_u9Bu-2ZFyWv4X6hKrA0evanNoGQ8eDQPXfx7SjqafsKCi27iaMPg8GRhpaYSCsvSHGzGiPeDz2ixRtFFfLXlMDaD3QWiesZirzij-QRYTtYifmiEVRpzT-opH75ayVvSznnba0PEfL2clvTtIGqWVVlh3ZqRAFPBKTif2It86VFgD9ex80vdNxevybQsymR4qz7-fuCML89YaLbIToyUxd_xZZlKzwfZlsrCAfZO6syO3D7joNVzr6UGyqjRAsr3G83FW8uvceXdSM95NG_3QDkjjoUdQBGEzbEoiiBEtbqBqviIx2P-RKdUamGQ6Pua6ALqRpVi0xlc9oaq8PXkMeP7X0Y2nMZULUGM1pyV_jSb79SEATvFICuF3TDdYKq2O1uFB02P4EdlYF3-Bc--3L29IF3YGYM_DXlsLKjDNmBQiT8kGfBsBh68WLb_GitHdlOaeQQQUpSNLufMgmQuHd_SM7owqYr1qrg0CSKms1UqyNdKJ1iyi3KH6SP8LcoZB1p0YC1kqx7HbJ0Fow_QgwT0DuZIV5iemIenLk1KvGFdebgwpR_bcWklZIUfFSyc9dkShI8io_sBTKj3t4txvaJxhdtag9oo_Vi1z7d-B06es_fLqXDfdccvOpegacRbXDnnTEGhCz_T_iqQ5ZeJOEXCzwnbnFItr_9aPZX6l6S__MmFyzDjm_aqLJBD9T56tV_6R_t4-FbNHxk1EqSVbT1LOwlVFhIfYjfRM3xCmBA; __Secure-STRP=ADq1D7rqE-LfAwerRf_-pXNoR0dRO9OGuVjFgBegjqwNWFzhYY8YWy8qOXBWxomFAboaq-9CqsVNJwh2kGC8TeVMdRqizaAwjQ; AEC=AaJma5skjbfXuM99kmF6R21NKAZxu-V4G8jUylKHyAxA8HVgqfskD7nMlg; __Secure-1PSIDTS=sidts-CjIBwQ9iI_uTlC7RrhSiOUcrM8QLwFfVoVTFoG_fGlClyM4KBQSvli49uVEJbka3rjmNlRAA; __Secure-3PSIDTS=sidts-CjIBwQ9iI_uTlC7RrhSiOUcrM8QLwFfVoVTFoG_fGlClyM4KBQSvli49uVEJbka3rjmNlRAA; GOOGLE_ABUSE_EXEMPTION=ID=1b922ca9a758de88:TM=1764658333:C=r:IP=45.122.246.171-:S=4RYGWUUK06YWjyQkvdcYODA; DV=oziAEViUtdJtkAYfDddvFtdQV1ndrVmBQYlvYjhSRgEAAICGSTB--aTyYAAAANSC5f3q3bq_JwAAAPob2FmvhbQoCgAAQIC4KVS_0vXdBAAAAA; SIDCC=AKEyXzUnvl91rvl9aQjSU7M037K65Td4nL5WMfT2tHmRtbDYqwCi_4dKJxCrxyj6wgpf6jSjWIU; __Secure-1PSIDCC=AKEyXzUzbj-OdYbHe0E5ORwsBitCVckKCO-jj92yzCtkZSd-6bbhb22XWMu12_6PEnYH27htLg; __Secure-3PSIDCC=AKEyXzVZYfydYpLtTGv7Usgza7M-axFdlXoK7UimgvFDrLlI5j0LHrMKjiKsHJy3spk6hXBiB_k';
        
        /**
         * Get default headers for Google search
         * 
         * @return array Headers array
         */
        private static function get_default_headers() {
            return array(
                'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
                'accept-language: en-US,en;q=0.9,vi;q=0.8',
                'cache-control: max-age=0',
                'downlink: 7.9',
                'priority: u=0, i',
                'referer: https://www.google.com/',
                'rtt: 50',
                'sec-ch-prefers-color-scheme: dark',
                'sec-ch-ua: "Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"',
                'sec-ch-ua-arch: "x86"',
                'sec-ch-ua-bitness: "64"',
                'sec-ch-ua-form-factors: "Desktop"',
                'sec-ch-ua-full-version: "142.0.7444.176"',
                'sec-ch-ua-full-version-list: "Chromium";v="142.0.7444.176", "Google Chrome";v="142.0.7444.176", "Not_A Brand";v="99.0.0.0"',
                'sec-ch-ua-mobile: ?0',
                'sec-ch-ua-model: ""',
                'sec-ch-ua-platform: "macOS"',
                'sec-ch-ua-platform-version: "15.5.0"',
                'sec-ch-ua-wow64: ?0',
                'sec-fetch-dest: document',
                'sec-fetch-mode: navigate',
                'sec-fetch-site: same-origin',
                'sec-fetch-user: ?1',
                'upgrade-insecure-requests: 1',
                'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36',
                'x-browser-channel: stable',
                'x-browser-copyright: Copyright 2025 Google LLC. All Rights reserved.',
                'x-browser-validation: d//u4R5DiWup/ApEN0L4er68I4A=',
                'x-browser-year: 2025',
                'x-client-data: CLG1yQEIlbbJAQiktskBCKmdygEIlpbLAQiSocsBCIagzQEI6OTOAQi5/c4BCJeMzwEIzZHPAQiak88BCPOYzwEI1JnPAQj9m88BCPqdzwEIw57PAQjTns8BGOyFzwEYsobPAQ=='
            );
        }
        
        /**
         * Perform Google search
         * 
         * @param string $query Search query
         * @param array $options Additional options (cookies, headers, etc.)
         * @return array|WP_Error Search results or error
         */
        public static function search($query, $options = array()) {
            // URL encode the query
            $encoded_query = urlencode($query);
            
            // Build search URL
            $search_url = 'https://www.google.com/search?q=' . $encoded_query;
            
            // Add additional query parameters if provided
            if (isset($options['params']) && is_array($options['params'])) {
                foreach ($options['params'] as $key => $value) {
                    $search_url .= '&' . urlencode($key) . '=' . urlencode($value);
                }
            }
            
            // Get cookies (use provided or default)
            $cookies = isset($options['cookies']) ? $options['cookies'] : self::$default_cookies;
            
            // Get headers (use provided or default)
            $headers = isset($options['headers']) ? $options['headers'] : self::get_default_headers();
            
            // Initialize curl
            $ch = curl_init($search_url);
            
            // Set curl options
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_TIMEOUT, isset($options['timeout']) ? $options['timeout'] : 30);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_COOKIE, $cookies);
            
            // Execute request
            $response = curl_exec($ch);
            $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            $curl_error = curl_error($ch);
            curl_close($ch);
            
            // Check for curl errors
            if ($response === false || !empty($curl_error)) {
                return new WP_Error('curl_error', __('cURL Error: ', 'ai-auto-tool') . $curl_error);
            }
            
            // Check HTTP status code
            if ($http_code !== 200) {
                return new WP_Error('http_error', sprintf(__('HTTP Error: %d', 'ai-auto-tool'), $http_code));
            }
            
            // Check if response is valid HTML
            if (empty($response) || strlen($response) < 100) {
                return new WP_Error('empty_response', __('Empty or too short response from Google', 'ai-auto-tool'));
            }
            
            // Check for CAPTCHA, blocking, or JavaScript challenge
            $blocked_indicators = array(
                'captcha',
                'unusual traffic',
                'automated queries',
                'knitsail', // Google's anti-bot system
                'enablejs', // JavaScript challenge redirect
                'SG_REL', // Security challenge
                'If you\'re having trouble accessing Google Search', // Challenge message
                'window.google.c.e', // Google challenge JavaScript
                'challenge_version'
            );
            
            $is_blocked = false;
            foreach ($blocked_indicators as $indicator) {
                if (stripos($response, $indicator) !== false) {
                    $is_blocked = true;
                    break;
                }
            }
            
            // Also check if response is mostly JavaScript (challenge page)
            $js_ratio = substr_count(strtolower($response), 'function') / max(strlen($response) / 1000, 1);
            if ($js_ratio > 0.1 && strlen($response) < 50000) {
                // Likely a challenge page (lots of JS, small size)
                $is_blocked = true;
            }
            
            if ($is_blocked) {
                return new WP_Error('blocked', __('Google detected automated requests and returned a challenge page. Please use Google Custom Search API or update cookies/headers.', 'ai-auto-tool'));
            }
            
            // Save HTML for debugging if requested
            if (isset($options['save_html']) && $options['save_html']) {
                $debug_file = isset($options['debug_file']) ? $options['debug_file'] : 
                    sys_get_temp_dir() . '/google-search-debug-' . time() . '.html';
                // Ensure we save as text, not binary
                file_put_contents($debug_file, $response);
            }
            
            // Parse results
            $results = self::parse_search_results($response);
            
            return array(
                'success' => true,
                'query' => $query,
                'url' => $search_url,
                'http_code' => $http_code,
                'results' => $results,
                'raw_html' => $response
            );
        }
        
        /**
         * Parse Google search results from HTML
         * 
         * @param string $html HTML content
         * @return array Parsed results
         */
        private static function parse_search_results($html) {
            $results = array(
                'organic' => array(),
                'ads' => array(),
                'featured_snippet' => null,
                'people_also_ask' => array(),
                'related_searches' => array()
            );
            
            // First try: Regex parsing as fallback (more reliable)
            $regex_results = self::parse_search_results_regex($html);
            if (!empty($regex_results['organic'])) {
                $results['organic'] = $regex_results['organic'];
            }
            
            // Second try: DOM parsing (more accurate but can fail)
            libxml_use_internal_errors(true);
            $dom = new DOMDocument();
            @$dom->loadHTML('<?xml encoding="UTF-8">' . $html);
            $xpath = new DOMXPath($dom);
            
            // Multiple selectors for organic results (Google changes structure frequently)
            $organic_selectors = array(
                "//div[contains(@class, 'g')]",
                "//div[@data-ved]",
                "//div[contains(@class, 'tF2Cxc')]",
                "//div[contains(@class, 'MjjYud')]",
                "//div[@jscontroller='SC7lYd']",
                "//div[contains(@class, 'hlcw0c')]",
                "//div[contains(@class, 'g-blk')]"
            );
            
            $processed_nodes = array();
            $dom_results = array();
            
            foreach ($organic_selectors as $selector) {
                $organic_nodes = $xpath->query($selector);
                foreach ($organic_nodes as $node) {
                    // Skip if already processed
                    $node_id = spl_object_hash($node);
                    if (isset($processed_nodes[$node_id])) {
                        continue;
                    }
                    $processed_nodes[$node_id] = true;
                    
                    $result = array();
                    
                    // Extract title - multiple possible locations
                    $title_selectors = array(
                        ".//h3",
                        ".//h3[contains(@class, 'LC20lb')]",
                        ".//h3[contains(@class, 'DKV0Md')]",
                        ".//h3[contains(@class, 'zBAuLc')]",
                        ".//a//h3",
                        ".//div[contains(@class, 'yuRUbf')]//h3",
                        ".//div[contains(@class, 'N54PNb')]//h3"
                    );
                    
                    foreach ($title_selectors as $title_sel) {
                        $title_node = $xpath->query($title_sel, $node)->item(0);
                        if ($title_node && !empty(trim($title_node->textContent))) {
                            $result['title'] = trim($title_node->textContent);
                            break;
                        }
                    }
                    
                    // Extract URL - multiple possible locations
                    $link_selectors = array(
                        ".//a[@href]",
                        ".//div[contains(@class, 'yuRUbf')]//a[@href]",
                        ".//a[contains(@class, 'BVG0Nb')][@href]",
                        ".//div[contains(@class, 'N54PNb')]//a[@href]"
                    );
                    
                    foreach ($link_selectors as $link_sel) {
                        $link_nodes = $xpath->query($link_sel, $node);
                        foreach ($link_nodes as $link_node) {
                            $href = $link_node->getAttribute('href');
                            if (!empty($href)) {
                                // Clean Google redirect URLs
                                if (strpos($href, '/url?q=') === 0 || strpos($href, '/url?') === 0) {
                                    $parsed = parse_url($href);
                                    if (isset($parsed['query'])) {
                                        parse_str($parsed['query'], $params);
                                        if (isset($params['q'])) {
                                            $href = $params['q'];
                                        }
                                    } else {
                                        $href = urldecode(substr($href, 7));
                                        $href = explode('&', $href)[0];
                                    }
                                }
                                // Skip Google internal URLs and validate
                                if ((strpos($href, 'http://') === 0 || strpos($href, 'https://') === 0 || strpos($href, '//') === 0) 
                                    && strpos($href, 'google.com') === false 
                                    && strpos($href, 'googleusercontent.com') === false) {
                                    $result['url'] = $href;
                                    break 2; // Break both loops
                                }
                            }
                        }
                    }
                    
                    // Extract snippet - multiple possible locations
                    $snippet_selectors = array(
                        ".//span[contains(@class, 'aCOpRe')]",
                        ".//div[contains(@class, 'VwiC3b')]",
                        ".//span[contains(@class, 'st')]",
                        ".//span[contains(@class, 'aST4p')]",
                        ".//div[contains(@class, 's')]//span",
                        ".//div[contains(@class, 'IsZvec')]//span",
                        ".//div[contains(@class, 'yXK7lf')]//span"
                    );
                    
                    foreach ($snippet_selectors as $snippet_sel) {
                        $snippet_nodes = $xpath->query($snippet_sel, $node);
                        if ($snippet_nodes->length > 0) {
                            $snippet_text = trim($snippet_nodes->item(0)->textContent);
                            if (!empty($snippet_text) && strlen($snippet_text) > 20) {
                                $result['snippet'] = $snippet_text;
                                break;
                            }
                        }
                    }
                    
                    // Only add if we have at least title and URL
                    if (!empty($result['title']) && !empty($result['url'])) {
                        $dom_results[] = $result;
                    }
                }
            }
            
            // Use DOM results if we got more than regex, otherwise use regex
            if (count($dom_results) > count($results['organic'])) {
                $results['organic'] = $dom_results;
            } elseif (empty($results['organic']) && !empty($dom_results)) {
                $results['organic'] = $dom_results;
            }
            
            // Parse featured snippet (answer box)
            $featured_node = $xpath->query("//div[contains(@class, 'xpdopen')] | //div[@data-attrid]")->item(0);
            if ($featured_node) {
                $featured = array();
                $featured_title = $xpath->query(".//h2 | .//h3", $featured_node)->item(0);
                if ($featured_title) {
                    $featured['title'] = trim($featured_title->textContent);
                }
                $featured_text = $xpath->query(".//span[contains(@class, 'hgKElc')] | .//div[contains(@class, 'Z0LcW')]", $featured_node)->item(0);
                if ($featured_text) {
                    $featured['text'] = trim($featured_text->textContent);
                }
                if (!empty($featured)) {
                    $results['featured_snippet'] = $featured;
                }
            }
            
            // Parse "People Also Ask" section
            $paa_nodes = $xpath->query("//div[contains(@class, 'related-question-pair')] | //div[@data-ved and .//div[contains(@class, 'cbphWd')]]");
            foreach ($paa_nodes as $paa_node) {
                $question = $xpath->query(".//div[contains(@class, 'cbphWd')] | .//span[contains(@class, 'CSkcDe')]", $paa_node)->item(0);
                if ($question) {
                    $results['people_also_ask'][] = trim($question->textContent);
                }
            }
            
            // Parse related searches
            $related_nodes = $xpath->query("//div[contains(@class, 'brs_col')]//a | //a[contains(@class, 's75CSd')]");
            foreach ($related_nodes as $related_node) {
                $related_text = trim($related_node->textContent);
                if (!empty($related_text)) {
                    $results['related_searches'][] = $related_text;
                }
            }
            
            return $results;
        }
        
        /**
         * Parse search results using regex (fallback method)
         * More reliable when DOM parsing fails
         * 
         * @param string $html HTML content
         * @return array Parsed results
         */
        private static function parse_search_results_regex($html) {
            $results = array(
                'organic' => array()
            );
            
            // Pattern 1: Extract from data-ved divs with h3 and links
            // Look for divs containing h3 tags followed by links
            preg_match_all('/<div[^>]*data-ved[^>]*>.*?<h3[^>]*>(.*?)<\/h3>.*?<a[^>]*href=["\']([^"\']+)["\'][^>]*>/is', $html, $matches, PREG_SET_ORDER);
            
            foreach ($matches as $match) {
                if (count($match) >= 3) {
                    $title = strip_tags($match[1]);
                    $url = $match[2];
                    
                    // Clean Google redirect URLs
                    if (strpos($url, '/url?q=') === 0 || strpos($url, '/url?') === 0) {
                        $parsed = parse_url($url);
                        if (isset($parsed['query'])) {
                            parse_str($parsed['query'], $params);
                            if (isset($params['q'])) {
                                $url = $params['q'];
                            }
                        }
                    }
                    
                    // Validate URL
                    if (!empty($title) && !empty($url) && 
                        (strpos($url, 'http://') === 0 || strpos($url, 'https://') === 0) &&
                        strpos($url, 'google.com') === false) {
                        $results['organic'][] = array(
                            'title' => trim($title),
                            'url' => $url,
                            'snippet' => '' // Will try to extract separately
                        );
                    }
                }
            }
            
            // Pattern 2: Extract from class="g" divs
            if (empty($results['organic'])) {
                preg_match_all('/<div[^>]*class=["\'][^"\']*\\bg\\b[^"\']*["\'][^>]*>.*?<h3[^>]*>(.*?)<\/h3>.*?<a[^>]*href=["\']([^"\']+)["\'][^>]*>/is', $html, $matches, PREG_SET_ORDER);
                
                foreach ($matches as $match) {
                    if (count($match) >= 3) {
                        $title = strip_tags($match[1]);
                        $url = $match[2];
                        
                        // Clean Google redirect URLs
                        if (strpos($url, '/url?q=') === 0 || strpos($url, '/url?') === 0) {
                            $parsed = parse_url($url);
                            if (isset($parsed['query'])) {
                                parse_str($parsed['query'], $params);
                                if (isset($params['q'])) {
                                    $url = $params['q'];
                                }
                            }
                        }
                        
                        // Validate URL
                        if (!empty($title) && !empty($url) && 
                            (strpos($url, 'http://') === 0 || strpos($url, 'https://') === 0) &&
                            strpos($url, 'google.com') === false) {
                            $results['organic'][] = array(
                                'title' => trim($title),
                                'url' => $url,
                                'snippet' => ''
                            );
                        }
                    }
                }
            }
            
            // Pattern 3: Simple pattern - any h3 followed by a link
            if (empty($results['organic'])) {
                preg_match_all('/<h3[^>]*>(.*?)<\/h3>.*?<a[^>]*href=["\']([^"\']+)["\'][^>]*>/is', $html, $matches, PREG_SET_ORDER);
                
                foreach ($matches as $match) {
                    if (count($match) >= 3) {
                        $title = strip_tags($match[1]);
                        $url = $match[2];
                        
                        // Skip if it's a Google internal link
                        if (strpos($url, 'google.com') !== false || strpos($url, 'googleusercontent.com') !== false) {
                            continue;
                        }
                        
                        // Clean Google redirect URLs
                        if (strpos($url, '/url?q=') === 0 || strpos($url, '/url?') === 0) {
                            $parsed = parse_url($url);
                            if (isset($parsed['query'])) {
                                parse_str($parsed['query'], $params);
                                if (isset($params['q'])) {
                                    $url = $params['q'];
                                }
                            }
                        }
                        
                        // Validate URL
                        if (!empty($title) && strlen($title) > 5 && 
                            !empty($url) && 
                            (strpos($url, 'http://') === 0 || strpos($url, 'https://') === 0)) {
                            
                            // Check if we already have this URL
                            $exists = false;
                            foreach ($results['organic'] as $existing) {
                                if ($existing['url'] === $url) {
                                    $exists = true;
                                    break;
                                }
                            }
                            
                            if (!$exists) {
                                $results['organic'][] = array(
                                    'title' => trim($title),
                                    'url' => $url,
                                    'snippet' => ''
                                );
                            }
                        }
                    }
                }
            }
            
            // Remove duplicates
            $unique_results = array();
            $seen_urls = array();
            foreach ($results['organic'] as $result) {
                if (!in_array($result['url'], $seen_urls)) {
                    $unique_results[] = $result;
                    $seen_urls[] = $result['url'];
                }
            }
            $results['organic'] = array_slice($unique_results, 0, 10); // Limit to 10 results
            
            return $results;
        }
        
        /**
         * Get search results as simple array (title, url, snippet)
         * Falls back to Jina AI Search if Google is blocked
         * 
         * @param string $query Search query
         * @param array $options Additional options
         * @return array|WP_Error Simple results array or error
         */
        public static function get_simple_results($query, $options = array()) {
            $search_result = self::search($query, $options);
            
            // If Google search is blocked, try Jina AI Search as fallback
            if (is_wp_error($search_result) && $search_result->get_error_code() === 'blocked') {
                if (defined('WP_DEBUG') && WP_DEBUG) {
                }
                
                $jina_result = self::search_jina_ai($query, $options);
                
                if (!is_wp_error($jina_result) && isset($jina_result['results']['organic'])) {
                    if (defined('WP_DEBUG') && WP_DEBUG) {
                    }
                    return $jina_result['results']['organic'];
                }
                
                // If Jina AI fails, return Jina AI error (especially if it's no_api_key)
                if (is_wp_error($jina_result)) {
                    if (defined('WP_DEBUG') && WP_DEBUG) {
                    }
                    // Return Jina AI error if it's a critical error like missing API key
                    if ($jina_result->get_error_code() === 'no_api_key') {
                        return $jina_result;
                    }
                }
            }
            
            if (is_wp_error($search_result)) {
                return $search_result;
            }
            
            return $search_result['results']['organic'];
        }
        
        /**
         * Update cookies for Google search
         * 
         * @param string $cookies Cookie string
         */
        public static function set_cookies($cookies) {
            self::$default_cookies = $cookies;
        }
        
        /**
         * Get current cookies
         * 
         * @return string Cookie string
         */
        public static function get_cookies() {
            return self::$default_cookies;
        }
        
        /**
         * Update headers for Google search
         * 
         * @param array $headers Headers array
         */
        public static function set_headers($headers) {
            // This would require storing headers, for now we use get_default_headers()
            // You can override headers in the search() method via options
        }
        
        /**
         * Get content from URL using PHP Readability (primary method)
         * 
         * @param string $url URL to fetch content from
         * @param array $options Additional options (timeout, etc.)
         * @return array|WP_Error Content data or error
         */
        private static function get_url_content_with_readability($url, $options = array()) {
            // Validate URL
            if (empty($url) || !filter_var($url, FILTER_VALIDATE_URL)) {
                return new WP_Error('invalid_url', __('Invalid URL provided', 'ai-auto-tool'));
            }
            
            // Check if Readability library exists - try multiple paths
            // Priority: lib folder (official) > tmp folder (reference)
            $possible_paths = array(
                // Primary: Official lib folder
                dirname(__FILE__) . '/readability/AIAutoTool_Readability.php',
                plugin_dir_path(__FILE__) . 'readability/AIAutoTool_Readability.php',
               // Fallback: Reference tmp folder (if exists)
              
               
            );
            
            $readability_path = null;
            foreach ($possible_paths as $path) {
                if (file_exists($path)) {
                    $readability_path = $path;
                    break;
                }
            }
            
            if (!$readability_path) {
                if (defined('WP_DEBUG') && WP_DEBUG) {
                }
                return new WP_Error('readability_not_found', __('PHP Readability library not found', 'ai-auto-tool'));
            }
            
            // Fetch HTML content from URL
            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_TIMEOUT, isset($options['timeout']) ? $options['timeout'] : 30);
            curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36');
            curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                'Accept-Language: en-US,en;q=0.9',
            ));
            
            $html = curl_exec($ch);
            $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            $curl_error = curl_error($ch);
            curl_close($ch);
            
            // Check for curl errors
            if ($html === false || !empty($curl_error)) {
                return new WP_Error('curl_error', __('cURL Error: ', 'ai-auto-tool') . $curl_error);
            }
            
            // Check HTTP status code
            if ($http_code !== 200) {
                return new WP_Error('http_error', sprintf(__('HTTP Error: %d', 'ai-auto-tool'), $http_code), array('http_code' => $http_code));
            }
            
            if (empty($html) || strlen($html) < 100) {
                return new WP_Error('empty_response', __('Empty or too short HTML response', 'ai-auto-tool'));
            }
            
            // Use Tidy if available to clean HTML
            if (function_exists('tidy_parse_string')) {
                $tidy_config = array(
                    'clean' => true,
                    'output-html' => true,
                    'wrap' => 0,
                    'indent' => false,
                    'show-body-only' => false
                );
                $tidy = tidy_parse_string($html, $tidy_config, 'UTF8');
                if ($tidy) {
                    $tidy->cleanRepair();
                    $html = (string)$tidy;
                }
            }
            
            // Load Readability library (AIAutoTool_JSLikeHTMLElement is already required inside AIAutoTool_Readability)
            require_once $readability_path;
            
            // Extract content using Readability
            try {
                $readability = new AIAutoTool_Readability($html, $url);
                $readability->debug = false;
                $readability->convertLinksToFootnotes = false;
                
                $result = $readability->init();
                
                if (defined('WP_DEBUG') && WP_DEBUG) {
                }
                
                // Try to get content even if init() returned false - sometimes content is still available
                // Get title
                $title_elem = $readability->getTitle();
                $title = '';
                if ($title_elem) {
                    $title = isset($title_elem->textContent) ? trim($title_elem->textContent) : '';
                }
                
                // Get content - try multiple methods (same as wp-automatic example)
                $content_elem = $readability->getContent();
                $content_html = '';
                $is_plain_text = false;
                
                if ($content_elem) {
                    // Method 1: Try to get HTML using innerHTML magic property (primary method)
                    // Access directly like wp-automatic does: $content_elem->innerHTML
                    try {
                        @$content_html = $content_elem->innerHTML; // Suppress warnings
                        if (empty($content_html) || !is_string($content_html)) {
                            $content_html = '';
                        }
                    } catch (Exception $e) {
                        $content_html = '';
                    } catch (Error $e) {
                        $content_html = '';
                    }
                    
                    // Method 2: Try getting HTML using ownerDocument->saveHTML() (more reliable)
                    if (empty($content_html) && isset($content_elem->ownerDocument)) {
                        try {
                            $content_html = $content_elem->ownerDocument->saveHTML($content_elem);
                            $content_html = trim($content_html);
                            // Remove wrapper tags if present
                            $content_html = preg_replace('/^<[^>]+>/', '', $content_html);
                            $content_html = preg_replace('/<\/[^>]+>$/', '', $content_html);
                            $content_html = trim($content_html);
                            if (defined('WP_DEBUG') && WP_DEBUG) {
                            }
                        } catch (Exception $e) {
                            if (defined('WP_DEBUG') && WP_DEBUG) {
                            }
                        }
                    }
                    
                    // Method 3: If no HTML, use textContent (plain text) - this often works when innerHTML doesn't
                    if (empty($content_html) && isset($content_elem->textContent)) {
                        $text_content = trim($content_elem->textContent);
                        if (!empty($text_content) && strlen($text_content) > 100) {
                            $content_html = $text_content;
                            $is_plain_text = true; // Mark as plain text, no HTML conversion needed
                            if (defined('WP_DEBUG') && WP_DEBUG) {
                            }
                        }
                    }
                }
                
                if (defined('WP_DEBUG') && WP_DEBUG) {
                }
                
                if (!empty($content_html) && is_string($content_html) && strlen($content_html) > 100) {
                    // Helper function to safely do preg_replace
                    $safe_replace = function($pattern, $replacement, $subject) {
                        if (!is_string($subject) || $subject === null) {
                            return '';
                        }
                        $result = @preg_replace($pattern, $replacement, $subject);
                        return ($result !== null && is_string($result)) ? $result : $subject;
                    };
                    
                    if (!$is_plain_text) {
                        // Process HTML content - convert to markdown
                        // Clean up Readability attributes
                        $content_html = $safe_replace('{ wp_automatic_Readability\=".*?"}s', '', $content_html);
                        
                        // Remove script and style tags
                        $content_html = $safe_replace('/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/is', '', $content_html);
                        $content_html = $safe_replace('/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/is', '', $content_html);
                        
                        // Convert HTML to markdown format
                        // Headings - preserve level
                        $content_html = $safe_replace('/<h1[^>]*>(.*?)<\/h1>/is', "\n\n# $1\n\n", $content_html);
                        $content_html = $safe_replace('/<h2[^>]*>(.*?)<\/h2>/is', "\n\n## $1\n\n", $content_html);
                        $content_html = $safe_replace('/<h3[^>]*>(.*?)<\/h3>/is', "\n\n### $1\n\n", $content_html);
                        $content_html = $safe_replace('/<h4[^>]*>(.*?)<\/h4>/is', "\n\n#### $1\n\n", $content_html);
                        $content_html = $safe_replace('/<h5[^>]*>(.*?)<\/h5>/is', "\n\n##### $1\n\n", $content_html);
                        $content_html = $safe_replace('/<h6[^>]*>(.*?)<\/h6>/is', "\n\n###### $1\n\n", $content_html);
                        
                        // Paragraphs
                        $content_html = $safe_replace('/<p[^>]*>(.*?)<\/p>/is', "$1\n\n", $content_html);
                        
                        // Line breaks
                        $content_html = $safe_replace('/<br[^>]*\/?>/i', "\n", $content_html);
                        
                        // Strong/Bold
                        $content_html = $safe_replace('/<strong[^>]*>(.*?)<\/strong>/is', "**$1**", $content_html);
                        $content_html = $safe_replace('/<b[^>]*>(.*?)<\/b>/is', "**$1**", $content_html);
                        
                        // Emphasis/Italic
                        $content_html = $safe_replace('/<em[^>]*>(.*?)<\/em>/is', "*$1*", $content_html);
                        $content_html = $safe_replace('/<i[^>]*>(.*?)<\/i>/is', "*$1*", $content_html);
                        
                        // Links - extract href and text
                        $content_html = $safe_replace('/<a[^>]*href=["\']([^"\']+)["\'][^>]*>(.*?)<\/a>/is', "[$2]($1)", $content_html);
                        
                        // Lists
                        $content_html = $safe_replace('/<li[^>]*>(.*?)<\/li>/is', "- $1\n", $content_html);
                        $content_html = $safe_replace('/<ul[^>]*>|<\/ul>|<ol[^>]*>|<\/ol>/is', "\n", $content_html);
                        
                        // Blockquotes
                        $content_html = $safe_replace('/<blockquote[^>]*>(.*?)<\/blockquote>/is', "\n> $1\n\n", $content_html);
                        
                        // Remove all remaining HTML tags
                        $content_html = strip_tags($content_html);
                        
                        // Decode HTML entities
                        $content_html = html_entity_decode($content_html, ENT_QUOTES | ENT_HTML5, 'UTF-8');
                    }
                    
                    // Clean up whitespace (for both HTML and plain text)
                    $content_html = $safe_replace('/[ \t]+/u', ' ', $content_html); // Multiple spaces to single
                    $content_html = $safe_replace('/\n{3,}/', "\n\n", $content_html); // Multiple newlines to double
                    $content_html = trim($content_html);
                        
                    return array(
                        'success' => true,
                        'url' => $url,
                        'content' => $content_html,
                        'title' => $title,
                        'format' => 'readability',
                        'length' => strlen($content_html),
                        'method' => 'php_readability'
                    );
                } else {
                    // Content is too short or empty
                    if (defined('WP_DEBUG') && WP_DEBUG) {
                    }
                }
                
                // If we get here, Readability failed to extract meaningful content
                if (defined('WP_DEBUG') && WP_DEBUG) {
                }
                
                return new WP_Error('readability_failed', __('PHP Readability could not extract content from this page', 'ai-auto-tool'));
                
            } catch (Exception $e) {
                return new WP_Error('readability_exception', __('PHP Readability error: ', 'ai-auto-tool') . $e->getMessage());
            }
        }
        
        /**
         * Get content from URL - tries PHP Readability first, falls back to Jina AI Reader
         * 
         * @param string $url URL to fetch content from
         * @param array $options Additional options (api_key, format, timeout, etc.)
         * @return array|WP_Error Content data or error
         */
        public static function get_url_content($url, $options = array()) {
            // Validate URL
            if (empty($url) || !filter_var($url, FILTER_VALIDATE_URL)) {
                return new WP_Error('invalid_url', __('Invalid URL provided', 'ai-auto-tool'));
            }
            
            // Try PHP Readability first (primary method)
            if (defined('WP_DEBUG') && WP_DEBUG) {
            }
            
            $readability_result = self::get_url_content_with_readability($url, $options);
            
            // If Readability succeeded, return the result
            if (!is_wp_error($readability_result) && isset($readability_result['success']) && $readability_result['success']) {
                if (defined('WP_DEBUG') && WP_DEBUG) {
                }
                return $readability_result;
            }
            
            // Readability failed, fallback to Jina AI API
            if (defined('WP_DEBUG') && WP_DEBUG) {
                $error_msg = is_wp_error($readability_result) ? $readability_result->get_error_message() : 'Unknown error';
            }
            
            // Build Jina AI Reader URL
            $jina_url = 'https://r.jina.ai/' . urlencode($url);
            
            // Prepare headers
            $headers = array(
                'Accept: text/plain, text/markdown, application/json',
                'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36'
            );
            
            // Add API key if provided
            if (isset($options['api_key']) && !empty($options['api_key'])) {
                $headers[] = 'X-Return-Format: markdown';
                $headers[] = 'Authorization: Bearer ' . $options['api_key'];
            } else {
                // Try to get API key from options or settings
                $api_key = isset($options['jina_api_key']) ? $options['jina_api_key'] : 
                    (class_exists('AIAutotool_AI_Provider_API_Keys') ? AIAutotool_AI_Provider_API_Keys::get_jina_key() : get_option('aiautotool_jina_api_key', ''));
                if (!empty($api_key)) {
                    $headers[] = 'X-Return-Format: markdown';
                    $headers[] = 'Authorization: Bearer ' . $api_key;
                }
            }
            
            // Add format option
            if (isset($options['format'])) {
                $headers[] = 'X-Return-Format: ' . $options['format'];
            } else {
                $headers[] = 'X-Return-Format: markdown';
            }
            
            // Initialize curl
            $ch = curl_init($jina_url);
            
            // Set curl options
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_TIMEOUT, isset($options['timeout']) ? $options['timeout'] : 60);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            
            // Execute request
            $response = curl_exec($ch);
            $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            $curl_error = curl_error($ch);
            curl_close($ch);
            
            // Check for curl errors
            if ($response === false || !empty($curl_error)) {
                return new WP_Error('curl_error', __('cURL Error: ', 'ai-auto-tool') . $curl_error);
            }
            
            // Check HTTP status code
            if ($http_code !== 200) {
                $error_msg = sprintf(__('HTTP Error: %d', 'ai-auto-tool'), $http_code);
                if ($http_code === 429) {
                    $error_msg = __('Rate limit exceeded. Please try again later or add API key.', 'ai-auto-tool');
                } elseif ($http_code === 401) {
                    $error_msg = __('Unauthorized. Please check your API key.', 'ai-auto-tool');
                }
                return new WP_Error('http_error', $error_msg, array('http_code' => $http_code));
            }
            
            // Parse response
            $content = trim($response);
            
            // Try to parse as JSON if it's JSON format
            $json_data = json_decode($content, true);
            if (json_last_error() === JSON_ERROR_NONE && is_array($json_data)) {
                return array(
                    'success' => true,
                    'url' => $url,
                    'content' => isset($json_data['content']) ? $json_data['content'] : $content,
                    'title' => isset($json_data['title']) ? $json_data['title'] : '',
                    'description' => isset($json_data['description']) ? $json_data['description'] : '',
                    'format' => 'json',
                    'raw_response' => $json_data
                );
            }
            
            return array(
                'success' => true,
                'url' => $url,
                'content' => $content,
                'format' => isset($options['format']) ? $options['format'] : 'markdown',
                'length' => strlen($content),
                'raw_response' => $response
            );
        }
        
        /**
         * Get content from multiple URLs using Jina AI Reader
         * 
         * @param array $urls Array of URLs to fetch
         * @param array $options Additional options
         * @return array Array of results (each can be content or WP_Error)
         */
        public static function get_multiple_urls_content($urls, $options = array()) {
            if (empty($urls) || !is_array($urls)) {
                return new WP_Error('invalid_input', __('Invalid URLs array provided', 'ai-auto-tool'));
            }
            
            $results = array();
            $delay = isset($options['delay']) ? (int)$options['delay'] : 1; // Delay between requests in seconds
            
            foreach ($urls as $index => $url) {
                // Add delay between requests to avoid rate limiting
                if ($index > 0 && $delay > 0) {
                    sleep($delay);
                }
                
                $result = self::get_url_content($url, $options);
                $results[] = array(
                    'url' => $url,
                    'result' => $result
                );
            }
            
            return $results;
        }
        
        /**
         * Search using Jina AI Search API (fallback when Google is blocked)
         * 
         * @param string $query Search query
         * @param array $options Additional options (api_key, limit, etc.)
         * @return array|WP_Error Search results or error
         */
        public static function search_jina_ai($query, $options = array()) {
            // Check if Jina AI API key is available
            $api_key = isset($options['api_key']) ? $options['api_key'] : 
                (isset($options['jina_api_key']) ? $options['jina_api_key'] : 
                (class_exists('AIAutotool_AI_Provider_API_Keys') ? AIAutotool_AI_Provider_API_Keys::get_jina_key() : get_option('aiautotool_jina_api_key', '')));
            
            if (empty($api_key)) {
                return new WP_Error('no_api_key', 'Jina AI API key is not configured. Please set up your Jina AI API token in the plugin settings to use this feature.');
            }
            
            // Build Jina AI Search URL
            $jina_search_url = 'https://s.jina.ai/?q=' . urlencode($query);
            
            // Prepare headers
            $headers = array(
                'Accept: application/json',
                'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36',
                'X-Respond-With: no-content' // Don't fetch full content, just search results
            );
            
            // Add API key to headers
            $headers[] = 'Authorization: Bearer ' . $api_key;
            
            // Initialize curl
            $ch = curl_init($jina_search_url);
            
            // Set curl options
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_TIMEOUT, isset($options['timeout']) ? $options['timeout'] : 30);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            
            // Execute request
            $response = curl_exec($ch);
            $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            $curl_error = curl_error($ch);
            curl_close($ch);
            
            // Check for curl errors
            if ($response === false || !empty($curl_error)) {
                return new WP_Error('curl_error', __('cURL Error: ', 'ai-auto-tool') . $curl_error);
            }
            
            // Check HTTP status code
            if ($http_code !== 200) {
                $error_msg = sprintf(__('HTTP Error: %d', 'ai-auto-tool'), $http_code);
                if ($http_code === 429) {
                    $error_msg = __('Rate limit exceeded. Please try again later.', 'ai-auto-tool');
                } elseif ($http_code === 401) {
                    $error_msg = __('Unauthorized. Please check your Jina AI API key.', 'ai-auto-tool');
                }
                return new WP_Error('http_error', $error_msg, array('http_code' => $http_code));
            }
            
            // Parse JSON response
            $json_data = json_decode($response, true);
            if (json_last_error() !== JSON_ERROR_NONE || !is_array($json_data)) {
                return new WP_Error('parse_error', __('Failed to parse Jina AI search response', 'ai-auto-tool'));
            }
            
            // Convert Jina AI format to our format
            $results = array(
                'organic' => array(),
                'ads' => array(),
                'featured_snippet' => null,
                'people_also_ask' => array(),
                'related_searches' => array()
            );
            
            // Jina AI returns results in different format, need to adapt
            if (isset($json_data['results']) && is_array($json_data['results'])) {
                foreach ($json_data['results'] as $item) {
                    $result = array(
                        'title' => isset($item['title']) ? $item['title'] : (isset($item['name']) ? $item['name'] : ''),
                        'url' => isset($item['url']) ? $item['url'] : (isset($item['link']) ? $item['link'] : ''),
                        'snippet' => isset($item['snippet']) ? $item['snippet'] : (isset($item['description']) ? $item['description'] : '')
                    );
                    
                    if (!empty($result['title']) && !empty($result['url'])) {
                        $results['organic'][] = $result;
                    }
                }
            } elseif (isset($json_data['data']) && is_array($json_data['data'])) {
                // Alternative format
                foreach ($json_data['data'] as $item) {
                    $result = array(
                        'title' => isset($item['title']) ? $item['title'] : '',
                        'url' => isset($item['url']) ? $item['url'] : '',
                        'snippet' => isset($item['snippet']) ? $item['snippet'] : ''
                    );
                    
                    if (!empty($result['title']) && !empty($result['url'])) {
                        $results['organic'][] = $result;
                    }
                }
            }
            
            return array(
                'success' => true,
                'query' => $query,
                'url' => $jina_search_url,
                'http_code' => $http_code,
                'results' => $results,
                'source' => 'jina_ai'
            );
        }
        
        /**
         * Get content from Google search results URLs
         * 
         * @param string $query Search query
         * @param int $limit Number of URLs to fetch content from (default: 5)
         * @param array $options Additional options
         * @return array|WP_Error Array of content results or error
         */
        public static function search_and_get_content($query, $limit = 5, $options = array()) {
            // Perform search
            $search_result = self::search($query, $options);
            
            if (is_wp_error($search_result)) {
                return $search_result;
            }
            
            // Get URLs from search results
            $urls = array();
            $organic_results = isset($search_result['results']['organic']) ? $search_result['results']['organic'] : array();
            
            foreach (array_slice($organic_results, 0, $limit) as $result) {
                if (isset($result['url']) && !empty($result['url'])) {
                    $urls[] = $result['url'];
                }
            }
            
            if (empty($urls)) {
                return new WP_Error('no_urls', __('No URLs found in search results', 'ai-auto-tool'));
            }
            
            // Get content from URLs
            $content_results = self::get_multiple_urls_content($urls, $options);
            
            // Combine search results with content
            $combined_results = array();
            foreach ($content_results as $index => $item) {
                $combined_results[] = array(
                    'url' => $item['url'],
                    'search_title' => isset($organic_results[$index]['title']) ? $organic_results[$index]['title'] : '',
                    'search_snippet' => isset($organic_results[$index]['snippet']) ? $organic_results[$index]['snippet'] : '',
                    'content' => is_wp_error($item['result']) ? null : $item['result'],
                    'error' => is_wp_error($item['result']) ? $item['result']->get_error_message() : null
                );
            }
            
            return array(
                'success' => true,
                'query' => $query,
                'search_results_count' => count($organic_results),
                'urls_fetched' => count($urls),
                'results' => $combined_results
            );
        }
    }
}

