import { expect, test } from "bun:test";
import { generate, parse } from "../src/index.ts";

test("Async syntax compiles loading, success and error branches into inert templates", () => {
  const code = generate(
    parse(`page Users {
      load client users { return [{ name: "Ada" }] }
      view {
        <Async source="users" retries="3">
          <Loading><p>Loading users</p></Loading>
          <Success data="users"><p>{users.name}</p></Success>
          <Error error="error"><p>{error.message}</p></Error>
        </Async>
      }
    }`),
  );
  expect(code).toContain('data-wrn-async="users"');
  expect(code).toContain('data-wrn-async-retries="3"');
  expect(code).toContain("data-wrn-async-loading");
  expect(code).toContain("data-wrn-async-success");
  expect(code).toContain("data-wrn-async-error");
  expect(code).toContain("__wrnexusClientLoad");
});

test("server named loads render Async success content during SSR", () => {
  const code = generate(
    parse(`page Users {
      load server users { return { name: "Ada" } }
      view {
        <Async source="users">
          <Loading><p>Loading</p></Loading>
          <Success><p>{users.name}</p></Success>
          <Error><p>Failed</p></Error>
        </Async>
      }
    }`),
  );
  expect(code).toContain('const users = ctx["users"]');
  expect(code).toContain('data-wrn-async-resolved="true"');
  expect(code).toContain('ctx["users"] !== undefined');
});

test("named loads support memoized dependencies and deferred execution", () => {
  const code = generate(
    parse(`page Data {
      load server account { return { id: 7 } }
      load server projects after account { return [account.id] }
      load server audit after projects defer { return { project: projects[0] } }
      view { <Async source="audit"><Loading>Wait</Loading><Success>Ready</Success></Async> }
    }`),
  );
  expect(code).toContain("const account = await __load_account()");
  expect(code).toContain("const projects = await __load_projects()");
  expect(code).toContain("__promise_projects ??=");
  expect(code).toContain("export async function __wrnexusClientLoad");
  expect(code).toContain('return { "audit": __values[0] }');
});

test("load dependency cycles and cross-phase server dependencies fail compilation", () => {
  expect(() =>
    parse(
      `page Cycle { load server first after second { return 1 } load server second after first { return 2 } view { <p>x</p> } }`,
    ),
  ).toThrow("cycle");
  expect(() =>
    parse(
      `page Phase { load client browser { return 1 } load server invalid after browser { return 2 } view { <p>x</p> } }`,
    ),
  ).toThrow("cannot depend");
});
