<?php

declare(strict_types=1);

namespace Core;

/**
 * Response — HTTP response helpers.
 */
final class Response
{
    // ── Redirects ─────────────────────────────────────────────────────────────

    public static function redirect(string $path, int $code = 302): never
    {
        $url = str_starts_with($path, 'http') ? $path : base_url() . $path;
        header('Location: ' . $url, true, $code);
        exit;
    }

    public static function back(): never
    {
        $referer = $_SERVER['HTTP_REFERER'] ?? base_url() . '/dashboard';
        header('Location: ' . $referer);
        exit;
    }

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

    /**
     * @param array<string, mixed> $data
     */
    public static function json(array $data, int $code = 200): never
    {
        http_response_code($code);
        header('Content-Type: application/json; charset=utf-8');
        header('X-Content-Type-Options: nosniff');
        echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        exit;
    }

    public static function success(string $message, array $data = [], int $code = 200): never
    {
        self::json(['success' => true, 'message' => $message, 'data' => $data], $code);
    }

    public static function error(string $message, array $errors = [], int $code = 400): never
    {
        self::json(['success' => false, 'message' => $message, 'errors' => $errors], $code);
    }

    // ── Views ─────────────────────────────────────────────────────────────────

    /**
     * Render a view file with data extracted into scope.
     *
     * @param array<string, mixed> $data
     */
    public static function view(string $view, array $data = [], ?string $layout = 'main'): void
    {
        extract($data, EXTR_SKIP);

        $viewFile = VIEW_PATH . '/' . str_replace('.', '/', $view) . '.php';

        if (!file_exists($viewFile)) {
            throw new \RuntimeException("View [{$view}] not found at {$viewFile}.");
        }

        if ($layout === null) {
            // No layout — render view directly
            require $viewFile;
            return;
        }

        // Capture view content
        ob_start();
        require $viewFile;
        $content = ob_get_clean();

        $layoutFile = VIEW_PATH . '/layouts/' . $layout . '.php';

        if (!file_exists($layoutFile)) {
            throw new \RuntimeException("Layout [{$layout}] not found.");
        }

        require $layoutFile;
    }

    // ── Abort ─────────────────────────────────────────────────────────────────

    public static function abort(int $code, string $message = ''): never
    {
        http_response_code($code);
        $errorView = VIEW_PATH . "/errors/{$code}.php";

        if (file_exists($errorView)) {
            require $errorView;
        } else {
            echo "<h1>Error {$code}</h1><p>" . htmlspecialchars($message) . '</p>';
        }
        exit;
    }
}
