<?php

declare(strict_types=1);

namespace App\Models;

use App\Core\BaseModel;

final class KnowledgeBaseModel extends BaseModel
{
    protected string $table = 'knowledge_base_articles';
    protected array $fillable = ['business_line_id', 'category', 'question', 'answer', 'is_active'];
    protected bool $softDeletes = true;
    protected bool $auditStamps = false;

    public function allActive(?int $businessLineId = null): array
    {
        $sql = 'SELECT * FROM knowledge_base_articles WHERE is_active = 1 AND deleted_at IS NULL';
        $bindings = [];

        if ($businessLineId !== null) {
            $sql .= ' AND (business_line_id = :bl OR business_line_id IS NULL)';
            $bindings['bl'] = $businessLineId;
        }
        $sql .= ' ORDER BY category, question';

        $stmt = $this->db->prepare($sql);
        $stmt->execute($bindings);

        return $stmt->fetchAll();
    }

    /**
     * FULLTEXT search against question+answer, used by both the
     * Chatbot's FAQ feature and the AI Assistant's "Answer Questions"
     * tool. Falls back to a LIKE search for very short queries (MySQL
     * FULLTEXT ignores queries shorter than the configured minimum
     * word length, commonly 3-4 chars, and stopwords).
     */
    public function search(string $query, ?int $businessLineId = null, int $limit = 5): array
    {
        $conditions = ['is_active = 1', 'deleted_at IS NULL'];
        $bindings = ['query_select' => $query, 'query_where' => $query];

        if ($businessLineId !== null) {
            $conditions[] = '(business_line_id = :bl OR business_line_id IS NULL)';
            $bindings['bl'] = $businessLineId;
        }

        $sql = 'SELECT *, MATCH(question, answer) AGAINST(:query_select IN NATURAL LANGUAGE MODE) AS relevance
                FROM knowledge_base_articles
                WHERE ' . implode(' AND ', $conditions) . ' AND MATCH(question, answer) AGAINST(:query_where IN NATURAL LANGUAGE MODE)
                ORDER BY relevance DESC LIMIT :limit';

        $stmt = $this->db->prepare($sql);
        foreach ($bindings as $k => $v) {
            $stmt->bindValue($k, $v);
        }
        $stmt->bindValue('limit', $limit, \PDO::PARAM_INT);
        $stmt->execute();
        $results = $stmt->fetchAll();

        if ($results !== []) {
            return $results;
        }

        // Fallback: plain LIKE search so short/stopword-only queries still find something.
        $likeSql = 'SELECT * FROM knowledge_base_articles WHERE ' . implode(' AND ', $conditions)
            . ' AND (question LIKE :like_q OR answer LIKE :like_a) LIMIT :limit';
        $likeStmt = $this->db->prepare($likeSql);
        if ($businessLineId !== null) {
            $likeStmt->bindValue('bl', $businessLineId);
        }
        $likeStmt->bindValue('like_q', '%' . $query . '%');
        $likeStmt->bindValue('like_a', '%' . $query . '%');
        $likeStmt->bindValue('limit', $limit, \PDO::PARAM_INT);
        $likeStmt->execute();

        return $likeStmt->fetchAll();
    }

    public function incrementViewCount(int $id): void
    {
        $this->db->prepare('UPDATE knowledge_base_articles SET view_count = view_count + 1 WHERE id = :id')->execute(['id' => $id]);
    }
}
