// Main app — form on the left, receipt on the right.

const todayISO = () => {
  const d = new Date();
  const p = (n) => String(n).padStart(2, "0");
  return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;
};

const newItem = (i = 0) => ({
  id: Math.random().toString(36).slice(2, 9),
  title: "",
  label: "",
  description: "",
  date: todayISO(),
  rateType: "hourly",
  hours: "",
  rate: "",
  total: "",
});

const SEED = {
  order: "4521",
  date: todayISO(),
  client: "Acme Co.",
  from: "Alex Petrov",
  note: "",
  currency: "USD",
  taxPct: "0",
  taxOrder: "after",
  discountType: "percent",
  discountValue: "",
  headerStyle: "glyph",
  paymentType: "link",
  paymentUrl: "https://buy.stripe.com/test_4521",
  cryptoAsset: "usdt-trc20",
  cryptoAddress: "TDMSuhGdaYrfBhQs6SiieNkq57GUG2Zp2F",
  items: [
    {
      ...newItem(),
      title: "Wireframes",
      label: "lo-fi",
      description: "Made a few screens so you can\ncheck the overall structure.",
      rateType: "hourly",
      hours: "8",
      rate: "30",
    },
    {
      ...newItem(),
      title: "API Integration",
      label: "v1",
      description: "Stripe + webhook handlers.",
      rateType: "hourly",
      hours: "5",
      rate: "60",
    },
    {
      ...newItem(),
      title: "Logo refresh",
      label: "",
      description: "",
      rateType: "fixed",
      total: "180",
    },
  ],
};

// ─────────────────────────────────────────────────────────────────

function App() {
  const [data, setData] = useState(SEED);
  const [copied, setCopied] = useState(false);
  const [downloading, setDownloading] = useState(false);
  const [downloadingPdf, setDownloadingPdf] = useState(false);

  // Tweaks
  const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
    "paperTheme": "white",
    "lang": "en"
  }/*EDITMODE-END*/;
  const [tweaks, setTweaks] = useTweaks(TWEAK_DEFAULTS);
  const t = useMemo(() => makeT(tweaks.lang || "en"), [tweaks.lang]);

  const set = (patch) => setData((d) => ({ ...d, ...patch }));
  const setItem = (id, patch) =>
    setData((d) => ({
      ...d,
      items: d.items.map((it) => (it.id === id ? { ...it, ...patch } : it)),
    }));
  const addItem = () =>
    setData((d) => ({ ...d, items: [...d.items, newItem(d.items.length)] }));
  const removeItem = (id) =>
    setData((d) => ({
      ...d,
      items: d.items.length > 1 ? d.items.filter((it) => it.id !== id) : d.items,
    }));

  const receiptData = useMemo(() => data, [data]);

  const handleCopy = async () => {
    const text = receiptAsText(receiptData, t);
    try {
      await navigator.clipboard.writeText(text);
      setCopied(true);
      setTimeout(() => setCopied(false), 1500);
    } catch (e) {
      console.error(e);
    }
  };

  // Capture the receipt as a high-res PNG dataURL using html-to-image,
  // which renders via SVG <foreignObject> — way more accurate for text
  // positioning than html2canvas (no baseline drift on pills, no clipped
  // letter-spacing tails). Waits for webfonts first.
  const captureReceiptPng = async () => {
    if (!window.htmlToImage) return null;
    const node = document.getElementById("receipt-print");
    if (!node) return null;
    if (document.fonts && document.fonts.ready) {
      try { await document.fonts.ready; } catch (e) {}
    }
    return await window.htmlToImage.toPng(node, {
      pixelRatio: 2,
      cacheBust: true,
      backgroundColor: null,
    });
  };

  const handleDownload = async () => {
    setDownloading(true);
    try {
      const dataUrl = await captureReceiptPng();
      if (!dataUrl) return;
      const link = document.createElement("a");
      link.download = `receipt-${data.order || "0000"}.png`;
      link.href = dataUrl;
      link.click();
    } finally {
      setDownloading(false);
    }
  };

  const handleDownloadPdf = () => {
    // Use the browser's native print → Save as PDF.
    // To avoid blank pages around the receipt (which happen when the app
    // chrome is merely visibility:hidden and still occupies layout), we
    // clone the receipt to body as .print-receipt-clone and display:none
    // the app via body.printing. After the print dialog closes we clean up.
    const node = document.getElementById("receipt-print");
    if (!node) return;

    setDownloadingPdf(true);
    const originalTitle = document.title;
    document.title = `receipt-${data.order || "0000"}`;

    const clone = node.cloneNode(true);
    clone.removeAttribute("id");
    clone.classList.add("print-receipt-clone");
    document.body.appendChild(clone);
    document.body.classList.add("printing");

    let cleanedUp = false;
    const cleanup = () => {
      if (cleanedUp) return;
      cleanedUp = true;
      document.body.classList.remove("printing");
      clone.remove();
      document.title = originalTitle;
      setDownloadingPdf(false);
      window.removeEventListener("afterprint", cleanup);
    };
    window.addEventListener("afterprint", cleanup);

    // Small tick so layout settles before opening the print dialog.
    setTimeout(() => {
      try {
        window.print();
      } catch (e) {
        cleanup();
      }
      // Fallback cleanup for browsers that don't fire afterprint reliably.
      setTimeout(cleanup, 1000);
    }, 30);
  };

  const subtotal = data.items.reduce((s, it) => s + lineItemTotal(it), 0);
  const discount =
    data.discountType === "percent"
      ? (subtotal * (parseFloat(data.discountValue) || 0)) / 100
      : parseFloat(data.discountValue) || 0;
  const taxBase =
    data.taxOrder === "before" ? subtotal : Math.max(0, subtotal - discount);
  const tax = (taxBase * (parseFloat(data.taxPct) || 0)) / 100;
  const total = Math.max(0, subtotal - discount) + tax;

  return (
    <div className="min-h-screen w-full bg-neutral-100 font-mono">
      <div className="grid grid-cols-1 md:grid-cols-[minmax(0,380px)_1fr] lg:grid-cols-[minmax(0,420px)_1fr]">
        {/* ───── LEFT: Form (pinned to viewport left edge) ───── */}
        <aside className="bg-white border-b md:border-b-0 md:border-r border-neutral-200 md:min-h-screen md:sticky md:top-0 md:self-start md:max-h-screen md:overflow-y-auto">
          <Header total={total} currency={data.currency} count={data.items.length} t={t} lang={tweaks.lang || "en"} onLang={(v) => setTweaks("lang", v)} />

          <div className="px-6 pb-8 space-y-1">
            <Section title={t("section_details")} defaultOpen>
              <div className="grid grid-cols-2 gap-3">
                <Field className="col-span-2" label={t("from")} htmlFor="f-from">
                  <Input
                    id="f-from"
                    value={data.from}
                    onChange={(e) => set({ from: e.target.value })}
                    placeholder={t("ph_from")}
                  />
                </Field>
                <Field label={t("order_no")} htmlFor="f-order">
                  <Input
                    id="f-order"
                    value={data.order}
                    onChange={(e) => set({ order: e.target.value })}
                    placeholder={t("ph_order")}
                  />
                </Field>
                <Field label={t("date")} htmlFor="f-date">
                  <Input
                    id="f-date"
                    type="date"
                    value={data.date}
                    onChange={(e) => set({ date: e.target.value })}
                  />
                </Field>
                <Field label={t("client")} htmlFor="f-client" optional optionalLabel={t("optional")}>
                  <Input
                    id="f-client"
                    value={data.client}
                    onChange={(e) => set({ client: e.target.value })}
                    placeholder={t("ph_client")}
                  />
                </Field>
                <Field label={t("currency")} htmlFor="f-cur">
                  <Select
                    value={data.currency}
                    onChange={(v) => set({ currency: v })}
                    options={[
                      { value: "USD", label: "$  USD" },
                      { value: "EUR", label: "€  EUR" },
                      { value: "RUB", label: "₽  RUB" },
                      { value: "GBP", label: "£  GBP" },
                    ]}
                  />
                </Field>
              </div>
            </Section>

            <Section
              title={t("section_items")}
              meta={`${t("items_n", data.items.length)} · ${fmtAmount(subtotal, data.currency)}`}
              defaultOpen
            >
              <div className="bg-neutral-100 p-3 space-y-2.5">
                {data.items.map((it, i) => (
                  <ItemCard
                    key={it.id}
                    idx={i}
                    item={it}
                    currency={data.currency}
                    canRemove={data.items.length > 1}
                    onChange={(patch) => setItem(it.id, patch)}
                    onRemove={() => removeItem(it.id)}
                    t={t}
                  />
                ))}

                <button
                  type="button"
                  onClick={addItem}
                  className="w-full h-11 border border-dashed border-neutral-400 hover:border-neutral-900 bg-white text-[11px] tracking-[0.16em] uppercase text-neutral-700 hover:text-neutral-900 transition-colors flex items-center justify-center gap-2"
                >
                  <span className="text-base leading-none">+</span> {t("add_item")}
                </button>
              </div>
            </Section>

            <Section
              title={t("section_adjust")}
              meta={
                discount > 0 || parseFloat(data.taxPct) > 0
                  ? [
                      discount > 0 ? `− ${fmtAmount(discount, data.currency)}` : null,
                      parseFloat(data.taxPct) > 0 ? `+${data.taxPct}% ${t("tax").toLowerCase()}` : null,
                    ]
                      .filter(Boolean)
                      .join(" · ")
                  : "—"
              }
              defaultOpen={false}
            >
              <div className="space-y-4">
                <div>
                  <Label>{t("discount")}</Label>
                  <div className="flex gap-2">
                    <div className="w-[120px] shrink-0">
                      <Segmented
                        value={data.discountType}
                        onChange={(v) => set({ discountType: v })}
                        options={[
                          { value: "percent", label: "%" },
                          { value: "amount", label: CURRENCY_SYMBOL[data.currency] },
                        ]}
                      />
                    </div>
                    <div className="flex-1">
                      <Input
                        inputMode="decimal"
                        value={data.discountValue}
                        onChange={(e) => set({ discountValue: e.target.value })}
                        placeholder={data.discountType === "percent" ? "0" : "0.00"}
                      />
                    </div>
                  </div>
                </div>

                <div>
                  <Label>{t("tax")}</Label>
                  <div className="flex gap-2">
                    <div className="w-[120px] shrink-0">
                      <Input
                        inputMode="decimal"
                        value={data.taxPct}
                        onChange={(e) => set({ taxPct: e.target.value })}
                        placeholder="0"
                      />
                    </div>
                    <div className="flex-1">
                      <Segmented
                        value={data.taxOrder}
                        onChange={(v) => set({ taxOrder: v })}
                        options={[
                          { value: "before", label: t("tax_before") },
                          { value: "after", label: t("tax_after") },
                        ]}
                      />
                    </div>
                  </div>
                  <div className="mt-1.5 text-[10px] tracking-[0.04em] text-neutral-500">
                    {data.taxOrder === "before"
                      ? t("tax_help_before")
                      : t("tax_help_after")}
                  </div>
                </div>
              </div>
            </Section>

            <Section title={t("section_note")} meta={data.note ? t("meta_set") : t("meta_empty")} defaultOpen={false}>
              <Textarea
                rows={3}
                value={data.note}
                onChange={(e) => set({ note: e.target.value })}
                placeholder={t("note_placeholder")}
              />
            </Section>

            <Section
              title={t("section_payment")}
              meta={
                data.paymentType === "none"
                  ? t("meta_off")
                  : data.paymentType === "link"
                  ? t("meta_pay_link")
                  : `${(cryptoMetaOf(data.cryptoAsset) || {}).ticker || "Crypto"}`
              }
              defaultOpen={data.paymentType !== "none"}
            >
              <PaymentFields data={data} set={set} t={t} />
            </Section>
          </div>
        </aside>

        {/* ───── RIGHT: Receipt preview ───── */}
        <main className="relative px-4 sm:px-6 lg:px-12 py-8 sm:py-10 lg:py-14">
          {/* Toolbar */}
          <div className="flex items-center justify-between gap-3 mb-8 max-w-[420px] mx-auto flex-wrap">
            <div className="text-[10px] tracking-[0.18em] uppercase text-neutral-500">
              {t("preview")}
            </div>
            <div className="flex gap-2 flex-wrap justify-end">
              <Button variant="outline" onClick={handleCopy}>
                {copied ? t("copied") : t("copy_as_text")}
              </Button>
              <Button variant="outline" onClick={handleDownloadPdf} disabled={downloadingPdf}>
                {downloadingPdf ? "…" : t("download_pdf")}
              </Button>
              <Button onClick={handleDownload} disabled={downloading}>
                {downloading ? "…" : t("download_png")}
              </Button>
            </div>
          </div>

          {/* The receipt */}
          <Receipt data={receiptData} theme={tweaks.paperTheme} t={t} />

          {/* Disclaimer block — lives in the page, not on the receipt */}
          <div className="mt-10 max-w-[420px] mx-auto">
            <div className="border-t border-neutral-300 pt-5 text-[10px] leading-[1.7] text-neutral-500 tracking-[0.04em] uppercase text-center space-y-2">
              <p>{t("disclaim_bottom_1")}</p>
              <p>{t("disclaim_bottom_2")}</p>
            </div>

            <div className="mt-6 flex items-center justify-center gap-3 text-[10px] tracking-[0.22em] uppercase">
              <span className="text-neutral-300">·</span>
              <a
                href="https://turchanovich.framer.ai/"
                target="_blank"
                rel="noopener noreferrer"
                className="text-neutral-700 hover:text-neutral-900 underline underline-offset-4 decoration-neutral-300 hover:decoration-neutral-900 transition-colors font-semibold"
              >
                {t("made_by")}
              </a>
              <span className="text-neutral-300">·</span>
            </div>

            {/* Density hint at bottom */}
            <div className="mt-4 text-center text-[10px] tracking-[0.2em] uppercase text-neutral-400">
              {t("print_invoice")} · {data.order || "0000"}
            </div>
          </div>
        </main>
      </div>

      {/* Tweaks panel */}
      <TweaksPanel>
        <TweakSection title="Receipt">
          <TweakRadio
            label="Paper"
            value={tweaks.paperTheme}
            onChange={(v) => setTweaks("paperTheme", v)}
            options={[
              { value: "white", label: "White" },
              { value: "cream", label: "Cream" },
            ]}
          />
        </TweakSection>
      </TweaksPanel>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────

function Header({ total, currency, count, t = (k) => k, lang = "en", onLang }) {
  return (
    <div className="px-6 pt-6 pb-4 border-b border-neutral-200 space-y-3">
      <div className="flex items-baseline justify-between">
        <div className="flex items-baseline gap-2">
          <div className="text-[18px] font-semibold tracking-[0.04em]">
            receipt<span className="text-neutral-400">.gen</span>
          </div>
          <div className="text-[10px] tracking-[0.18em] uppercase text-neutral-400">
            v0.2
          </div>
        </div>
        <div className="text-right">
          <div className="text-[9px] tracking-[0.2em] uppercase text-neutral-500">
            {t("total")}
          </div>
          <div className="text-[15px] font-semibold tabular-nums leading-tight">
            {fmtAmount(total, currency)}
          </div>
        </div>
      </div>

      {/* Language switcher */}
      <div className="flex items-center gap-1 -mx-1">
        {(window.LANGS || []).map((l) => {
          const active = l.code === lang;
          return (
            <button
              key={l.code}
              type="button"
              onClick={() => onLang && onLang(l.code)}
              className={cx(
                "px-2 py-1 text-[10px] tracking-[0.18em] uppercase font-semibold transition-colors",
                active
                  ? "bg-neutral-900 text-white"
                  : "bg-transparent text-neutral-400 hover:text-neutral-900"
              )}
            >
              {l.label}
            </button>
          );
        })}
      </div>
    </div>
  );
}

function Section({ title, meta, defaultOpen = true, children }) {
  const [open, setOpen] = useState(defaultOpen);
  return (
    <div className="border-b border-neutral-200 last:border-b-0">
      <div
        role="button"
        tabIndex={0}
        onClick={() => setOpen((o) => !o)}
        onKeyDown={(e) => {
          if (e.key === "Enter" || e.key === " ") {
            e.preventDefault();
            setOpen((o) => !o);
          }
        }}
        className="w-full flex items-center justify-between gap-3 py-4 cursor-pointer select-none group"
      >
        <div className="flex items-center gap-2 min-w-0">
          <span className="text-[11px] tracking-[0.22em] uppercase font-semibold text-neutral-900">
            {title}
          </span>
        </div>
        <div className="flex items-center gap-3">
          {meta && (
            <span className="text-[10px] tracking-[0.06em] tabular-nums text-neutral-500 group-hover:text-neutral-700 transition-colors">
              {meta}
            </span>
          )}
          <Chevron open={open} />
        </div>
      </div>
      {open && <div className="pb-5">{children}</div>}
    </div>
  );
}

function cryptoMetaOf(value) {
  return (window.CRYPTO_ASSETS || []).find((a) => a.value === value);
}

function SectionTitle({ children, className }) {
  return (
    <div
      className={cx(
        "flex items-center gap-3 mb-4 text-[10px] tracking-[0.2em] uppercase text-neutral-900",
        className
      )}
    >
      <span className="font-semibold">{children}</span>
      <div className="flex-1 border-t border-dashed border-neutral-300" />
    </div>
  );
}

function Field({ label, htmlFor, optional, optionalLabel, children, className }) {
  return (
    <div className={className}>
      <Label htmlFor={htmlFor} optional={optional} optionalLabel={optionalLabel}>
        {label}
      </Label>
      {children}
    </div>
  );
}

function ItemCard({ idx, item, currency, canRemove, onChange, onRemove, t = (k) => k }) {
  const total = lineItemTotal(item);
  const num = String(idx + 1).padStart(2, "0");
  // Items with a title default to collapsed; the active/empty one opens.
  const [open, setOpen] = useState(!item.title);

  return (
    <div className="border border-neutral-200 bg-white">
      {/* card header — click to toggle */}
      <div
        role="button"
        tabIndex={0}
        onClick={() => setOpen((o) => !o)}
        onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); setOpen((o) => !o); } }}
        className="w-full flex items-center justify-between gap-2 px-3 h-10 border-b border-neutral-200 text-left hover:bg-neutral-50 transition-colors cursor-pointer"
        style={{ borderBottomColor: open ? "#e5e5e5" : "transparent" }}
      >
        <div className="flex items-center gap-2 min-w-0 flex-1">
          <span className="text-[10px] tracking-[0.2em] uppercase text-neutral-400 shrink-0">
            {num}
          </span>
          <span className="text-[12px] uppercase tracking-[0.04em] font-medium text-neutral-900 truncate">
            {item.title || <span className="text-neutral-400 italic normal-case tracking-normal">{t("item_untitled")}</span>}
          </span>
          {item.label && (
            <span className="px-1.5 py-[1px] bg-neutral-900 text-white text-[9px] tracking-[0.1em] uppercase leading-none shrink-0">
              {item.label}
            </span>
          )}
        </div>
        <div className="flex items-center gap-3 shrink-0">
          <div className="text-[11px] tabular-nums font-medium">
            {fmtAmount(total, currency)}
          </div>
          {canRemove && (
            <IconButton
              onClick={(e) => { e.stopPropagation(); onRemove(); }}
              title={t("item_remove")}
            >
              <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                <path d="M3 6h18M8 6V4a2 2 0 012-2h4a2 2 0 012 2v2M6 6l1 14a2 2 0 002 2h6a2 2 0 002-2l1-14" />
              </svg>
            </IconButton>
          )}
          <Chevron open={open} />
        </div>
      </div>

      {open && (
      <div className="p-3 grid grid-cols-2 gap-3">
        <Field className="col-span-2" label={t("item_title")} htmlFor={`title-${item.id}`}>
          <Input
            id={`title-${item.id}`}
            value={item.title}
            onChange={(e) => onChange({ title: e.target.value })}
            placeholder={t("ph_title")}
            className="uppercase"
          />
        </Field>

        <Field label={t("item_label")} htmlFor={`label-${item.id}`} optional optionalLabel={t("optional")}>
          <Input
            id={`label-${item.id}`}
            value={item.label}
            onChange={(e) => onChange({ label: e.target.value })}
            placeholder={t("ph_label")}
          />
        </Field>
        <Field label={t("date")} htmlFor={`date-${item.id}`}>
          <Input
            id={`date-${item.id}`}
            type="date"
            value={item.date}
            onChange={(e) => onChange({ date: e.target.value })}
          />
        </Field>

        <Field className="col-span-2" label={t("item_description")} htmlFor={`desc-${item.id}`} optional optionalLabel={t("optional")}>
          <Textarea
            id={`desc-${item.id}`}
            rows={2}
            value={item.description}
            onChange={(e) => onChange({ description: e.target.value })}
            placeholder={t("ph_description")}
          />
        </Field>

        <div className="col-span-2">
          <Label>{t("item_rate_type")}</Label>
          <Segmented
            value={item.rateType}
            onChange={(v) => onChange({ rateType: v })}
            options={[
              { value: "fixed", label: t("item_fixed") },
              { value: "hourly", label: t("item_hourly") },
            ]}
          />
        </div>

        {item.rateType === "hourly" ? (
          <>
            <Field label={t("item_hours")} htmlFor={`hrs-${item.id}`}>
              <Input
                id={`hrs-${item.id}`}
                inputMode="decimal"
                value={item.hours}
                onChange={(e) => onChange({ hours: e.target.value })}
                placeholder={t("ph_hours")}
              />
            </Field>
            <Field label={t("item_rate_per_h", CURRENCY_SYMBOL[currency])} htmlFor={`rate-${item.id}`}>
              <Input
                id={`rate-${item.id}`}
                inputMode="decimal"
                value={item.rate}
                onChange={(e) => onChange({ rate: e.target.value })}
                placeholder={t("ph_rate")}
              />
            </Field>
          </>
        ) : (
          <Field className="col-span-2" label={t("item_total", CURRENCY_SYMBOL[currency])} htmlFor={`tot-${item.id}`}>
            <Input
              id={`tot-${item.id}`}
              inputMode="decimal"
              value={item.total}
              onChange={(e) => onChange({ total: e.target.value })}
              placeholder={t("ph_total")}
            />
          </Field>
        )}

        <div className="col-span-2 pt-1 flex justify-end">
          <button
            type="button"
            onClick={() => setOpen(false)}
            className="text-[10px] tracking-[0.18em] uppercase text-neutral-500 hover:text-neutral-900 transition-colors"
          >
            {t("item_done_collapse")}
          </button>
        </div>
      </div>
      )}
    </div>
  );
}

function Chevron({ open }) {
  return (
    <svg
      width="10"
      height="10"
      viewBox="0 0 10 10"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.4"
      className="text-neutral-500"
      style={{ transform: open ? "rotate(180deg)" : "rotate(0deg)", transition: "transform 150ms" }}
    >
      <path d="M2 4l3 3 3-3" />
    </svg>
  );
}

function PaymentFields({ data, set, t = (k) => k }) {
  const opts = [
    { value: "none", label: t("payment_none") },
    { value: "link", label: t("payment_link") },
    { value: "crypto", label: t("payment_crypto") },
  ];
  return (
    <div className="space-y-3">
      <Segmented
        value={data.paymentType}
        onChange={(v) => set({ paymentType: v })}
        options={opts}
      />

      {data.paymentType === "link" && (
        <Field label={t("payment_url")} htmlFor="f-payurl">
          <Input
            id="f-payurl"
            type="url"
            value={data.paymentUrl}
            onChange={(e) => set({ paymentUrl: e.target.value })}
            placeholder="https://buy.stripe.com/..."
          />
          <Disclaimer>{t("disclaim_link")}</Disclaimer>
        </Field>
      )}

      {data.paymentType === "crypto" && (
        <div className="grid grid-cols-2 gap-3">
          <Field label={t("payment_asset")} htmlFor="f-asset" className="col-span-2">
            <Select
              value={data.cryptoAsset}
              onChange={(v) => set({ cryptoAsset: v })}
              options={CRYPTO_ASSETS.map((a) => ({
                value: a.value,
                label: `${a.ticker}  ·  ${a.network}`,
              }))}
            />
          </Field>
          <Field className="col-span-2" label={t("payment_address")} htmlFor="f-addr">
            <CryptoAddressField
              asset={data.cryptoAsset}
              value={data.cryptoAddress}
              onChange={(v) => set({ cryptoAddress: v })}
              t={t}
            />
            <Disclaimer>{t("disclaim_addr")}</Disclaimer>
          </Field>
        </div>
      )}
    </div>
  );
}

function Disclaimer({ children }) {
  return (
    <div className="mt-2 flex items-start gap-2 px-2.5 py-2 bg-amber-50 border-l-2 border-amber-500 text-[10px] leading-[1.5] text-amber-900 tracking-[0.02em] uppercase">
      <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" className="shrink-0 mt-[1px]">
        <path d="M12 9v4M12 17h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z" />
      </svg>
      <span>{children}</span>
    </div>
  );
}

function CryptoAddressField({ asset, value, onChange, t = (k) => k }) {
  const trimmed = (value || "").trim();
  const result = validateCryptoAddress(asset, trimmed);
  const meta = (window.CRYPTO_ASSETS || []).find((a) => a.value === asset);

  const borderColor =
    result.ok === true ? "#111" : result.ok === false ? "#b91c1c" : "#d4d4d4";

  const msg =
    result.ok === true
      ? t("addr_valid")
      : result.ok === false
      ? t("addr_invalid")
      : trimmed
      ? ""
      : t("addr_enter");

  return (
    <div>
      <textarea
        id="f-addr"
        rows={2}
        value={value}
        onChange={(e) => onChange(e.target.value)}
        placeholder={asset && asset.startsWith("btc") ? "bc1… / 1… / 3…" : asset === "usdt-trc20" ? "T…" : asset === "usdc-sol" ? "Solana address" : "0x… (40 hex chars)"}
        className="w-full px-3 py-2 bg-white text-[13px] text-neutral-900 placeholder:text-neutral-400 focus:outline-none transition-colors font-mono resize-none break-all"
        style={{ border: `1px solid ${borderColor}` }}
      />
      <div className="mt-1.5 flex items-center justify-between gap-2 text-[10px] tracking-[0.12em] uppercase tabular-nums">
        <span className={cx(
          result.ok === true && "text-emerald-700",
          result.ok === false && "text-red-700",
          result.ok === null && "text-neutral-400",
        )}>
          {result.ok === true && "✓ "}
          {result.ok === false && "× "}
          {msg}
        </span>
        <span className="text-neutral-400">
          {meta && meta.network}
        </span>
      </div>
    </div>
  );
}

// Mount
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
