<?php

declare(strict_types=1);

namespace FatBottom\Core;

final class Http
{
    public static function redirect(string $path): never
    {
        header('Location: ' . self::url($path));
        exit;
    }

    public static function abort(int $status, string $message): never
    {
        http_response_code($status);
        echo $message;
        exit;
    }

    public static function flash(string $type, string $message): void
    {
        $_SESSION['_flash'][] = ['type' => $type, 'message' => $message];
    }

    public static function consumeFlash(): array
    {
        $messages = $_SESSION['_flash'] ?? [];
        unset($_SESSION['_flash']);
        return $messages;
    }

    public static function old(array $input): void
    {
        $_SESSION['_old'] = $input;
    }

    public static function consumeOld(): array
    {
        $old = $_SESSION['_old'] ?? [];
        unset($_SESSION['_old']);
        return $old;
    }

    public static function path(): string
    {
        $path = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
        $path = is_string($path) ? rawurldecode($path) : '/';
        $basePath = self::basePath();

        if ($basePath !== '' && ($path === $basePath || str_starts_with($path, $basePath . '/'))) {
            $path = substr($path, strlen($basePath)) ?: '/';
        }

        $path = '/' . ltrim($path, '/');
        $path = rtrim($path, '/');
        return $path === '' ? '/' : $path;
    }

    public static function url(string $path = '/'): string
    {
        if (
            preg_match('#^(?:[a-z][a-z0-9+.-]*:)?//#i', $path)
            || str_starts_with($path, 'mailto:')
            || str_starts_with($path, 'tel:')
            || str_starts_with($path, '#')
        ) {
            return $path;
        }

        $basePath = self::basePath();
        $path = '/' . ltrim($path, '/');
        return ($basePath === '' ? '' : $basePath) . ($path === '/' ? '/' : $path);
    }

    public static function basePath(): string
    {
        static $basePath;
        if (isset($basePath)) {
            return $basePath;
        }

        $documentRoot = realpath((string) ($_SERVER['DOCUMENT_ROOT'] ?? ''));
        $applicationRoot = realpath(BASE_PATH);
        $publicRoot = realpath(BASE_PATH . '/public');

        if ($documentRoot && $publicRoot && $documentRoot === $publicRoot) {
            return $basePath = '';
        }

        if (
            $documentRoot
            && $applicationRoot
            && str_starts_with($applicationRoot . DIRECTORY_SEPARATOR, rtrim($documentRoot, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR)
        ) {
            $relative = substr($applicationRoot, strlen(rtrim($documentRoot, DIRECTORY_SEPARATOR)));
            return $basePath = rtrim('/' . trim(str_replace(DIRECTORY_SEPARATOR, '/', $relative), '/'), '/');
        }

        $script = str_replace('\\', '/', (string) ($_SERVER['SCRIPT_NAME'] ?? ''));
        $script = preg_replace('#/(?:public/)?index\.php$#', '', $script) ?? '';
        return $basePath = rtrim($script, '/');
    }
}
