<?php

declare(strict_types=1);

namespace App\Controllers;

use Core\Auth;
use Core\Request;
use Core\Response;
use Core\Session;
use Core\Database;

/**
 * BaseController — shared behaviour for all controllers.
 */
abstract class BaseController
{
    protected Database $db;

    public function __construct()
    {
        $this->db = Database::getInstance();
    }

    // ── View Rendering ────────────────────────────────────────────────────────

    /**
     * @param array<string, mixed> $data
     */
    protected function view(string $view, array $data = [], string $layout = 'main'): void
    {
        // Allow controllers to override layout via $data['layout']
        if (isset($data['layout'])) {
            $layout = $data['layout'];
            unset($data['layout']);
        }
        $data['authUser'] = Auth::user();
        Response::view($view, $data, $layout);
    }

    // ── Redirects ─────────────────────────────────────────────────────────────

    protected function redirect(string $path): never
    {
        Response::redirect($path);
    }

    protected function back(): never
    {
        Response::back();
    }

    // ── JSON ──────────────────────────────────────────────────────────────────

    protected function json(array $data, int $code = 200): never
    {
        Response::json($data, $code);
    }

    protected function success(string $message, array $data = []): never
    {
        Response::success($message, $data);
    }

    protected function error(string $message, array $errors = [], int $code = 400): never
    {
        Response::error($message, $errors, $code);
    }

    // ── Flash ─────────────────────────────────────────────────────────────────

    protected function flash(string $type, string $message): void
    {
        Session::flash($type, $message);
    }

    // ── Auth Guard ────────────────────────────────────────────────────────────

    protected function requireAuth(): void
    {
        Auth::requireLogin();
    }

    protected function requirePermission(string $permission): void
    {
        $this->requireAuth();
        Auth::require($permission);
    }

    // ── Pagination ────────────────────────────────────────────────────────────

    protected function currentPage(): int
    {
        return max(1, Request::int('page', 1));
    }

    protected function offset(int $page, int $perPage = ITEMS_PER_PAGE): int
    {
        return ($page - 1) * $perPage;
    }
}
