<?php
declare(strict_types=1);

/**
 * Softra API smoke test:
 * 1) reads credentials from .env (format: "key: value")
 * 2) authenticates (/account/auth)
 * 3) fetches branches (/branch/list)
 * 4) fetches car models (/car/model/list?includeBrandDetails=true)
 *
 * Usage:
 *   php softra-test.php
 *   php softra-test.php branch=BYDGOSZCZ from=2026-03-30T12:00:00 to=2026-04-02T12:00:00 category=
 */

function fail(string $message, int $code = 1): never
{
    if (PHP_SAPI !== 'cli') {
        http_response_code(500);
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode(['ok' => false, 'error' => $message], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;
        exit($code);
    }

    if (defined('STDERR')) {
        fwrite(STDERR, $message . PHP_EOL);
    } else {
        echo $message . PHP_EOL;
    }
    exit($code);
}

function parseEnvFile(string $path): array
{
    if (!is_file($path)) {
        fail("Brak pliku .env: {$path}");
    }

    $result = [];
    $lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    if ($lines === false) {
        fail("Nie mogę odczytać pliku .env");
    }

    foreach ($lines as $line) {
        $line = trim($line);
        if ($line === '' || str_starts_with($line, '#')) {
            continue;
        }

        // supports:
        // key: value
        // key=value
        $sepPos = strpos($line, ':');
        if ($sepPos === false) {
            $sepPos = strpos($line, '=');
        }
        if ($sepPos === false) {
            continue;
        }

        $key = trim(substr($line, 0, $sepPos));
        $value = trim(substr($line, $sepPos + 1));
        $value = trim($value, "\"'");
        if ($key !== '') {
            $result[strtolower($key)] = $value;
        }
    }

    return $result;
}

function parseInputArgs(?array $argv = null): array
{
    $args = [];

    if (PHP_SAPI === 'cli') {
        $argv = $argv ?? [];
        foreach (array_slice($argv, 1) as $arg) {
            $pos = strpos($arg, '=');
            if ($pos === false) {
                continue;
            }
            $k = strtolower(trim(substr($arg, 0, $pos)));
            $v = trim(substr($arg, $pos + 1));
            $args[$k] = $v;
        }
        return $args;
    }

    foreach ($_GET as $k => $v) {
        if (!is_string($k)) {
            continue;
        }
        $args[strtolower($k)] = is_string($v) ? trim($v) : '';
    }

    return $args;
}

function requestJson(string $method, string $url, ?array $payload = null, array $headers = []): array
{
    $ch = curl_init($url);
    if ($ch === false) {
        fail('Nie udało się zainicjować cURL');
    }

    $httpHeaders = array_merge(['Accept: application/json'], $headers);
    if ($payload !== null) {
        $httpHeaders[] = 'Content-Type: application/json';
    }

    curl_setopt_array($ch, [
        CURLOPT_CUSTOMREQUEST => strtoupper($method),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => $httpHeaders,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_CONNECTTIMEOUT => 15,
    ]);

    if ($payload !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
    }

    $raw = curl_exec($ch);
    $err = curl_error($ch);
    $status = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($raw === false) {
        fail("Błąd połączenia cURL: {$err}");
    }

    $decoded = json_decode($raw, true);
    if (!is_array($decoded)) {
        $decoded = ['raw' => $raw];
    }

    return [
        'status' => $status,
        'body' => $decoded,
        'raw' => $raw,
    ];
}

$env = parseEnvFile(__DIR__ . DIRECTORY_SEPARATOR . '.env');
$args = parseInputArgs($argv ?? null);

$baseUrl = rtrim($env['url'] ?? '', '/');
$username = $env['username'] ?? '';
$password = $env['password'] ?? '';

if ($baseUrl === '' || $username === '' || $password === '') {
    fail('W .env muszą być pola: url, username, password');
}

$authRes = requestJson('POST', $baseUrl . '/account/auth', [
    'login' => $username,
    'password' => $password,
]);

if ($authRes['status'] !== 200 || empty($authRes['body']['token'])) {
    fail("Auth nieudany (HTTP {$authRes['status']}): {$authRes['raw']}");
}

$token = (string) $authRes['body']['token'];
$authHeader = ['Authorization: Bearer ' . $token];

$branchesRes = requestJson('GET', $baseUrl . '/branch/list', null, $authHeader);
if ($branchesRes['status'] !== 200 || !is_array($branchesRes['body'])) {
    fail("Pobranie oddziałów nieudane (HTTP {$branchesRes['status']}): {$branchesRes['raw']}");
}

$branches = $branchesRes['body'];
if (count($branches) === 0) {
    fail('API działa, ale /branch/list zwróciło pustą listę oddziałów');
}

$branch = $args['branch'] ?? ($branches[0]['relatedBranchName'] ?? $branches[0]['name'] ?? '');
if ($branch === '') {
    fail('Nie udało się ustalić branchName (podaj ręcznie: branch=NAZWA)');
}

$from = $args['from'] ?? (new DateTimeImmutable('+7 days'))->format('Y-m-d\TH:i:s');
$to = $args['to'] ?? (new DateTimeImmutable('+10 days'))->format('Y-m-d\TH:i:s');
$category = $args['category'] ?? ''; // empty = all categories

$modelsRes = requestJson(
    'POST',
    $baseUrl . '/car/model/list?includeBrandDetails=true',
    [
        'dateFrom' => $from,
        'dateTo' => $to,
        'branchName' => $branch,
        'category' => $category,
    ],
    $authHeader
);

if ($modelsRes['status'] !== 200 || !is_array($modelsRes['body'])) {
    fail("Pobranie listy aut nieudane (HTTP {$modelsRes['status']}): {$modelsRes['raw']}");
}

$models = $modelsRes['body'];

$result = [
    'ok' => true,
    'baseUrl' => $baseUrl,
    'branch' => $branch,
    'dateFrom' => $from,
    'dateTo' => $to,
    'modelsCount' => count($models),
    'models' => $models,
];

if (PHP_SAPI !== 'cli') {
    header('Content-Type: application/json; charset=utf-8');
}

echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;
