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

test("compiles portable wrn markup to React Native components", () => {
  const code = compileNativeWireFile(`page Home {
    state count = 0
    view {
      <main class="screen">
        <h1>Count {count}</h1>
        <button @click="count++">Add</button>
        {#if count > 0}<p>Started</p>{:else}<p>Ready</p>{/if}
      </main>
    }
    style { .screen { padding: 24px; background-color: white; } }
  }`);
  expect(code).toContain("const [count, setCount] = useState(0)");
  expect(code).toContain('<View style={[styles["screen"] ]}>');
  expect(code).toContain("<Text>Count {count}</Text>");
  expect(code).toContain("onPress={() => { setCount(value => value + 1) }}");
  expect(code).toContain('"padding": 24');
  expect(() => new Bun.Transpiler({ loader: "tsx" }).transformSync(code)).not.toThrow();
});

test("rejects browser-only elements with an actionable error", () => {
  expect(() => compileNativeWireFile("page Data { view { <table></table> } }")).toThrow(
    NativeCompileError,
  );
});

test("compiles loops to native JSX", () => {
  const code = compileNativeWireFile(
    "page List { view { <ul>{#each items as item, i}<li>{item.name}</li>{:empty}<li>Empty</li>{/each}</ul> } }",
  );
  expect(code).toContain("(items).map((item, i)");
  expect(code).toContain("<Text>{item.name}</Text>");
});

test("selects mobile-only markup and events for native output", () => {
  const code = compileNativeWireFile(`page Platforms { view {
    <button data-native-only="mobile" @mobile-click="save()" @browser-click="copy()">Save</button>
    <p data-native-only="browser">Browser help</p>
  } }`);
  expect(code).toContain("onPress={() => { save() }}");
  expect(code).not.toContain("copy()");
  expect(code).not.toContain("Browser help");
});

test("rejects declarative Capacitor actions instead of silently dropping them in Expo", () => {
  expect(() =>
    compileNativeWireFile(
      `page Share { view { <button data-native-mobile="share">Share</button> } }`,
    ),
  ).toThrow("currently targets browser/Capacitor pages");
});

test("does not emit native visibility directives as React Native props", () => {
  const code = compileNativeWireFile(
    `page Support { view { <p data-native-requires="camera">Camera</p> } }`,
  );
  expect(code).not.toContain("data-native-requires");
});
