/* generic highlighter for generated Swift/Kotlin — strings, numbers, types, calls */
function hlGeneric(src) {
  const esc = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
  const re = /("[^"]*"|\\\([^)]*\)|\$\w+)|(\b\d+\b)|(\b[A-Z][A-Za-z0-9_]*\b)|(\.[a-z][A-Za-z0-9_]*)|([A-Za-z_]\w*)/g;
  let out = "", last = 0, m;
  while ((m = re.exec(src)) !== null) {
    out += esc(src.slice(last, m.index));
    const [w, str, num, type, dot, word] = m;
    if (str) out += `<span class="s">${esc(str)}</span>`;
    else if (num) out += `<span class="n">${num}</span>`;
    else if (type) out += `<span class="t">${type}</span>`;
    else if (dot) out += `<span class="f">${esc(dot)}</span>`;
    else out += esc(word);
    last = m.index + w.length;
  }
  out += esc(src.slice(last));
  return out;
}

/* codegen for the demo subset — representative, idiomatic-looking output */
function genSwift(parsed) {
  const body = parsed.els
    .map((el) => {
      if (el.kind === "text") {
        let s = `    Text("${el.text}")`;
        if (el.mods.includes("big")) s += "\n        .font(.title)";
        if (el.mods.includes("bold")) s += "\n        .bold()";
        if (el.mods.includes("gray")) s += "\n        .foregroundColor(.secondary)";
        return s;
      }
      if (el.kind === "button")
        return `    Button("${el.text}") {\n        // action\n    }${el.mods.includes("red") ? "\n    .foregroundColor(.red)" : ""}`;
      if (el.kind === "textfield") return `    TextField("${el.placeholder}", text: $newTitle)`;
      if (el.kind === "toggle") return `    Toggle("${el.label}", isOn: $${el.label.replace(/\W/g, "")})`;
      if (el.kind === "spacer") return "    Spacer()";
      return "";
    })
    .filter(Boolean)
    .join("\n");
  return `struct ${parsed.title}View: View {\n  var body: some View {\n    VStack(spacing: 16) {\n${body}\n    }\n  }\n}`;
}

function genKotlin(parsed) {
  const body = parsed.els
    .map((el) => {
      if (el.kind === "text") {
        const args = ['"' + el.text + '"'];
        if (el.mods.includes("big")) args.push("fontSize = 24.sp");
        if (el.mods.includes("bold")) args.push("fontWeight = FontWeight.Bold");
        if (el.mods.includes("gray")) args.push("color = Color.Gray");
        return `    Text(${args.join(", ")})`;
      }
      if (el.kind === "button")
        return `    Button(onClick = { /* action */ }) {\n        Text("${el.text}")\n    }`;
      if (el.kind === "textfield")
        return `    OutlinedTextField(value = newTitle, onValueChange = { newTitle = it }, label = { Text("${el.placeholder}") })`;
      if (el.kind === "toggle") return `    Switch(checked = ${el.label.replace(/\W/g, "")}, onCheckedChange = {})`;
      if (el.kind === "spacer") return "    Spacer(modifier = Modifier.weight(1f))";
      return "";
    })
    .filter(Boolean)
    .join("\n");
  return `@Composable\nfun ${parsed.title}Screen() {\n  Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {\n${body}\n  }\n}`;
}

const GH = (
  <svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor" aria-hidden="true">
    <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z" />
  </svg>
);

const STARTER = `app CounterApp:
  name: "Counter"
  start: Home

screen Home:
  state count = 0

  text "Hello, Nativ", big, bold
  text "Edit me — the preview is live.", gray
  button "Tapped {count} times":
    count += 1`;

function starterFromUrl() {
  try {
    return new URLSearchParams(window.location.search).get("source") || STARTER;
  } catch (e) {
    return STARTER;
  }
}

function copyText(text) {
  if (navigator.clipboard?.writeText) return navigator.clipboard.writeText(text);
  const el = document.createElement("textarea");
  el.value = text;
  el.setAttribute("readonly", "");
  el.style.position = "fixed";
  el.style.top = "-1000px";
  document.body.appendChild(el);
  el.select();
  const ok = document.execCommand("copy");
  document.body.removeChild(el);
  return ok ? Promise.resolve() : Promise.reject(new Error("copy failed"));
}

/**
 * Playground — recreation of the hosted /try editor: a top bar, a split
 * source-editor / output pane, and a target switcher (Preview · SwiftUI ·
 * Compose). Edit the .nativ source on the left and watch the preview update.
 */
function Playground() {
  const { Button } = window.NativDesignSystem_024c5a;
  const [source, setSource] = React.useState(starterFromUrl);
  const [tab, setTab] = React.useState("preview");
  const [shareLabel, setShareLabel] = React.useState("Share");
  const [time] = React.useState("9:41");
  const parsed = window.parseNativ(source);

  const tabs = [
    { id: "preview", label: "Preview", dot: "var(--grad)" },
    { id: "swift", label: "SwiftUI", dot: "var(--swift)" },
    { id: "kotlin", label: "Compose", dot: "var(--compose)" },
  ];

  const share = async () => {
    const url = `${window.location.origin}${window.location.pathname}?source=${encodeURIComponent(source)}`;
    try {
      if (navigator.share) await navigator.share({ title: "Try Nativ", url });
      else await copyText(url);
      setShareLabel("Copied");
    } catch (e) {
      try {
        await copyText(url);
        setShareLabel("Copied");
      } catch (copyError) {
        setShareLabel("Copy failed");
      }
    }
    setTimeout(() => setShareLabel("Share"), 1600);
  };

  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        height: "100vh",
        minHeight: 560,
        color: "var(--text)",
      }}
    >
      {/* top bar */}
      <header
        style={{
          display: "flex",
          alignItems: "center",
          gap: 18,
          padding: "0 20px",
          height: 56,
          flex: "none",
          borderBottom: "1px solid var(--line)",
          background: "rgba(8,9,12,.82)",
          backdropFilter: "blur(10px)",
        }}
      >
        <span style={{ fontFamily: "var(--mono)", fontSize: 18, fontWeight: 700, letterSpacing: "-.02em" }}>
          nativ
          <span
            style={{
              background: "var(--grad)",
              WebkitBackgroundClip: "text",
              backgroundClip: "text",
              color: "transparent",
            }}
          >
            _
          </span>
        </span>
        <span style={{ fontFamily: "var(--mono)", fontSize: 13, color: "var(--faint)" }}>
          / try
        </span>
        <span
          style={{
            fontFamily: "var(--mono)",
            fontSize: 12,
            color: "var(--muted)",
            border: "1px solid var(--line)",
            borderRadius: "var(--r-sm)",
            padding: "4px 10px",
            background: "var(--panel-deep)",
          }}
        >
          untitled.nativ
        </span>
        <div style={{ marginLeft: "auto", display: "flex", alignItems: "center", gap: 10 }}>
          <a href="/roadmap/" style={{ color: "var(--muted)", textDecoration: "none", fontFamily: "var(--body)", fontSize: 13 }}>
            Roadmap
          </a>
          <Button variant="ghost" size="sm" onClick={share}>{shareLabel}</Button>
          <span
            title="Private during initial development · public repo release coming soon. Cargo package is public: cargo install nativ."
            style={{
              display: "inline-flex",
              alignItems: "center",
              gap: 8,
              fontFamily: "var(--body)",
              fontWeight: 650,
              fontSize: 12.5,
              color: "var(--faint)",
              border: "1px solid var(--line-soft)",
              borderRadius: "var(--r-sm)",
              padding: "7px 12px",
              background: "rgba(255,255,255,.025)",
              cursor: "not-allowed",
            }}
          >
            {GH} Repo private · Cargo public
          </span>
        </div>
      </header>

      {/* body split */}
      <div style={{ display: "flex", flex: 1, minHeight: 0 }}>
        {/* editor side */}
        <section
          style={{
            flex: "1 1 52%",
            display: "flex",
            flexDirection: "column",
            minWidth: 0,
            borderRight: "1px solid var(--line)",
          }}
        >
          <div
            style={{
              display: "flex",
              alignItems: "center",
              gap: 10,
              height: 42,
              flex: "none",
              padding: "0 16px",
              borderBottom: "1px solid var(--line-soft)",
              fontFamily: "var(--mono)",
              fontSize: 12.5,
              color: "var(--muted)",
            }}
          >
            <span style={{ width: 8, height: 8, borderRadius: "50%", background: "var(--grad)" }} />
            src/screens/Home.nativ
            <span style={{ marginLeft: "auto", fontSize: 11, letterSpacing: ".05em", color: "var(--faint)", textTransform: "uppercase" }}>
              tab completes
            </span>
          </div>
          <window.SourceEditor value={source} onChange={setSource} />
        </section>

        {/* output side */}
        <section style={{ flex: "1 1 48%", display: "flex", flexDirection: "column", minWidth: 0, background: "var(--bg-soft)" }}>
          <div
            style={{
              display: "flex",
              alignItems: "center",
              gap: 6,
              height: 42,
              flex: "none",
              padding: "0 12px",
              borderBottom: "1px solid var(--line-soft)",
            }}
          >
            {tabs.map((t) => {
              const on = t.id === tab;
              const tint =
                t.id === "kotlin"
                  ? { color: "var(--compose)", borderColor: "var(--compose-line)", background: "var(--compose-fill)" }
                  : t.id === "swift"
                  ? { color: "var(--swift)", borderColor: "var(--swift-line)", background: "var(--swift-fill)" }
                  : { color: "var(--text)", borderColor: "var(--line-strong)", background: "rgba(255,255,255,.04)" };
              return (
                <button
                  key={t.id}
                  onClick={() => setTab(t.id)}
                  style={{
                    display: "inline-flex",
                    alignItems: "center",
                    gap: 7,
                    padding: "6px 13px",
                    borderRadius: "var(--r-sm)",
                    cursor: "pointer",
                    fontFamily: "var(--mono)",
                    fontSize: 12.5,
                    border: "1px solid transparent",
                    background: "transparent",
                    color: "var(--muted)",
                    ...(on ? tint : null),
                  }}
                >
                  <span style={{ width: 7, height: 7, borderRadius: "50%", background: t.dot }} />
                  {t.label}
                </button>
              );
            })}
            <span style={{ marginLeft: "auto", fontFamily: "var(--mono)", fontSize: 11, color: "var(--faint)", letterSpacing: ".05em", textTransform: "uppercase", paddingRight: 6 }}>
              {tab === "preview" ? "live" : "nativ emits"}
            </span>
          </div>

          <div className="no-scrollbar" style={{ flex: 1, minHeight: 0, overflow: "auto", display: "flex", justifyContent: "center", padding: tab === "preview" ? "30px 20px" : 0 }}>
            {tab === "preview" ? (
              <Phone time={time} title={parsed.title}>
                <window.NativePreview source={source} />
              </Phone>
            ) : (
              <pre
                className="no-scrollbar"
                style={{
                  margin: 0,
                  padding: "20px 22px",
                  width: "100%",
                  fontFamily: "var(--mono)",
                  fontSize: 13,
                  lineHeight: "1.75",
                  color: "var(--text)",
                  overflow: "auto",
                }}
                dangerouslySetInnerHTML={{
                  __html: hlGeneric(tab === "swift" ? genSwift(parsed) : genKotlin(parsed)),
                }}
              />
            )}
          </div>
        </section>
      </div>
    </div>
  );
}

/* compact phone shell for the preview tab (white iOS screen) */
function Phone({ children, time, title }) {
  return (
    <div style={{ width: 268, flex: "none" }}>
      <div
        style={{
          position: "relative",
          borderRadius: 42,
          padding: 10,
          background: "#1a1d24",
          border: "1px solid var(--line)",
          boxShadow: "var(--shadow-frame)",
        }}
      >
        <div style={{ position: "relative", height: 540, borderRadius: 33, overflow: "hidden", background: "#fff", color: "#000" }}>
          <div
            style={{
              position: "relative",
              height: 44,
              display: "flex",
              alignItems: "center",
              justifyContent: "space-between",
              padding: "0 22px",
              fontFamily: "-apple-system, system-ui, sans-serif",
              fontSize: 13,
              fontWeight: 600,
              zIndex: 5,
            }}
          >
            <span>{time}</span>
            <span style={{ fontSize: 11 }}>● ▮▮▮</span>
          </div>
          <div
            style={{
              position: "absolute",
              top: 9,
              left: "50%",
              transform: "translateX(-50%)",
              width: 78,
              height: 24,
              borderRadius: 13,
              background: "#000",
              zIndex: 10,
            }}
          />
          <div className="no-scrollbar" style={{ height: 540 - 44, overflow: "auto" }}>{children}</div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Playground });
