<?php
declare(strict_types=1);

header('Content-Type: application/json; charset=utf-8');

$dataDir = __DIR__ . DIRECTORY_SEPARATOR . 'data';
$dataFile = $dataDir . DIRECTORY_SEPARATOR . 'session.json';

if (!is_dir($dataDir)) {
    mkdir($dataDir, 0775, true);
}

if (!file_exists($dataFile)) {
    file_put_contents($dataFile, "[]\n", LOCK_EX);
}

function respond(int $code, array $payload): void {
    http_response_code($code);
    echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

function read_sessions(string $dataFile): array {
    $raw = file_get_contents($dataFile);
    $decoded = json_decode($raw ?: '[]', true);
    return is_array($decoded) ? $decoded : [];
}

function write_sessions(string $dataFile, array $sessions): void {
    $tmp = $dataFile . '.tmp';
    $json = json_encode(array_values($sessions), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    if ($json === false) {
        respond(500, ['error' => 'Gagal encode JSON.']);
    }
    if (file_put_contents($tmp, $json . PHP_EOL, LOCK_EX) === false) {
        respond(500, ['error' => 'Gagal menulis file temporary. Cek permission folder data/.']);
    }
    if (!rename($tmp, $dataFile)) {
        @unlink($tmp);
        respond(500, ['error' => 'Gagal menyimpan data/session.json. Cek permission folder data/.']);
    }
}

function get_json_body(): array {
    $raw = file_get_contents('php://input');
    if ($raw === false || trim($raw) === '') return [];
    $decoded = json_decode($raw, true);
    if (!is_array($decoded)) respond(400, ['error' => 'JSON body tidak valid.']);
    return $decoded;
}

function new_id(string $prefix): string {
    return $prefix . '_' . base_convert((string) time(), 10, 36) . '_' . bin2hex(random_bytes(4));
}

$action = $_GET['action'] ?? 'sessions';
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';

try {
    if ($action === 'sessions' && $method === 'GET') {
        respond(200, ['sessions' => read_sessions($dataFile)]);
    }

    if ($action === 'create' && $method === 'POST') {
        $body = get_json_body();
        $name = trim((string)($body['name'] ?? ''));

        if ($name === '') respond(400, ['error' => 'Nama session wajib diisi.']);

        $sessions = read_sessions($dataFile);
        $now = gmdate('c');

        $session = $body;
        $session['id'] = $session['id'] ?? new_id('sess');
        $session['name'] = $name;
        $session['createdAt'] = $session['createdAt'] ?? $now;
        $session['updatedAt'] = $now;

        $sessions[] = $session;
        write_sessions($dataFile, $sessions);

        respond(201, ['session' => $session]);
    }

    if ($action === 'update' && $method === 'POST') {
        $id = trim((string)($_GET['id'] ?? ''));
        if ($id === '') respond(400, ['error' => 'ID session kosong.']);

        $body = get_json_body();
        $name = trim((string)($body['name'] ?? ''));

        if ($name === '') respond(400, ['error' => 'Nama session wajib diisi.']);

        $sessions = read_sessions($dataFile);
        $found = false;
        $updated = null;

        foreach ($sessions as $idx => $session) {
            if (($session['id'] ?? '') === $id) {
                $updated = array_merge($session, $body);
                $updated['id'] = $id;
                $updated['name'] = $name;
                $updated['updatedAt'] = gmdate('c');
                $sessions[$idx] = $updated;
                $found = true;
                break;
            }
        }

        if (!$found) respond(404, ['error' => 'Session tidak ditemukan.']);

        write_sessions($dataFile, $sessions);
        respond(200, ['session' => $updated]);
    }

    if ($action === 'delete' && $method === 'POST') {
        $id = trim((string)($_GET['id'] ?? ''));
        if ($id === '') respond(400, ['error' => 'ID session kosong.']);

        $sessions = read_sessions($dataFile);
        $filtered = [];

        foreach ($sessions as $session) {
            if (($session['id'] ?? '') !== $id) $filtered[] = $session;
        }

        write_sessions($dataFile, $filtered);
        respond(200, ['ok' => true]);
    }

    respond(404, ['error' => 'Endpoint tidak ditemukan.']);
} catch (Throwable $e) {
    respond(500, ['error' => $e->getMessage()]);
}
