<?php
namespace App\Controllers;

use App\Core\Auth;
use App\Core\Controller;
use App\Core\Database;
use App\Core\Request;
use App\Core\Session;
use App\Services\DeflectionSearch;

class KbController extends Controller
{
    public function index(): void
    {
        $status = Request::query('status', '');
        $where = ['1=1'];
        $params = [];
        if ($status !== '') { $where[] = 'status = :status'; $params['status'] = $status; }

        $articles = Database::all(
            "SELECT a.*, c.name AS category_name, u.name AS author_name FROM kb_articles a
             LEFT JOIN kb_categories c ON c.id = a.category_id
             LEFT JOIN users u ON u.id = a.author_id
             WHERE " . implode(' AND ', $where) . " ORDER BY a.updated_at DESC",
            $params
        );

        $this->render('kb/index', [
            'pageTitle' => 'Knowledge Base',
            'pageSubtitle' => count($articles) . ' article(s)',
            'articles' => $articles, 'status' => $status,
        ]);
    }

    public function search(): void
    {
        $q = trim((string)Request::query('q', ''));
        $results = DeflectionSearch::suggest($q, 'internal', 6);
        $results = array_map(fn($r) => [
            'id' => $r['id'], 'title' => $r['title'], 'excerpt' => strip_tags($r['excerpt']),
            'url' => \App\Core\View::url('/kb/' . $r['id']),
        ], $results);
        $this->json($results);
    }

    public function createForm(): void
    {
        $this->render('kb/edit', [
            'pageTitle' => 'New knowledge article', 'article' => null,
            'categories' => Database::all('SELECT * FROM kb_categories ORDER BY name'),
            'products' => Database::all('SELECT * FROM products WHERE is_active = 1 ORDER BY name'),
        ]);
    }

    public function store(): void
    {
        $this->requireCsrf();
        $id = Database::insert('kb_articles', [
            'category_id' => Request::post('category_id') ?: null,
            'product_id' => Request::post('product_id') ?: null,
            'title' => trim((string)Request::post('title')),
            'slug' => $this->slugify((string)Request::post('title')),
            'body' => (string)Request::post('body'),
            'keywords' => Request::post('keywords'),
            'visibility' => Request::post('visibility', 'internal'),
            'status' => 'draft',
            'author_id' => Auth::id(),
        ]);
        Session::flash('success', 'Article created as draft.');
        $this->redirect('/kb/' . $id . '/edit');
    }

    public function show(string $id): void
    {
        $article = Database::one('SELECT * FROM kb_articles WHERE id = :id', ['id' => $id]);
        if (!$article) { $this->notFound(); return; }
        Database::run('UPDATE kb_articles SET views = views + 1 WHERE id = :id', ['id' => $id]);
        $this->render('kb/show', ['pageTitle' => $article['title'], 'article' => $article]);
    }

    public function editForm(string $id): void
    {
        $article = Database::one('SELECT * FROM kb_articles WHERE id = :id', ['id' => $id]);
        if (!$article) { $this->notFound(); return; }
        $this->render('kb/edit', [
            'pageTitle' => 'Edit — ' . $article['title'], 'article' => $article,
            'categories' => Database::all('SELECT * FROM kb_categories ORDER BY name'),
            'products' => Database::all('SELECT * FROM products WHERE is_active = 1 ORDER BY name'),
        ]);
    }

    public function update(string $id): void
    {
        $this->requireCsrf();
        $this->saveFields($id);
        Session::flash('success', 'Article saved.');
        $this->redirect('/kb/' . $id . '/edit');
    }

    private function saveFields(string $id): void
    {
        $article = Database::one('SELECT * FROM kb_articles WHERE id = :id', ['id' => $id]);
        if (!$article) { $this->notFound(); return; }

        if ($article['body'] !== (string)Request::post('body') || $article['title'] !== Request::post('title')) {
            Database::insert('kb_article_versions', [
                'kb_article_id' => $id, 'version' => $article['version'], 'title' => $article['title'],
                'body' => $article['body'], 'edited_by' => Auth::id(),
            ]);
        }

        Database::update('kb_articles', [
            'category_id' => Request::post('category_id') ?: null,
            'product_id' => Request::post('product_id') ?: null,
            'title' => trim((string)Request::post('title')),
            'body' => (string)Request::post('body'),
            'keywords' => Request::post('keywords'),
            'visibility' => Request::post('visibility', 'internal'),
            'version' => (int)$article['version'] + 1,
        ], 'id = :id', ['id' => $id]);
    }

    public function publish(string $id): void
    {
        $this->requireCsrf();
        $this->saveFields($id);
        Database::update('kb_articles', ['status' => 'published', 'published_at' => date('Y-m-d H:i:s')], 'id = :id', ['id' => $id]);
        Session::flash('success', 'Article published.');
        $this->redirect('/kb');
    }

    public function retire(string $id): void
    {
        $this->requireCsrf();
        Database::update('kb_articles', ['status' => 'retired'], 'id = :id', ['id' => $id]);
        Session::flash('success', 'Article retired.');
        $this->redirect('/kb');
    }

    private function slugify(string $title): string
    {
        $slug = strtolower(trim(preg_replace('/[^a-z0-9]+/i', '-', $title), '-'));
        $base = $slug ?: 'article';
        $slug = $base; $i = 1;
        while (Database::scalar('SELECT COUNT(*) FROM kb_articles WHERE slug = :s', ['s' => $slug]) > 0) {
            $slug = $base . '-' . (++$i);
        }
        return $slug;
    }
}
