<?php
declare(strict_types=1);

namespace Celena\Module\Comments;

use Celena\Core\Database\Connection;
use Celena\Core\Http\Pagination;
use Celena\Core\Http\Request;
use Celena\Core\Http\Response;
use Celena\Core\Security\Auth;
use Celena\Core\Security\Csrf;
use Celena\Core\Security\Filter;
use Celena\Core\Security\Permission;
use Celena\Core\Template\Engine;
use Celena\Module\AdminBase\AdminController;
use Celena\Module\Settings\Options;

final class CommentsController extends AdminController
{
    private const STATUSES = ['pending', 'approved', 'spam', 'trash'];

    public function __construct(
        Engine $engine,
        Auth $auth,
        Options $options,
        private readonly Connection $conn,
    ) {
        parent::__construct($engine, $auth, $options);
    }

    public function index(Request $request): Response
    {
        if (!Permission::can($this->auth->user(), 'comments.read')) {
            return $this->redirect('/admin', 'Доступ запрещён.', 'error');
        }
        $filter = Filter::in($request->query('status'), self::STATUSES, '');
        $page = Filter::int($request->query('page', 1), 1);
        $q = $this->conn->builder('celena_comments');
        if ($filter !== '') {
            $q->where('status', '=', $filter);
        }
        $total = (clone $q)->count();
        $p = new Pagination($page, 30, $total);
        $rows = $q->orderBy('id', 'desc')->limit($p->perPage)->offset($p->offset)->get();
        return $this->view('admin/comments/index', [
            'comments' => $rows,
            'pagination' => $p->toArray('/admin/comments?page=:page' . ($filter !== '' ? '&status=' . $filter : '')),
            'current_filter' => $filter,
        ], 'comments', 'Комментарии');
    }

    public function setStatus(Request $request, array $params): Response
    {
        if (!Permission::can($this->auth->user(), 'comments.update')) {
            return $this->redirect('/admin/comments', 'Доступ запрещён.', 'error');
        }
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            return $this->redirect($this->backUrl(), 'CSRF.', 'error');
        }
        $id = Filter::int($params['id'] ?? 0);
        $status = Filter::in($request->input('status'), self::STATUSES, null);
        if ($status === null) {
            return $this->redirect($this->backUrl(), 'Неверный статус.', 'error');
        }
        $this->conn->builder('celena_comments')->where('id', '=', $id)->update([
            'status' => $status,
            'updated_at' => date('Y-m-d H:i:s'),
        ]);
        return $this->redirect($this->backUrl(), 'Статус: ' . $status);
    }

    public function delete(Request $request, array $params): Response
    {
        if (!Permission::can($this->auth->user(), 'comments.delete')) {
            return $this->redirect('/admin/comments', 'Доступ запрещён.', 'error');
        }
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            return $this->redirect($this->backUrl(), 'CSRF.', 'error');
        }
        $id = Filter::int($params['id'] ?? 0);
        $this->conn->builder('celena_comments')->where('id', '=', $id)->delete();
        return $this->redirect($this->backUrl(), 'Комментарий удалён.');
    }

    /** Возврат на список с сохранённым фильтром по статусу (берём из Referer). */
    private function backUrl(): string
    {
        $ref = (string) ($_SERVER['HTTP_REFERER'] ?? '');
        if ($ref !== '' && preg_match('~/admin/comments(\?[^#]*)?~', $ref, $m)) {
            return '/admin/comments' . ($m[1] ?? '');
        }
        return '/admin/comments';
    }
}
