<?php
defined('ABSPATH') or die('Direct access not allowed');

class CodeEditor_Search {
    public function __construct() {
        add_action('wp_ajax_code_editor_search', [$this, 'handle_search_request']);
    }

    public function handle_search_request() {
        check_ajax_referer('code_editor_nonce', 'security');
        
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Unauthorized', 403);
        }

        $query = isset($_POST['query']) ? sanitize_text_field($_POST['query']) : '';
        $path = isset($_POST['path']) ? sanitize_text_field($_POST['path']) : '';
        $case_sensitive = isset($_POST['case_sensitive']) ? (bool)$_POST['case_sensitive'] : false;
        
        if (empty($query)) {
            wp_send_json_error('Empty search query', 400);
        }

        $results = $this->search_in_directory($query, $path, $case_sensitive);
        wp_send_json_success($results);
    }

    private function search_in_directory($query, $path, $case_sensitive) {
        $base_path = ABSPATH;
        $full_path = realpath($base_path . $path);
        
        if (strpos($full_path, $base_path) !== 0 || !is_dir($full_path)) {
            return [];
        }

        $results = [];
        $flags = $case_sensitive ? '' : 'i';
        $pattern = preg_quote($query, '/');
        
        $directory = new RecursiveDirectoryIterator($full_path);
        $iterator = new RecursiveIteratorIterator($directory);
        
        foreach ($iterator as $file) {
            if ($file->isFile() && $file->isReadable()) {
                $file_path = $file->getPathname();
                $relative_path = str_replace($base_path, '', $file_path);
                $content = file_get_contents($file_path);
                
                if (preg_match_all("/$pattern/$flags", $content, $matches, PREG_OFFSET_CAPTURE)) {
                    $file_results = [
                        'path' => $relative_path,
                        'matches' => []
                    ];
                    
                    foreach ($matches[0] as $match) {
                        $line = $this->get_line_number($content, $match[1]);
                        $file_results['matches'][] = [
                            'line' => $line,
                            'text' => $this->get_line_text($content, $match[1])
                        ];
                    }
                    
                    $results[] = $file_results;
                }
            }
        }
        
        return $results;
    }

    private function get_line_number($content, $offset) {
        return substr_count($content, "\n", 0, $offset) + 1;
    }

    private function get_line_text($content, $offset) {
        $start = strrpos($content, "\n", -$offset) + 1;
        $end = strpos($content, "\n", $offset);
        
        if ($end === false) {
            $end = strlen($content);
        }
        
        return substr($content, $start, $end - $start);
    }
}

new CodeEditor_Search();