"use client";

import { useMemo, useState } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { ArrowLeft, ArrowRight, Check, Search } from "lucide-react";
import ImageUpload from "@/components/image-upload";

export type Empresa = { id: string; name: string };

export type PopupInicial = {
  id: string;
  title: string;
  message: string | null;
  image_url: string | null;
  image_url_mobile: string | null;
  image_side: string;
  background_color: string;
  text_color: string;
  cta_label: string | null;
  cta_url: string | null;
  cta_new_tab: boolean;
  require_ack: boolean;
  ack_label: string | null;
  frequency: string;
  audience: string;
  active: boolean;
  start_at: string | null;
  end_at: string | null;
  company_ids: string[];
};

const CORES_SUGERIDAS = ["#4F46E5", "#0F172A", "#DB2777", "#F97316", "#059669", "#0EA5E9", "#7C3AED", "#DC2626"];

/* O popup e um quadrado, e a imagem ocupa metade dele. Estes numeros sao os
   mesmos do CSS do admin (`.ktl-popup`), em dobro para telas retina — e sao
   ditos na tela porque a imagem nao e cortada. */
/** O que a caixa de ciencia diz quando o cadastro nao escreve nada. */
const CIENCIA_PADRAO = "Li e estou ciente deste aviso.";

const LADO_DO_POPUP = 520;
const LARGURA_DA_IMAGEM = LADO_DO_POPUP / 2;
const ALTURA_DA_IMAGEM = LADO_DO_POPUP;

/* No celular as duas metades viram andares, e a de cima fica deitada. Sao duas
   proporcoes diferentes, entao sao duas artes: nao existe imagem que preencha
   1:2 em pe e 4:3 deitada ao mesmo tempo sem ser cortada. */
const LARGURA_NO_CELULAR = 400;
const ALTURA_NO_CELULAR = 300;

/** `datetime-local` só aceita "AAAA-MM-DDTHH:MM", sem fuso e sem segundos. */
function paraCampoDeData(valor: string | null) {
  if (!valor) return "";
  const data = new Date(valor);
  if (Number.isNaN(data.getTime())) return "";
  const desloque = new Date(data.getTime() - data.getTimezoneOffset() * 60000);
  return desloque.toISOString().slice(0, 16);
}

function deCampoDeData(valor: string) {
  const limpo = valor.trim();
  if (!limpo) return null;
  const data = new Date(limpo);
  return Number.isNaN(data.getTime()) ? null : data.toISOString();
}

/* Preto ou branco sobre a cor escolhida, pelo brilho. É a mesma conta que o
   admin faz para o rótulo do botão: sem ela, botão claro com letra clara. */
function contrasteSobre(hex: string) {
  const limpo = String(hex || "").replace("#", "");
  const cheio = limpo.length === 3 ? limpo.split("").map((c) => c + c).join("") : limpo;
  if (cheio.length !== 6) return "#0F172A";
  const r = parseInt(cheio.slice(0, 2), 16);
  const g = parseInt(cheio.slice(2, 4), 16);
  const b = parseInt(cheio.slice(4, 6), 16);
  return (r * 299 + g * 587 + b * 114) / 1000 > 160 ? "#0F172A" : "#FFFFFF";
}

function corValida(valor: string) {
  return /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(valor);
}

const rotulo = "block text-sm font-medium text-slate-700";
const campo =
  "mt-1.5 h-11 w-full rounded-xl border border-slate-200 bg-white px-3 text-sm text-slate-900 outline-none transition focus:border-slate-400";

export default function PopupFormClient({
  mode,
  initial,
  empresas,
}: {
  mode: "create" | "edit";
  initial: PopupInicial | null;
  empresas: Empresa[];
}) {
  const router = useRouter();

  const [title, setTitle] = useState(initial?.title ?? "");
  const [message, setMessage] = useState(initial?.message ?? "");
  const [imageUrl, setImageUrl] = useState(initial?.image_url ?? "");
  const [imageUrlMobile, setImageUrlMobile] = useState(initial?.image_url_mobile ?? "");
  const [imageSide, setImageSide] = useState(initial?.image_side === "right" ? "right" : "left");
  const [backgroundColor, setBackgroundColor] = useState(initial?.background_color ?? "#4F46E5");
  const [textColor, setTextColor] = useState(initial?.text_color ?? "#FFFFFF");
  const [ctaLabel, setCtaLabel] = useState(initial?.cta_label ?? "");
  const [ctaUrl, setCtaUrl] = useState(initial?.cta_url ?? "");
  const [ctaNewTab, setCtaNewTab] = useState(initial?.cta_new_tab ?? true);
  const [requireAck, setRequireAck] = useState(initial?.require_ack ?? false);
  const [ackLabel, setAckLabel] = useState(initial?.ack_label ?? "");
  const [frequency, setFrequency] = useState(initial?.frequency ?? "once");
  const [audience, setAudience] = useState(initial?.audience ?? "all");
  const [companyIds, setCompanyIds] = useState<string[]>(initial?.company_ids ?? []);
  const [active, setActive] = useState(initial?.active ?? true);
  const [startAt, setStartAt] = useState(paraCampoDeData(initial?.start_at ?? null));
  const [endAt, setEndAt] = useState(paraCampoDeData(initial?.end_at ?? null));

  const [buscaEmpresa, setBuscaEmpresa] = useState("");
  const [salvando, setSalvando] = useState(false);
  const [erro, setErro] = useState("");

  const empresasFiltradas = useMemo(() => {
    const alvo = buscaEmpresa.trim().toLowerCase();
    if (!alvo) return empresas;
    return empresas.filter((empresa) => empresa.name.toLowerCase().includes(alvo));
  }, [empresas, buscaEmpresa]);

  const temBotao = Boolean(ctaLabel.trim() && ctaUrl.trim());

  function alternarEmpresa(id: string) {
    setCompanyIds((antes) => (antes.includes(id) ? antes.filter((item) => item !== id) : [...antes, id]));
  }

  async function salvar() {
    setErro("");
    if (!title.trim()) {
      setErro("Informe o título do popup.");
      return;
    }
    if (audience === "selected" && companyIds.length === 0) {
      setErro("Escolha pelo menos uma empresa, ou volte o público para todas.");
      return;
    }
    if (!corValida(backgroundColor) || !corValida(textColor)) {
      setErro("As cores precisam estar no formato #RRGGBB.");
      return;
    }
    if (ctaLabel.trim() && !ctaUrl.trim()) {
      setErro("O botão tem rótulo mas não tem link.");
      return;
    }

    const corpo = {
      ...(mode === "edit" && initial ? { id: initial.id } : {}),
      title: title.trim(),
      message: message.trim() || null,
      image_url: imageUrl.trim() || null,
      image_url_mobile: imageUrlMobile.trim() || null,
      image_side: imageSide,
      background_color: backgroundColor,
      text_color: textColor,
      cta_label: ctaLabel.trim() || null,
      cta_url: ctaUrl.trim() || null,
      cta_new_tab: ctaNewTab,
      require_ack: requireAck,
      ack_label: ackLabel.trim() || null,
      frequency,
      audience,
      company_ids: audience === "selected" ? companyIds : [],
      active,
      start_at: deCampoDeData(startAt),
      end_at: deCampoDeData(endAt),
    };

    setSalvando(true);
    try {
      const resposta = await fetch("/api/system-popups", {
        method: mode === "edit" ? "PATCH" : "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify(corpo),
      });
      const retorno = (await resposta.json().catch(() => null)) as { error?: string } | null;
      if (!resposta.ok) throw new Error(retorno?.error || "Não foi possível salvar o popup.");
      router.push("/popups");
      router.refresh();
    } catch (falha) {
      setErro(falha instanceof Error ? falha.message : "Não foi possível salvar o popup.");
    } finally {
      setSalvando(false);
    }
  }

  const metadeDoTexto = (
    <div
      className="flex min-w-0 flex-1 flex-col justify-center gap-3 overflow-y-auto p-6"
      style={{ background: backgroundColor, color: textColor }}
    >
      <h3 className="text-[1.3rem] font-extrabold leading-tight tracking-tight">{title || "Título do aviso"}</h3>
      {message ? <p className="whitespace-pre-line text-sm leading-snug opacity-90">{message}</p> : null}
      {/* A ordem do aviso travado: texto, atalho do boletim, ciencia e so entao
          o "Continuar". Mesma do admin, senao a previa aprova um desenho que
          nao e o que vai ao ar. */}
      {requireAck ? (
        <>
          {temBotao ? (
            <span
              className="mt-0.5 flex items-center justify-between gap-3 rounded-xl px-3.5 py-2.5 text-xs font-bold leading-snug"
              style={{ background: "rgba(255,255,255,.14)", border: "1px solid rgba(255,255,255,.28)" }}
            >
              {ctaLabel}
              <ArrowRight size={15} strokeWidth={2.5} className="flex-none" />
            </span>
          ) : null}

          <span
            className="mt-0.5 flex items-start gap-2.5 rounded-xl px-3 py-2.5 text-xs font-semibold leading-snug"
            style={{ background: "rgba(255,255,255,.14)", border: "1px solid rgba(255,255,255,.28)" }}
          >
            <span
              className="mt-px h-4 w-4 flex-none rounded"
              style={{ border: "1.5px solid currentColor" }}
            />
            {ackLabel.trim() || CIENCIA_PADRAO}
          </span>

          <span
            className="mt-0.5 block rounded-full px-5 py-2.5 text-center text-sm font-bold opacity-40"
            style={{ background: textColor, color: contrasteSobre(textColor) }}
          >
            Continuar
          </span>
        </>
      ) : temBotao ? (
        <span
          className="mt-0.5 inline-flex w-fit rounded-full px-5 py-2.5 text-sm font-bold"
          style={{ background: textColor, color: contrasteSobre(textColor) }}
        >
          {ctaLabel}
        </span>
      ) : null}
    </div>
  );

  /* `object-contain` e a cor de fundo atrás: é exatamente o que o admin faz,
     então a prévia mostra a sobra de cor antes de a imagem ir para o ar. */
  const metadeDaImagem = imageUrl ? (
    <div className="min-w-0 flex-1 overflow-hidden" style={{ background: backgroundColor }}>
      {/* eslint-disable-next-line @next/next/no-img-element */}
      <img src={imageUrl} alt="" className="h-full w-full object-contain" />
    </div>
  ) : (
    <div className="flex min-w-0 flex-1 items-center justify-center bg-slate-100 px-2 text-center text-[11px] font-medium leading-tight text-slate-400">
      {LARGURA_DA_IMAGEM} × {ALTURA_DA_IMAGEM} px
    </div>
  );

  return (
    <div className="min-h-screen bg-slate-50/50 p-6 sm:p-10 font-sans">
      <div className="mx-auto max-w-[1180px]">
        <Link href="/popups" className="inline-flex items-center gap-2 text-sm font-medium text-slate-500 hover:text-slate-900">
          <ArrowLeft size={16} />
          Voltar para popups
        </Link>
        <h1 className="mt-3 text-2xl font-semibold tracking-tight text-slate-900">
          {mode === "edit" ? "Editar popup" : "Novo popup"}
        </h1>
        <p className="mt-1 text-sm text-slate-500">
          O que você montar aqui é exatamente o que abre na tela de quem entra no sistema.
        </p>

        <div className="mt-6 grid gap-6 lg:grid-cols-[minmax(0,1fr)_minmax(0,420px)]">
          {/* ------------------------------------------------ o cadastro */}
          <div className="grid gap-5">
            <section className="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
              <h2 className="text-sm font-semibold text-slate-900">Conteúdo</h2>

              <div className="mt-4 grid gap-4">
                <label className="block">
                  <span className={rotulo}>Título</span>
                  <input value={title} onChange={(e) => setTitle(e.target.value)} className={campo} placeholder="Ex.: Novidade no PDV" />
                </label>

                <label className="block">
                  <span className={rotulo}>Texto</span>
                  <textarea
                    value={message}
                    onChange={(e) => setMessage(e.target.value)}
                    rows={4}
                    placeholder="Explique o recado em uma ou duas frases."
                    className="mt-1.5 w-full rounded-xl border border-slate-200 bg-white p-3 text-sm text-slate-900 outline-none transition focus:border-slate-400"
                  />
                </label>

                <div>
                  <span className={rotulo}>Imagem no computador</span>
                  {/* O tamanho exato fica na tela porque a imagem NÃO é
                      cortada: fora dessa medida ela encolhe para caber e sobra
                      cor em volta. */}
                  <div className="mt-1.5 rounded-xl border border-indigo-200 bg-indigo-50 px-3 py-2.5 text-xs leading-relaxed text-indigo-800">
                    <strong className="font-bold">Tamanho exato: {LARGURA_DA_IMAGEM} × {ALTURA_DA_IMAGEM} px</strong>{" "}
                    (proporção 1:2, em pé). O popup é um quadrado de {LADO_DO_POPUP} × {LADO_DO_POPUP} px e a imagem ocupa
                    a metade dele.
                    <br />
                    Sua imagem <strong className="font-bold">não é cortada</strong>: nessa medida ela preenche o lado
                    inteiro; em qualquer outra, ela cabe inteira e o que sobrar fica com a cor de fundo.
                  </div>
                  <div className="mt-2">
                    <ImageUpload
                      bucket="products"
                      folder="popups"
                      value={imageUrl}
                      onChange={setImageUrl}
                      aspect={1 / 2}
                      ratioLabel="1:2"
                      encaixe="contain"
                      hint={`Tamanho exato: ${LARGURA_DA_IMAGEM} × ${ALTURA_DA_IMAGEM} px. Nada é cortado.`}
                    />
                  </div>
                </div>

                <div>
                  <span className={rotulo}>Imagem no celular</span>
                  {/* Arte propria porque no celular a faixa e deitada. A mesma
                      arte em pe caberia inteira, mas encolhida no meio de um
                      campo de cor — foi assim que ficou antes deste campo. */}
                  <div className="mt-1.5 rounded-xl border border-indigo-200 bg-indigo-50 px-3 py-2.5 text-xs leading-relaxed text-indigo-800">
                    <strong className="font-bold">Tamanho exato: {LARGURA_NO_CELULAR} × {ALTURA_NO_CELULAR} px</strong>{" "}
                    (proporção 4:3, deitada). No celular o popup vira dois andares: a imagem em cima, ocupando a largura
                    inteira, e o texto embaixo.
                    <br />
                    <strong className="font-bold">Pode deixar em branco.</strong> Sem ela, a imagem do computador
                    aparece inteira no meio, sobre uma cópia desfocada dela mesma.
                  </div>
                  <div className="mt-2">
                    <ImageUpload
                      bucket="products"
                      folder="popups"
                      value={imageUrlMobile}
                      onChange={setImageUrlMobile}
                      aspect={4 / 3}
                      ratioLabel="4:3"
                      encaixe="contain"
                      hint={`Tamanho exato: ${LARGURA_NO_CELULAR} × ${ALTURA_NO_CELULAR} px. Nada é cortado.`}
                    />
                  </div>
                </div>

                <div>
                  <span className={rotulo}>Lado da imagem</span>
                  <div className="mt-1.5 flex gap-2">
                    {[
                      { valor: "left", texto: "Imagem à esquerda" },
                      { valor: "right", texto: "Imagem à direita" },
                    ].map((opcao) => (
                      <button
                        key={opcao.valor}
                        type="button"
                        onClick={() => setImageSide(opcao.valor)}
                        className={[
                          "h-11 flex-1 rounded-xl border text-sm font-medium transition",
                          imageSide === opcao.valor
                            ? "border-slate-900 bg-slate-900 text-white"
                            : "border-slate-200 bg-white text-slate-700 hover:bg-slate-50",
                        ].join(" ")}
                      >
                        {opcao.texto}
                      </button>
                    ))}
                  </div>
                  <p className="mt-1.5 text-xs text-slate-400">No celular a imagem sempre fica em cima.</p>
                </div>
              </div>
            </section>

            <section className="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
              <h2 className="text-sm font-semibold text-slate-900">Cores</h2>
              <div className="mt-4 grid gap-4 sm:grid-cols-2">
                {[
                  { titulo: "Fundo", valor: backgroundColor, definir: setBackgroundColor },
                  { titulo: "Texto", valor: textColor, definir: setTextColor },
                ].map((item) => (
                  <div key={item.titulo}>
                    <span className={rotulo}>{item.titulo}</span>
                    <div className="mt-1.5 flex items-center gap-2">
                      <input
                        type="color"
                        value={corValida(item.valor) ? item.valor : "#4F46E5"}
                        onChange={(e) => item.definir(e.target.value.toUpperCase())}
                        className="h-11 w-14 cursor-pointer rounded-xl border border-slate-200 bg-white p-1"
                      />
                      <input
                        value={item.valor}
                        onChange={(e) => item.definir(e.target.value.toUpperCase())}
                        className={`${campo} mt-0 flex-1 font-mono`}
                        placeholder="#4F46E5"
                      />
                    </div>
                  </div>
                ))}
              </div>
              <div className="mt-3 flex flex-wrap gap-2">
                {CORES_SUGERIDAS.map((cor) => (
                  <button
                    key={cor}
                    type="button"
                    onClick={() => setBackgroundColor(cor)}
                    title={cor}
                    className="h-8 w-8 rounded-lg border border-slate-200 transition hover:scale-110"
                    style={{ background: cor }}
                  />
                ))}
              </div>
            </section>

            <section className="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
              <h2 className="text-sm font-semibold text-slate-900">Botão</h2>
              <p className="mt-1 text-xs text-slate-500">Opcional. Sem rótulo e link, o popup fica só com o texto.</p>
              <div className="mt-4 grid gap-4 sm:grid-cols-2">
                <label className="block">
                  <span className={rotulo}>Rótulo</span>
                  <input value={ctaLabel} onChange={(e) => setCtaLabel(e.target.value)} className={campo} placeholder="Ex.: Ver novidade" />
                </label>
                <label className="block">
                  <span className={rotulo}>Link</span>
                  <input
                    value={ctaUrl}
                    onChange={(e) => setCtaUrl(e.target.value)}
                    className={campo}
                    placeholder="https://..."
                  />
                </label>
              </div>
              <label className="mt-3 flex items-center gap-2 text-sm text-slate-700">
                <input type="checkbox" checked={ctaNewTab} onChange={(e) => setCtaNewTab(e.target.checked)} className="h-4 w-4" />
                Abrir em outra aba
              </label>
            </section>

            <section className="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
              <h2 className="text-sm font-semibold text-slate-900">Ciência obrigatória</h2>
              <p className="mt-1 text-xs text-slate-500">
                Com isto ligado, o X e o clique fora param de fechar. Só sai marcando a caixa, e a marcação fica
                gravada com data, empresa e o texto exato que a pessoa leu.
              </p>

              <label className="mt-4 flex cursor-pointer items-start gap-2.5 rounded-xl border border-slate-200 bg-slate-50/60 p-3">
                <input
                  type="checkbox"
                  checked={requireAck}
                  onChange={(e) => setRequireAck(e.target.checked)}
                  className="mt-0.5 h-4 w-4"
                />
                <span className="text-sm text-slate-700">
                  <span className="block font-semibold text-slate-900">Exigir ciência para fechar</span>
                  <span className="mt-0.5 block text-xs leading-relaxed text-slate-500">
                    Use quando precisar provar depois que a pessoa foi avisada. Para recado comum, deixe desligado.
                  </span>
                </span>
              </label>

              {requireAck ? (
                <label className="mt-4 block">
                  <span className={rotulo}>Texto da caixa de ciência</span>
                  <input
                    value={ackLabel}
                    onChange={(e) => setAckLabel(e.target.value)}
                    className={campo}
                    placeholder={CIENCIA_PADRAO}
                  />
                  <span className="mt-1.5 block text-xs text-slate-400">
                    Em branco usa &ldquo;{CIENCIA_PADRAO}&rdquo;. É este texto que fica guardado como prova.
                  </span>
                </label>
              ) : null}
            </section>

            <section className="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
              <h2 className="text-sm font-semibold text-slate-900">Quando e para quem</h2>

              <div className="mt-4 grid gap-4">
                <div>
                  <span className={rotulo}>Aparece</span>
                  <div className="mt-1.5 grid gap-2 sm:grid-cols-3">
                    {[
                      { valor: "once", texto: "Uma vez por pessoa", dica: "Editar o popup faz voltar" },
                      { valor: "daily", texto: "Uma vez por dia", dica: "Volta todo dia" },
                      { valor: "always", texto: "Toda vez que abrir", dica: "Só para urgência" },
                    ].map((opcao) => (
                      <button
                        key={opcao.valor}
                        type="button"
                        onClick={() => setFrequency(opcao.valor)}
                        className={[
                          "rounded-xl border p-3 text-left transition",
                          frequency === opcao.valor
                            ? "border-slate-900 bg-slate-900 text-white"
                            : "border-slate-200 bg-white text-slate-700 hover:bg-slate-50",
                        ].join(" ")}
                      >
                        <span className="block text-sm font-semibold">{opcao.texto}</span>
                        <span className={`block text-[11px] ${frequency === opcao.valor ? "text-white/70" : "text-slate-400"}`}>
                          {opcao.dica}
                        </span>
                      </button>
                    ))}
                  </div>
                </div>

                <div className="grid gap-4 sm:grid-cols-2">
                  <label className="block">
                    <span className={rotulo}>Começa em</span>
                    <input type="datetime-local" value={startAt} onChange={(e) => setStartAt(e.target.value)} className={campo} />
                  </label>
                  <label className="block">
                    <span className={rotulo}>Termina em</span>
                    <input type="datetime-local" value={endAt} onChange={(e) => setEndAt(e.target.value)} className={campo} />
                  </label>
                </div>
                <p className="-mt-2 text-xs text-slate-400">Deixe em branco para não ter prazo.</p>

                <div>
                  <span className={rotulo}>Quem vê</span>
                  <div className="mt-1.5 flex gap-2">
                    {[
                      { valor: "all", texto: "Todas as empresas" },
                      { valor: "selected", texto: "Escolher empresas" },
                    ].map((opcao) => (
                      <button
                        key={opcao.valor}
                        type="button"
                        onClick={() => setAudience(opcao.valor)}
                        className={[
                          "h-11 flex-1 rounded-xl border text-sm font-medium transition",
                          audience === opcao.valor
                            ? "border-slate-900 bg-slate-900 text-white"
                            : "border-slate-200 bg-white text-slate-700 hover:bg-slate-50",
                        ].join(" ")}
                      >
                        {opcao.texto}
                      </button>
                    ))}
                  </div>
                </div>

                {audience === "selected" ? (
                  <div className="rounded-xl border border-slate-200 bg-slate-50/60 p-3">
                    <div className="flex items-center gap-2 rounded-lg border border-slate-200 bg-white px-3">
                      <Search size={15} className="text-slate-400" />
                      <input
                        value={buscaEmpresa}
                        onChange={(e) => setBuscaEmpresa(e.target.value)}
                        placeholder="Buscar empresa"
                        className="h-10 flex-1 border-0 bg-transparent text-sm outline-none placeholder:text-slate-400"
                      />
                      <span className="text-xs font-semibold text-slate-500">{companyIds.length} marcada(s)</span>
                    </div>
                    <div className="mt-2 max-h-64 overflow-y-auto">
                      {empresasFiltradas.map((empresa) => {
                        const marcada = companyIds.includes(empresa.id);
                        return (
                          <button
                            key={empresa.id}
                            type="button"
                            onClick={() => alternarEmpresa(empresa.id)}
                            className="flex w-full items-center gap-2 rounded-lg px-2 py-2 text-left text-sm text-slate-700 transition hover:bg-white"
                          >
                            <span
                              className={[
                                "flex h-5 w-5 shrink-0 items-center justify-center rounded-md border",
                                marcada ? "border-slate-900 bg-slate-900 text-white" : "border-slate-300 bg-white",
                              ].join(" ")}
                            >
                              {marcada ? <Check size={13} /> : null}
                            </span>
                            {empresa.name}
                          </button>
                        );
                      })}
                      {empresasFiltradas.length === 0 ? (
                        <p className="px-2 py-4 text-center text-xs text-slate-400">Nenhuma empresa encontrada.</p>
                      ) : null}
                    </div>
                  </div>
                ) : null}

                <label className="flex items-center gap-2 text-sm text-slate-700">
                  <input type="checkbox" checked={active} onChange={(e) => setActive(e.target.checked)} className="h-4 w-4" />
                  Popup ligado
                </label>
              </div>
            </section>

            {erro ? (
              <div className="rounded-xl border border-rose-200 bg-rose-50 px-4 py-3 text-sm text-rose-700">{erro}</div>
            ) : null}

            <div className="flex justify-end gap-2">
              <Link
                href="/popups"
                className="inline-flex h-11 items-center rounded-xl border border-slate-200 bg-white px-5 text-sm font-medium text-slate-700 transition hover:bg-slate-50"
              >
                Cancelar
              </Link>
              <button
                type="button"
                onClick={() => void salvar()}
                disabled={salvando}
                className="inline-flex h-11 items-center rounded-xl bg-slate-900 px-6 text-sm font-semibold text-white shadow-sm transition hover:bg-slate-800 disabled:opacity-50"
              >
                {salvando ? "Salvando…" : mode === "edit" ? "Salvar alterações" : "Criar popup"}
              </button>
            </div>
          </div>

          {/* ------------------------------------------------ a prévia */}
          <div className="lg:sticky lg:top-10 lg:self-start">
            <p className="text-sm font-semibold text-slate-900">Prévia</p>
            <p className="mt-1 text-xs text-slate-500">
              É assim que abre na tela de quem entrar: um quadrado de {LADO_DO_POPUP} × {LADO_DO_POPUP} px no meio da
              tela, sem tomar o resto.
            </p>
            <div className="mt-3 rounded-2xl bg-slate-900/90 p-5">
              {/* Quadrado, do mesmo tamanho que abre no admin. */}
              <div className="mx-auto flex aspect-square w-full max-w-[360px] overflow-hidden rounded-[18px] shadow-2xl">
                {imageSide === "right" ? (
                  <>
                    {metadeDoTexto}
                    {metadeDaImagem}
                  </>
                ) : (
                  <>
                    {metadeDaImagem}
                    {metadeDoTexto}
                  </>
                )}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}
