#!/usr/bin/env php
<?php

declare(strict_types=1);

function assert_true(bool $cond, string $msg): void
{
    if (!$cond) {
        fwrite(STDERR, "[FAIL] {$msg}\n");
        exit(1);
    }
}

function request(string $method, string $route, array $json = [], array $headers = []): array|WP_Error
{
    $req = new WP_REST_Request($method, $route, $json, $headers);
    return rest_do_request($req);
}

function unwrap(array|WP_Error $res, string $context): array
{
    if ($res instanceof WP_Error) {
        $status = $res->data['status'] ?? 500;
        fwrite(STDERR, "[FAIL] {$context}: {$res->code} {$res->message} ({$status})\n");
        exit(1);
    }
    return $res;
}

require __DIR__ . '/wp_emulation.php';

$html = do_shortcode('[calendar]');
assert_true(str_contains($html, 'cp-login-btn'), 'calendar shortcode should render login button');
assert_true(str_contains($html, 'cp-create-btn'), 'calendar shortcode should render create button');
assert_true(str_contains($html, 'cp-public-list'), 'calendar shortcode should render public list');
assert_true(str_contains($html, 'cp-verify-btn'), 'calendar shortcode should render verify action');
assert_true(str_contains($html, 'cp-reset-request-btn'), 'calendar shortcode should render reset action');
assert_true(str_contains($html, 'cp-future-only'), 'calendar shortcode should render future-only control');
assert_true(str_contains($html, 'cp-theme'), 'calendar shortcode should render theme selector');
assert_true(str_contains($html, 'cp-delete-occ-confirm-btn'), 'calendar shortcode should render delete occurrence control');

$reg = unwrap(request('POST', '/calendar/v1/users/register', [
    'email' => 'ui-emu@example.test',
    'password' => 'pass12345',
    'debug_tokens' => true,
]), 'register');
$verify = (string) ($reg['data']['verify_token'] ?? '');
$userId = (int) ($reg['data']['user']['id'] ?? 0);
assert_true($verify !== '' && $userId > 0, 'registration should provide token/id in debug mode');

unwrap(request('POST', '/calendar/v1/users/verify', ['token' => $verify]), 'verify');
unwrap(request('PATCH', '/calendar/v1/admin/users/' . $userId . '/approve', []), 'approve');

$GLOBALS['wp_user'] = [
    'id' => 0,
    'email' => '',
    'caps' => [],
];

$authHeader = 'Basic ' . base64_encode('ui-emu@example.test:pass12345');
$me = unwrap(request('GET', '/calendar/v1/users/me', [], ['Authorization' => $authHeader]), 'users me');
assert_true((string) ($me['data']['email'] ?? '') === 'ui-emu@example.test', 'me endpoint should resolve basic user');

$created = unwrap(request('POST', '/calendar/v1/events', [
    'title' => 'UI Emu Event',
    'description' => 'ui flow',
    'location' => 'Desk',
    'category' => 'Test',
    'all_day_event' => false,
    'start_datetime' => '2026-06-01T10:00:00+01:00',
    'end_datetime' => '2026-06-01T11:00:00+01:00',
    'repeat_type' => 'daily',
    'repeat_interval' => 1,
    'repeat_range_mode' => 'count',
    'repeat_count' => 3,
], ['Authorization' => $authHeader]), 'create event');
$eventId = (int) ($created['data']['id'] ?? 0);
assert_true($eventId > 0, 'basic-auth user should be able to create event');

unwrap(request('DELETE', '/calendar/v1/events/' . $eventId . '/occurrences/' . rawurlencode('2026-06-02T10:00:00+01:00'), [], ['Authorization' => $authHeader]), 'delete occurrence');
$occ = unwrap(request('GET', '/calendar/v1/events/' . $eventId . '/occurrences', ['from' => '2026-06-01', 'months' => 1], ['Authorization' => $authHeader]), 'list occurrences');
$days = [];
foreach ((array) ($occ['data'] ?? []) as $row) {
    $days[] = substr((string) ($row['occurrence_start'] ?? ''), 0, 10);
}
assert_true(!in_array('2026-06-02', $days, true), 'deleted occurrence should not remain');

unwrap(request('DELETE', '/calendar/v1/events/' . $eventId, [], ['Authorization' => $authHeader]), 'delete event');
$deletedEvent = request('GET', '/calendar/v1/events/' . $eventId, [], ['Authorization' => $authHeader]);
assert_true($deletedEvent instanceof WP_Error, 'deleted event should not resolve');
assert_true(($deletedEvent->data['status'] ?? 0) === 404, 'deleted event fetch should return 404');

$GLOBALS['wp_user'] = [
    'id' => 1,
    'email' => 'admin@example.test',
    'caps' => ['manage_options', 'edit_posts'],
];
unwrap(request('DELETE', '/calendar/v1/admin/users/' . $userId, []), 'remove user');
$GLOBALS['wp_user'] = [
    'id' => 0,
    'email' => '',
    'caps' => [],
];
$meAfterRemove = request('GET', '/calendar/v1/users/me', [], ['Authorization' => $authHeader]);
assert_true($meAfterRemove instanceof WP_Error, 'removed user should not authenticate');
assert_true(($meAfterRemove->data['status'] ?? 0) === 401, 'removed user me endpoint should return 401');

echo "[PASS] ui-e2e wp emulation\n";
