pub fn Page(ctx: zx.PageContext) !zx.Component {
    std.log.info("Starting fetch request (server-side)...", .{});

    // Server-side: use blocking Io
    const result = try zx.fetch(.blocking, ctx.arena, "https://jsonplaceholder.typicode.com/todos/1", .{});
    var res = result orelse return error.FetchError;
    defer res.deinit();

    const t = res.text() catch |err| {
        std.log.err("Fetch text error: {s}", .{@errorName(err)});
        return error.FetchTextError;
    };

    std.log.info("Fetch completed (server-side): {s}", .{t});

    return (
        <div @allocator={ctx.arena} class="todo-container">
            <TimerDemo @rendering={.client} />
        </div>
    );
}

// Timer state
var interval_count: u32 = 0;
var interval_id: ?u64 = null;

/// Timer Demo Component
pub fn TimerDemo(allocator: zx.Allocator) zx.Component {
    return (
        <div @{allocator} class="timer-demo">
            <h3 class="timer-title">⏱️ Timer Demo</h3>
            <p class="timer-subtitle">Test setTimeout and setInterval from WASM</p>

            <div class="timer-buttons">
                <button class="timer-btn timeout-btn" onclick={startTimeout}>
                    setTimeout (2s)
                </button>
                <button class="timer-btn interval-btn" onclick={toggleInterval}>
                    {if (interval_id != null) "Stop Interval" else "Start Interval (1s)"}
                </button>
                <button class="timer-btn fetch-btn" onclick={doFetch}>
                    Fetch API
                </button>
            </div>

            <div class="timer-output">
                <span class="timer-label">Interval ticks: </span>
                <strong class="timer-count">{interval_count}</strong>
            </div>

            <p class="timer-hint">Check browser console for output</p>
        </div>
    );
}

fn startTimeout(_: zx.EventContext) void {
    std.log.info("setTimeout started (2 seconds)...", .{});
    _ = zx.client.setTimeout(&onTimeoutFired, 2000);
}

fn toggleInterval(_: zx.EventContext) void {
    if (interval_id) |id| {
        zx.client.clearInterval(id);
        interval_id = null;
        std.log.info("Interval stopped", .{});
    } else {
        interval_count = 0;
        interval_id = zx.client.setInterval(&onIntervalTick, 1000);
        std.log.info("Interval started (every 1 second)", .{});
    }

    zx.rerender();
}

fn onIntervalTick() void {
    interval_count += 1;
    zx.rerender();
}

fn onTimeoutFired() void {
    std.log.info("setTimeout fired after 2 seconds!", .{});
}

/// Callback for fetch completion
fn onFetchComplete(response: ?*zx.Fetch.Response, err: ?zx.Fetch.FetchError) void {
    if (err) |e| {
        std.log.err("Fetch error!", .{});
        std.log.err("Fetch error: {s}", .{@errorName(e)});
        return;
    }

    if (response) |res| {
        defer res.deinit();
        const text = res.text() catch |e| {
            std.log.err("Fetch text error: {s}", .{@errorName(e)});
            return;
        };
        std.log.info("Fetch completed! Response:", .{});
        std.log.info("Fetch text: {s}", .{text});
    }
}

fn doFetch(_: zx.EventContext) void {
    std.log.info("Starting fetch request (client-side)...", .{});

    _ = zx.fetch(
        .wasm(&onFetchComplete),
        zx.client_allocator,
        "https://jsonplaceholder.typicode.com/todos/1",
        .{},
    ) catch |err| {
        std.log.err("Fetch init error: {s}", .{@errorName(err)});
    };

    std.log.info("Fetch initiated (async)", .{});
}

const zx = @import("zx");
const std = @import("std");
