<?php
namespace App\Services;

use App\Core\Database;

/**
 * Knowledge-base matching used at the point of ticket creation (FR-SUP-056)
 * and for the agent's "insert KB article" action (FR-SUP-035).
 */
class DeflectionSearch
{
    public static function suggest(string $query, string $visibility = 'customer', int $limit = 5, ?int $productId = null): array
    {
        $query = trim($query);
        if ($query === '' || mb_strlen($query) < 3) return [];

        $sql = "SELECT id, title, slug, LEFT(body, 220) AS excerpt,
                       MATCH(title, body, keywords) AGAINST (:q IN NATURAL LANGUAGE MODE) AS relevance
                FROM kb_articles
                WHERE status = 'published' AND visibility = :vis";
        $params = ['q' => $query, 'vis' => $visibility];
        if ($productId) {
            $sql .= ' AND (product_id = :pid OR product_id IS NULL)';
            $params['pid'] = $productId;
        }
        $sql .= ' HAVING relevance > 0 ORDER BY relevance DESC LIMIT :lim';

        // LIMIT can't be bound as a normal param on all PDO drivers without emulation; inline safely.
        $sql = str_replace(':lim', (int)$limit, $sql);
        unset($params['lim']);

        try {
            return Database::all($sql, $params);
        } catch (\Throwable $e) {
            // Fall back to LIKE search if the FULLTEXT index isn't available (e.g. MyISAM-only host).
            $like = '%' . $query . '%';
            $sql2 = "SELECT id, title, slug, LEFT(body, 220) AS excerpt FROM kb_articles
                      WHERE status = 'published' AND visibility = :vis AND (title LIKE :like OR keywords LIKE :like)
                      LIMIT " . (int)$limit;
            return Database::all($sql2, ['vis' => $visibility, 'like' => $like]);
        }
    }
}
