// ---------------------------------------------------------------------------
// @executor-js/plugin-example/client
//
// Frontend half: a single page that calls the plugin's `greet` mutation
// and renders the response. Demonstrates the typed reactive client
// pattern — `ExampleClient.mutation(...)` is fully typed against
// `ExampleApi` from `./shared` with no codegen.
//
// Server-only deps (Effect, Node, executor.config) MUST NOT be imported
// here — the Vite plugin bundles this entry into the frontend.
// ---------------------------------------------------------------------------

import { useState } from "react";
import { defineClientPlugin, createPluginAtomClient, useAtomSet } from "@executor-js/sdk/client";

import { ExampleApi } from "./shared";

const ExampleClient = createPluginAtomClient(ExampleApi);

const greetAtom = ExampleClient.mutation("example", "greet");

function ExamplePage() {
  const [name, setName] = useState("world");
  const [result, setResult] = useState<string>();
  const doGreet = useAtomSet(greetAtom, { mode: "promise" });

  return (
    <div style={{ maxWidth: 480, margin: "2rem auto", padding: "1rem" }}>
      <h1 style={{ fontSize: "1.25rem", marginBottom: "1rem" }}>Example plugin</h1>
      <div style={{ display: "flex", gap: 8 }}>
        {/* The example plugin demonstrates the SDK in isolation, so it
            uses raw HTML controls instead of `@executor-js/react`'s
            wrapped components — third-party plugin authors don't have
            to depend on the host's component library. */}
        {/* oxlint-disable-next-line react/forbid-elements */}
        <input
          value={name}
          onChange={(e) => setName(e.target.value)}
          style={{
            flex: 1,
            padding: "0.5rem 0.75rem",
            border: "1px solid #ccc",
            borderRadius: 6,
          }}
        />
        {/* oxlint-disable-next-line react/forbid-elements */}
        <button
          type="button"
          onClick={async () => {
            // Mutation has no shared state to invalidate — explicit
            // empty `reactivityKeys` documents the intent for the
            // `require-reactivity-keys` rule.
            const g = await doGreet({ payload: { name }, reactivityKeys: [] });
            setResult(`${g.message} (#${g.count})`);
          }}
          style={{
            padding: "0.5rem 0.75rem",
            border: "1px solid #ccc",
            borderRadius: 6,
            cursor: "pointer",
          }}
        >
          Greet
        </button>
      </div>
      {result && (
        <pre style={{ marginTop: "1rem", padding: "0.5rem", background: "#f5f5f5" }}>{result}</pre>
      )}
    </div>
  );
}

export default defineClientPlugin({
  id: "example" as const,
  pages: [
    {
      path: "/",
      component: ExamplePage,
      nav: { label: "Example" },
    },
  ],
});
