<?php
namespace App\Core;

/** Abstraksi permintaan HTTP. */
class Request
{
    public static function method(): string
    {
        $m = strtoupper($_SERVER['REQUEST_METHOD'] ?? 'GET');
        if ($m === 'POST' && isset($_POST['_method'])) {
            $override = strtoupper((string)$_POST['_method']);
            if (in_array($override, ['PUT', 'PATCH', 'DELETE'], true)) return $override;
        }
        return $m;
    }

    public static function isPost(): bool { return self::method() === 'POST'; }
    public static function isGet(): bool  { return self::method() === 'GET'; }

    public static function isAjax(): bool
    {
        return strtolower($_SERVER['HTTP_X_REQUESTED_WITH'] ?? '') === 'xmlhttprequest'
            || str_contains(strtolower($_SERVER['HTTP_ACCEPT'] ?? ''), 'application/json');
    }

    public static function uri(): string
    {
        $uri = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?: '/';
        $base = Config::get('app.base_url', '');
        if ($base && str_starts_with($uri, $base)) {
            $uri = substr($uri, strlen($base));
        }
        $uri = '/' . trim($uri, '/');
        return $uri === '/' ? '/' : rtrim($uri, '/');
    }

    public static function ip(): string
    {
        foreach (['HTTP_CF_CONNECTING_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_REAL_IP', 'REMOTE_ADDR'] as $k) {
            if (!empty($_SERVER[$k])) {
                $ip = trim(explode(',', (string)$_SERVER[$k])[0]);
                if (filter_var($ip, FILTER_VALIDATE_IP)) return $ip;
            }
        }
        return '0.0.0.0';
    }

    public static function userAgent(): string
    {
        return mb_substr((string)($_SERVER['HTTP_USER_AGENT'] ?? ''), 0, 250);
    }

    public static function input(string $key, $default = null)
    {
        $v = $_POST[$key] ?? $_GET[$key] ?? $default;
        return is_string($v) ? trim($v) : $v;
    }

    public static function get(string $key, $default = null)
    {
        $v = $_GET[$key] ?? $default;
        return is_string($v) ? trim($v) : $v;
    }

    public static function post(string $key, $default = null)
    {
        $v = $_POST[$key] ?? $default;
        return is_string($v) ? trim($v) : $v;
    }

    public static function int(string $key, int $default = 0): int
    {
        $v = self::input($key, $default);
        return is_numeric($v) ? (int)$v : $default;
    }

    /** Membaca nilai uang dari input yang mungkin berformat Indonesia (1.250.000,50). */
    public static function money(string $key, float $default = 0.0): float
    {
        $v = self::input($key, null);
        if ($v === null || $v === '') return $default;
        return Num::parse((string)$v);
    }

    public static function date(string $key, ?string $default = null): ?string
    {
        $v = self::input($key, null);
        if (!$v) return $default;
        $d = Dates::parse((string)$v);
        return $d ?: $default;
    }

    public static function array(string $key): array
    {
        $v = $_POST[$key] ?? $_GET[$key] ?? [];
        return is_array($v) ? $v : ($v === '' ? [] : [$v]);
    }

    public static function bool(string $key, bool $default = false): bool
    {
        $v = self::input($key, null);
        if ($v === null) return $default;
        return in_array(strtolower((string)$v), ['1', 'true', 'on', 'yes', 'ya'], true);
    }

    public static function all(): array
    {
        return array_merge($_GET, $_POST);
    }

    public static function json(): array
    {
        $raw = file_get_contents('php://input') ?: '';
        $d = json_decode($raw, true);
        return is_array($d) ? $d : [];
    }

    public static function file(string $key): ?array
    {
        $f = $_FILES[$key] ?? null;
        if (!$f || ($f['error'] ?? UPLOAD_ERR_NO_FILE) === UPLOAD_ERR_NO_FILE) return null;
        return $f;
    }
}
