pub fn Page(ctx: zx.PageContext) zx.Component {
    return (
        <div @allocator={ctx.arena}>
            <input type="text" name="name" value="Jodhn Doe" />
            <ProfileForm @rendering={.client} />
            <br />
            <hr />
            <br />
            <ProfileForm @rendering={.client} />
        </div>
    );
}

pub fn ProfileForm(ctx: *zx.ComponentContext) zx.Component {
    const count = ctx.state(i32, 0);
    const age = ctx.state(i32, 0);
    const p = ctx.state(Person, Person{
        .first_name = "Ziex",
        .last_name = "Dev",
        .age = 25,
    });

    const person = p.get();

    return (
        <div @allocator={ctx.allocator}>
            <span>Count: {count}</span>
            <button onclick={ctx.bind(serverIncrement)} value="server">+ (Server)</button>
            <button onclick={ctx.bind(clientIncrement)} value="server">+ (Client)</button>
            <button onclick={ctx.sbind(serverSIncrementHandler, .{count})} value="server">+ (Server sbind)</button>
            <br />

            <span>Age: {age}</span>
            <button onclick={ctx.bind(serverAgeIncrement)} value="server">+ (Server)</button>
            <br />

            <span>{person.first_name} {person.last_name} - {person.age}</span>
            <button onclick={ctx.bind(serverStateUpdateHandler)} value="server">Update (Server))</button>
            <br />

            <form action={handleSubmit}>
                <label>Username: <input type="text" name="username" required /></label>
                <input type="submit" name="action" value="Login" />
            </form>
            <button onclick={clientEvent} value="client">Client Event</button>
            <button onclick={serverEvent} value="server">Server Event</button>

            <form action={typedform}>
                <label>Name: <input type="text" name="name" defaultValue="John Doe" required /></label>
                <label>ID: <input type="text" name="id" defaultValue="123" required /></label>
                <input type="submit" name="action" value="Submit" />
            </form>

            <form action={directtypedform}>
                <label>Name: <input type="text" name="name" defaultValue="John Doe" required /></label>
                <label>ID: <input type="text" name="id" defaultValue="123" required /></label>
                <input type="submit" name="action" value="Submit" />
            </form>
        </div>
    );
}

const Person = struct {
    first_name: []const u8,
    last_name: []const u8,
    age: i32,
};

// This will execute on the browser
fn clientEvent(ctx: zx.client.Event) void {
    const val = ctx.value() orelse "";
    std.log.info("onclick: {s}\n", .{val});
}

// This runs on the server
fn serverEvent(ctx: zx.server.Event) void {
    const val = ctx.value() orelse "";
    std.log.info("onclick: {s}\n", .{val});
}

// This will execute on the browser
fn clientIncrement(ctx: *zx.client.Event.Stateful) void {
    const val = ctx.state(i32);
    val.set(val.get() + 1);
    std.log.info("increment: {d}\n", .{val.get()});
}

fn serverIncrement(e: *zx.server.Event.Stateful) void {
    const val = e.state(i32);
    val.set(val.get() + 1);
    std.log.info("increment: {d}\n", .{val.get()});
}

fn serverAgeIncrement(e: *zx.server.Event.Stateful) void {
    _ = e.state(i32);
    const val = e.state(i32);
    val.set(val.get() + 1);
}

fn serverSIncrementHandler(e: *zx.server.Event.Stateful) void {
    const val = e.state(i32);
    val.set(val.get() + 1);
    std.log.info("increment: {d}\n", .{val.get()});
}

fn serverStateUpdateHandler(e: *zx.server.Event.Stateful) void {
    _ = e.state(i32);
    _ = e.state(i32);
    var person = e.state(Person);

    const updated_person = Person{
        .first_name = "ZX",
        .last_name = "FW",
        .age = person.get().age + 1,
    };
    person.set(updated_person);
}

// This should be a server action
fn handleSubmit(ctx: zx.server.Action) void {
    // const formdata = ctx.request.formData();
    // const username = formdata.get("username") orelse "";

    // std.log.info("server form handler username: {s}", .{username});

    const data = ctx.data(struct {
        username: []const u8,
    });

    std.log.info("server form handler username: {s}", .{data.username});


// _ = data;

    //   const mformdata = ctx.request.multiFormData();
    //   const v = mformdata.get("name: []const u8");
    // const musername = if (mformdata.get("username")) |val| val.data else "";

    // std.log.info("server form handler musername: {s}", .{musername});
}

const FormData = struct {
    name: []const u8,
    id: i32,
};

// This should be a server action
fn typedform(ctx: zx.server.Action) void {
    const data = ctx.data(FormData);

    std.log.info("server form handler name: {s}, id: {d}", .{data.name, data.id});
}


// This should be a server action
fn directtypedform(data: FormData) void {
    std.log.info("server form handler name: {s}, id: {d}", .{data.name, data.id});
}

pub const options: zx.PageOptions = .{
    .methods = &.{ .GET, .POST },
};

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