<?php

require_once APP_ROOT . '/models/Item.php';
require_once APP_ROOT . '/models/Coin.php';

class SearchController
{
    private PDO $db;

    public function __construct()
    {
        if (!Session::isLoggedIn()) {
            header('Content-Type: application/json');
            echo json_encode(['error' => 'Unauthorized']);
            exit;
        }
        $this->db = Database::getInstance();
    }

    public function search(): void
    {
        $query = trim($_GET['q'] ?? '');
        $userId = Session::getUserId();

        if (empty($query)) {
            header('Content-Type: application/json');
            echo json_encode([]);
            exit;
        }

        $itemModel = new Item();
        $coinModel = new Coin();
        $results = [];

        // Search items (banknotes)
        $itemResults = $this->searchItems($itemModel, $query, $userId);
        $results = array_merge($results, $itemResults);

        // Search coins
        $coinResults = $this->searchCoins($coinModel, $query, $userId);
        $results = array_merge($results, $coinResults);

        // Sort by relevance (exact matches first)
        usort($results, function($a, $b) use ($query) {
            $aExact = 0;
            $bExact = 0;

            // Check for exact matches in key fields
            if (strcasecmp($a['nominal_value'], $query) === 0) $aExact++;
            if (strcasecmp($b['nominal_value'], $query) === 0) $bExact++;
            if (strcasecmp($a['catalog_number'], $query) === 0) $aExact++;
            if (strcasecmp($b['catalog_number'], $query) === 0) $bExact++;

            if ($aExact !== $bExact) {
                return $bExact - $aExact;
            }

            // Then sort by collection/subcollection/item order
            return $a['sort_order'] - $b['sort_order'];
        });

        // Limit to 20 results
        $results = array_slice($results, 0, 20);

        header('Content-Type: application/json');
        echo json_encode($results);
        exit;
    }

    private function searchItems(Item $itemModel, string $query, int $userId): array
    {
        $stmt = $this->db->prepare(
            'SELECT i.id, i.nominal_value, i.catalog_number, i.country, i.image_obverse, i.sort_order,
                    c.name as collection_name, s.name as subcollection_name, s.collection_id, s.id as subcollection_id,
                    "item" as type
             FROM items i
             JOIN subcollections s ON i.subcollection_id = s.id
             JOIN collections c ON s.collection_id = c.id
             WHERE c.user_id = :user_id
             AND (
                 i.nominal_value LIKE :query1 OR
                 i.catalog_number LIKE :query2 OR
                 i.country LIKE :query3 OR
                 i.description_obverse LIKE :query4 OR
                 i.description_reverse LIKE :query5 OR
                 i.additional_info LIKE :query6 OR
                 i.note LIKE :query7 OR
                 c.name LIKE :query8 OR
                 s.name LIKE :query9
             )
             ORDER BY c.sort_order ASC, s.sort_order ASC, i.sort_order ASC
             LIMIT 20'
        );

        $searchTerm = '%' . $query . '%';
        $stmt->execute([
            'user_id' => $userId,
            'query1' => $searchTerm,
            'query2' => $searchTerm,
            'query3' => $searchTerm,
            'query4' => $searchTerm,
            'query5' => $searchTerm,
            'query6' => $searchTerm,
            'query7' => $searchTerm,
            'query8' => $searchTerm,
            'query9' => $searchTerm
        ]);

        $results = [];
        foreach ($stmt->fetchAll() as $row) {
            $results[] = [
                'id' => $row['id'],
                'nominal_value' => $row['nominal_value'],
                'catalog_number' => $row['catalog_number'],
                'country' => $row['country'],
                'collection_name' => $row['collection_name'],
                'subcollection_name' => $row['subcollection_name'],
                'thumbnail' => $row['image_obverse'],
                'edit_url' => APP_URL . '/items/' . $row['id'] . '/edit',
                'type' => $row['type'],
                'sort_order' => $row['sort_order']
            ];
        }

        return $results;
    }

    private function searchCoins(Coin $coinModel, string $query, int $userId): array
    {
        $stmt = $this->db->prepare(
            'SELECT c.id, c.nominal_value, c.catalog_number, c.country, c.image_obverse, c.sort_order,
                    col.name as collection_name, s.name as subcollection_name, s.collection_id, s.id as subcollection_id,
                    "coin" as type
             FROM coins c
             JOIN subcollections s ON c.subcollection_id = s.id
             JOIN collections col ON s.collection_id = col.id
             WHERE col.user_id = :user_id
             AND (
                 c.nominal_value LIKE :query1 OR
                 c.catalog_number LIKE :query2 OR
                 c.country LIKE :query3 OR
                 c.description_obverse LIKE :query4 OR
                 c.description_reverse LIKE :query5 OR
                 c.additional_info LIKE :query6 OR
                 c.note LIKE :query7 OR
                 col.name LIKE :query8 OR
                 s.name LIKE :query9
             )
             ORDER BY col.sort_order ASC, s.sort_order ASC, c.sort_order ASC
             LIMIT 20'
        );

        $searchTerm = '%' . $query . '%';
        $stmt->execute([
            'user_id' => $userId,
            'query1' => $searchTerm,
            'query2' => $searchTerm,
            'query3' => $searchTerm,
            'query4' => $searchTerm,
            'query5' => $searchTerm,
            'query6' => $searchTerm,
            'query7' => $searchTerm,
            'query8' => $searchTerm,
            'query9' => $searchTerm
        ]);

        $results = [];
        foreach ($stmt->fetchAll() as $row) {
            $results[] = [
                'id' => $row['id'],
                'nominal_value' => $row['nominal_value'],
                'catalog_number' => $row['catalog_number'],
                'country' => $row['country'],
                'collection_name' => $row['collection_name'],
                'subcollection_name' => $row['subcollection_name'],
                'thumbnail' => $row['image_obverse'],
                'edit_url' => APP_URL . '/coins/' . $row['id'] . '/edit',
                'type' => $row['type'],
                'sort_order' => $row['sort_order']
            ];
        }

        return $results;
    }
}
