<?php
/**
 * (c) ININOUT & PYXIS. All Rights Reserved.
 * Wszelkie modyfikacje tego pliku wymagaja zgloszenia oraz zgody autorow.
 * Any modifications to this file require notification and consent of the authors.
 */
/**
 * i-BOK 5 - Global Admin Search (AJAX endpoint)
 *
 * Called via: admin.php?page=search&action=query&q=...
 * Returns JSON with grouped search results.
 *
 * Optymalizacja: dane klientów/zleceń/infra cache'owane w sesji na 30s
 * aby powtarzane wyszukiwania nie odpytywały bazy za każdym razem.
 */

$action = $_GET['action'] ?? '';

if ($action === 'query') {
    header('Content-Type: application/json; charset=utf-8');

    // Capture stray PHP output
    ob_start();

    try {
        $q = trim($_GET['q'] ?? '');
        if (mb_strlen($q) < 2) {
            ob_end_clean();
            echo json_encode(['results' => [], 'query' => $q]);
            exit;
        }

        $q_lower = mb_strtolower($q);
        $max_per_category = 5;
        $results = [];
        $cache_ttl = 30; // seconds

        // --- Helper: session cache for expensive reads ---
        $now = time();
        if (!isset($_SESSION['_search_cache'])) {
            $_SESSION['_search_cache'] = [];
        }

        /**
         * Get data from session cache or call function
         */
        function _search_cached($key, $callback) {
            global $cache_ttl, $now;
            if (isset($_SESSION['_search_cache'][$key]) &&
                ($now - $_SESSION['_search_cache'][$key]['t']) < $GLOBALS['cache_ttl']) {
                return $_SESSION['_search_cache'][$key]['d'];
            }
            $data = $callback();
            $_SESSION['_search_cache'][$key] = ['t' => $now, 'd' => $data];
            return $data;
        }

        // --- 1. Clients (by name, login, account number) ---
        $clients = _search_cached('clients', function() { return vbk_read_klienci(); });
        $client_matches = [];
        $matched_ids = [];
        foreach ($clients as $id => $c) {
            $searchable = mb_strtolower(
                $id . ' ' .
                ($c['login'] ?? '') . ' ' .
                ($c['nazwisko'] ?? '') . ' ' .
                ($c['nr_rachunku'] ?? '')
            );
            if (mb_strpos($searchable, $q_lower) !== false) {
                $client_matches[] = [
                    'label' => ($c['nazwisko'] ?? '') ?: ($c['login'] ?? $id),
                    'sublabel' => 'ID: ' . $id . (($c['login'] ?? '') ? ' | ' . $c['login'] : ''),
                    'icon' => 'bi-person',
                    'url' => 'admin.php?page=klient_info&id=' . urlencode($id),
                ];
                $matched_ids[] = $id;
                if (count($client_matches) >= $max_per_category) break;
            }
        }

        // --- 1b. Client contacts (tel, email, NIP, PESEL, address) ---
        // Single SQL query instead of loop — O(1) instead of O(N)
        if (count($client_matches) < $max_per_category) {
            $remaining = $max_per_category - count($client_matches);
            $contact_results = db_search_clients_by_contact($q, $remaining, $matched_ids);
            foreach ($contact_results as $cr) {
                $client_matches[] = [
                    'label' => $cr['nazwisko'] ?: ($cr['login'] ?: $cr['id']),
                    'sublabel' => 'ID: ' . $cr['id'] . ($cr['detail'] ? ' | ' . $cr['detail'] : ''),
                    'icon' => 'bi-person',
                    'url' => 'admin.php?page=klient_info&id=' . urlencode($cr['id']),
                ];
            }
        }

        if (!empty($client_matches)) {
            $results[] = [
                'category' => __('global_search.clients'),
                'icon' => 'bi-people',
                'items' => $client_matches,
            ];
        }

        // --- 2. Documents (invoices) ---
        $doc_matches = [];
        $docs = db_search_dokumenty($q, $max_per_category);
        foreach ($docs as $doc) {
            $doc_matches[] = [
                'label' => $doc['nr_faktury'] ?? '',
                'sublabel' => ($doc['kwota_brutto'] ?? '') . ' | ' . ($doc['data_wystawienia'] ?? ''),
                'icon' => 'bi-file-earmark-text',
                'url' => 'admin.php?page=klient_info&id=' . urlencode($doc['id_klienta'] ?? ''),
            ];
        }
        if (!empty($doc_matches)) {
            $results[] = [
                'category' => __('global_search.invoices'),
                'icon' => 'bi-file-earmark-text',
                'items' => $doc_matches,
            ];
        }

        // --- 3. Service orders ---
        $zlecenia = _search_cached('zlecenia', function() { return vbk_read_zlecenia(); });
        $service_matches = [];
        foreach ($zlecenia as $z) {
            $searchable = mb_strtolower(
                ($z['nr'] ?? '') . ' ' .
                ($z['nazwisko'] ?? '') . ' ' .
                ($z['tresc'] ?? '') . ' ' .
                ($z['miejscowosc'] ?? '')
            );
            if (mb_strpos($searchable, $q_lower) !== false) {
                $service_matches[] = [
                    'label' => '#' . ($z['nr'] ?? '') . ' - ' . ($z['nazwisko'] ?? ''),
                    'sublabel' => mb_substr($z['tresc'] ?? '', 0, 60) . (mb_strlen($z['tresc'] ?? '') > 60 ? '...' : ''),
                    'icon' => 'bi-tools',
                    'url' => 'admin.php?page=serwis&search=' . urlencode($q),
                ];
                if (count($service_matches) >= $max_per_category) break;
            }
        }
        if (!empty($service_matches)) {
            $results[] = [
                'category' => __('global_search.service'),
                'icon' => 'bi-tools',
                'items' => $service_matches,
            ];
        }

        // --- 4. Infrastructure ---
        $infra = _search_cached('infra', function() { return vbk_read_infra(); });
        $infra_matches = [];
        foreach ($infra as $dev) {
            $searchable = mb_strtolower(
                ($dev['ip'] ?? '') . ' ' .
                ($dev['mac'] ?? '') . ' ' .
                ($dev['nazwa'] ?? '') . ' ' .
                ($dev['typ_model'] ?? '') . ' ' .
                ($dev['funkcja'] ?? '')
            );
            if (mb_strpos($searchable, $q_lower) !== false) {
                $infra_matches[] = [
                    'label' => ($dev['nazwa'] ?? '') ?: ($dev['ip'] ?? ''),
                    'sublabel' => ($dev['ip'] ?? '') . (($dev['mac'] ?? '') ? ' | ' . $dev['mac'] : ''),
                    'icon' => 'bi-hdd-network',
                    'url' => 'admin.php?page=infra&search=' . urlencode($q),
                ];
                if (count($infra_matches) >= $max_per_category) break;
            }
        }
        if (!empty($infra_matches)) {
            $results[] = [
                'category' => __('global_search.infra'),
                'icon' => 'bi-hdd-network',
                'items' => $infra_matches,
            ];
        }

        // --- 5. Devices (MAC list) ---
        $maclista = _search_cached('maclista', function() { return vbk_read_maclista(); });
        $device_matches = [];
        foreach ($maclista as $dev) {
            $searchable = mb_strtolower(
                ($dev['ip'] ?? '') . ' ' .
                ($dev['mac'] ?? '') . ' ' .
                ($dev['ip_pub'] ?? '') . ' ' .
                ($dev['podl_do'] ?? '')
            );
            if (mb_strpos($searchable, $q_lower) !== false) {
                $device_matches[] = [
                    'label' => ($dev['ip'] ?? '') ?: ($dev['mac'] ?? ''),
                    'sublabel' => ($dev['mac'] ?? '') . (($dev['podl_do'] ?? '') ? ' | ' . $dev['podl_do'] : ''),
                    'icon' => 'bi-router',
                    'url' => 'admin.php?page=urzadzenia&search=' . urlencode($q),
                ];
                if (count($device_matches) >= $max_per_category) break;
            }
        }
        if (!empty($device_matches)) {
            $results[] = [
                'category' => __('global_search.devices'),
                'icon' => 'bi-router',
                'items' => $device_matches,
            ];
        }

        ob_end_clean();

        $json = json_encode(['results' => $results, 'query' => $q], JSON_INVALID_UTF8_SUBSTITUTE);
        if ($json === false) {
            echo json_encode(['results' => [], 'query' => $q, 'error' => 'JSON encode error: ' . json_last_error_msg()]);
        } else {
            echo $json;
        }

    } catch (\Throwable $e) {
        ob_end_clean();
        ibok_log("Global search error: " . $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine(), 'error');
        echo json_encode([
            'results' => [],
            'query'   => $_GET['q'] ?? '',
            'error'   => $e->getMessage(),
        ]);
    }

    exit;
}
