"use client";

import { createContext, useContext, useEffect, useRef, useState, useSyncExternalStore } from "react";
import { ArrowLeftRight, ChevronDown, Pipette, Plus, X } from "lucide-react";
import { CampoDecimal } from "@/components/ui/campo-decimal";
import { corValida, cssDaPintura, sombraDura, sombraSuave, type Borda, type ParadaDoDegrade, type Pintura, type Sombra } from "@/lib/banner-editor/documento";

/*
  Os campos do editor de banners, num lugar só: cor (com a paleta da loja,
  as cores já usadas no banner e uma paleta viva), pintura (cor, degradê,
  radial), sombra, borda, réguas, números e grupos que abrem e fecham.
  Número digitado vai por CampoDecimal (nunca type="number").
*/

/* As cores que o seletor oferece: as da loja e as já usadas no banner chegam pelo editor. */
export const ContextoDasCores = createContext<{ daLoja: string[]; usadas: string[] }>({ daLoja: [], usadas: [] });

export const PALETA_VIVA = [
  "#FFFFFF", "#F4F4F5", "#A1A1AA", "#141414",
  "#FFD400", "#FFB020", "#FF7A00", "#FF3D00",
  "#E11D48", "#DB2777", "#C026D3", "#7C3AED",
  "#4F46E5", "#2563EB", "#0EA5E9", "#06B6D4",
  "#10B981", "#00A650", "#84CC16", "#7C2D12",
];

/* ---------------------------------------------- cores recentes e conta-gotas */

const CHAVE_DAS_RECENTES = "ktalogu:artes:cores-recentes";
const EVENTO_DAS_RECENTES = "ktalogu:cores-recentes";

function lerRecentes(): string[] {
  try {
    const lista = JSON.parse(window.localStorage.getItem(CHAVE_DAS_RECENTES) || "[]");
    return Array.isArray(lista) ? lista.map((c) => corValida(c, "")).filter(Boolean).slice(0, 12) : [];
  } catch {
    return [];
  }
}

/** Guarda a cor escolhida no topo das recentes (lembradas neste navegador). */
export function lembrarCor(cor: string) {
  const valida = corValida(cor, "");
  if (!valida) return;
  const lista = [valida, ...lerRecentes().filter((c) => c !== valida)].slice(0, 12);
  try {
    window.localStorage.setItem(CHAVE_DAS_RECENTES, JSON.stringify(lista));
  } catch {
    /* sem armazenamento, só não lembra */
  }
  window.dispatchEvent(new Event(EVENTO_DAS_RECENTES));
}

/** As cores usadas por último (atualiza quando outra parte do editor escolhe uma). */
export function useCoresRecentes() {
  const [lista, setLista] = useState<string[]>([]);
  useEffect(() => {
    const ler = () => setLista(lerRecentes());
    ler();
    window.addEventListener(EVENTO_DAS_RECENTES, ler);
    return () => window.removeEventListener(EVENTO_DAS_RECENTES, ler);
  }, []);
  return lista;
}

type ContaGotas = { open: () => Promise<{ sRGBHex: string }> };

/** Conta-gotas: pega a cor de qualquer ponto da tela (navegadores que têm, como Chrome e Edge). */
export function BotaoContaGotas({ aoPegar, grande = false }: { aoPegar: (cor: string) => void; grande?: boolean }) {
  /* O navegador tem conta-gotas? (no servidor, não). */
  const tem = useSyncExternalStore(
    () => () => undefined,
    () => "EyeDropper" in window,
    () => false,
  );
  if (!tem) return null;
  return (
    <button
      type="button"
      title="Conta-gotas: pegar uma cor da arte"
      onClick={async () => {
        try {
          const Construtor = (window as unknown as { EyeDropper: new () => ContaGotas }).EyeDropper;
          const { sRGBHex } = await new Construtor().open();
          const cor = corValida(sRGBHex, "");
          if (cor) {
            lembrarCor(cor);
            aoPegar(cor);
          }
        } catch {
          /* desistiu (Esc) */
        }
      }}
      className={`flex shrink-0 items-center justify-center rounded-lg border border-[var(--ks-color-border)] bg-white text-[#4B4760] transition hover:border-[#A78BFA] hover:text-[#6D28D9] ${grande ? "h-9 w-9 rounded-[10px]" : "h-9 w-9"}`}
    >
      <Pipette size={16} />
    </button>
  );
}

export function Rotulo({ children }: { children: React.ReactNode }) {
  return <span className="mb-1.5 block text-[10.5px] font-bold uppercase tracking-[0.12em] text-[var(--ks-color-text-soft)]">{children}</span>;
}

/** Um grupo de ajustes que abre e fecha (o título sempre à vista). */
export function Grupo({ titulo, aberto: abertoDeInicio = true, children, acao }: { titulo: string; aberto?: boolean; children: React.ReactNode; acao?: React.ReactNode }) {
  const [aberto, setAberto] = useState(abertoDeInicio);
  return (
    <section className="border-t border-[var(--ks-color-border)] first:border-t-0">
      <div className="flex items-center gap-2 px-4 py-3">
        <button type="button" onClick={() => setAberto((v) => !v)} className="flex flex-1 items-center gap-1.5 text-left text-[12.5px] font-bold text-[var(--ks-color-text-primary)]">
          <ChevronDown size={14} className={`text-[var(--ks-color-text-soft)] transition-transform ${aberto ? "" : "-rotate-90"}`} />
          {titulo}
        </button>
        {acao}
      </div>
      {aberto ? <div className="space-y-3 px-4 pb-4">{children}</div> : null}
    </section>
  );
}

export function Regua({
  rotulo,
  valor,
  min,
  max,
  passo = 1,
  aoMudar,
  formato = (v: number) => String(Math.round(v)),
}: {
  rotulo: string;
  valor: number;
  min: number;
  max: number;
  passo?: number;
  aoMudar: (v: number) => void;
  formato?: (v: number) => string;
}) {
  return (
    <label className="block">
      <span className="mb-1 flex items-center justify-between text-[11.5px] font-semibold text-[var(--ks-color-text-primary)]">
        {rotulo}
        <span className="tabular-nums text-[var(--ks-color-text-soft)]">{formato(valor)}</span>
      </span>
      <input type="range" min={min} max={max} step={passo} value={valor} onChange={(e) => aoMudar(Number(e.target.value))} className="h-1.5 w-full cursor-pointer accent-[#7C3AED]" />
    </label>
  );
}

export function Opcoes<T extends string>({ valor, opcoes, aoMudar }: { valor: T; opcoes: Array<{ valor: T; rotulo: React.ReactNode; titulo?: string }>; aoMudar: (v: T) => void }) {
  return (
    <div className="flex gap-1 rounded-xl bg-[var(--ks-color-bg-inset)] p-1">
      {opcoes.map((o) => (
        <button
          key={o.valor}
          type="button"
          title={o.titulo}
          onClick={() => aoMudar(o.valor)}
          className={`flex min-w-0 flex-1 items-center justify-center gap-1 rounded-lg px-1.5 py-1.5 text-[11.5px] font-semibold transition ${valor === o.valor ? "bg-white text-[#5B21B6] shadow-sm" : "text-[var(--ks-color-text-soft)] hover:text-[var(--ks-color-text-primary)]"}`}
        >
          {o.rotulo}
        </button>
      ))}
    </div>
  );
}

export function Chave({ rotulo, ligado, aoMudar }: { rotulo: string; ligado: boolean; aoMudar: (v: boolean) => void }) {
  return (
    <button
      type="button"
      onClick={() => aoMudar(!ligado)}
      aria-pressed={ligado}
      className={`flex items-center justify-between gap-3 py-0.5 text-left text-[12px] font-semibold text-[var(--ks-color-text-primary)] ${rotulo ? "w-full" : "shrink-0"}`}
    >
      {rotulo}
      <span className={`relative h-5 w-9 shrink-0 rounded-full transition ${ligado ? "bg-[#7C3AED]" : "bg-[#D9D6E4]"}`}>
        <span className={`absolute top-0.5 h-4 w-4 rounded-full bg-white shadow transition-all ${ligado ? "left-[18px]" : "left-0.5"}`} />
      </span>
    </button>
  );
}

/** Número digitado (X, Y, largura...), com o rótulo dentro. */
export function Numero({ rotulo, valor, aoMudar, sufixo, negativo = false }: { rotulo: string; valor: number; aoMudar: (v: number) => void; sufixo?: string; negativo?: boolean }) {
  return (
    <label className="flex h-9 items-center gap-1.5 rounded-lg border border-[var(--ks-color-border)] bg-white px-2 focus-within:border-[#A78BFA]">
      <span className="text-[10.5px] font-bold text-[var(--ks-color-text-soft)]">{rotulo}</span>
      <CampoDecimal valor={Math.round(valor)} aoMudar={aoMudar} casas={0} permiteNegativo={negativo} className="w-full min-w-0 bg-transparent text-right text-[12.5px] font-semibold tabular-nums outline-none" />
      {sufixo ? <span className="text-[10.5px] text-[var(--ks-color-text-soft)]">{sufixo}</span> : null}
    </label>
  );
}

/* ------------------------------------------------------------------ cor */

function Amostra({ cor, ativa, aoClicar, titulo }: { cor: string; ativa?: boolean; aoClicar: () => void; titulo?: string }) {
  return (
    <button
      type="button"
      title={titulo || cor}
      onClick={aoClicar}
      className={`h-7 w-7 rounded-lg border transition hover:scale-110 ${ativa ? "ring-2 ring-[#7C3AED] ring-offset-1" : ""}`}
      style={{ background: cor, borderColor: "rgba(0,0,0,.1)" }}
    />
  );
}

/** O botão com a amostra da cor; abre a paleta (loja, usadas, viva) e o seletor livre. */
export function Cor({ valor, aoMudar, rotulo, compacta = false }: { valor: string; aoMudar: (cor: string) => void; rotulo?: string; compacta?: boolean }) {
  const [aberta, setAberta] = useState(false);
  const [rascunho, setRascunho] = useState(valor);
  const caixa = useRef<HTMLDivElement | null>(null);
  const { daLoja, usadas } = useContext(ContextoDasCores);
  const recentes = useCoresRecentes();

  useEffect(() => {
    if (!aberta) return;
    const fora = (e: MouseEvent) => {
      if (!caixa.current?.contains(e.target as Node)) setAberta(false);
    };
    document.addEventListener("mousedown", fora);
    return () => document.removeEventListener("mousedown", fora);
  }, [aberta]);

  const escolher = (cor: string) => {
    aoMudar(cor);
    setRascunho(cor);
    lembrarCor(cor);
  };

  return (
    <div ref={caixa} className="relative">
      <button
        type="button"
        onClick={() => {
          setRascunho(valor);
          setAberta((v) => !v);
        }}
        title={rotulo}
        className={compacta ? "flex h-8 w-8 items-center justify-center rounded-lg border border-[var(--ks-color-border)] bg-white hover:border-[#A78BFA]" : "flex h-9 w-full items-center gap-2 rounded-lg border border-[var(--ks-color-border)] bg-white px-2 text-left hover:border-[#A78BFA]"}
      >
        <span className="h-5 w-5 shrink-0 rounded-md border" style={{ background: valor, borderColor: "rgba(0,0,0,.12)" }} />
        {compacta ? null : (
          <span className="min-w-0 flex-1">
            {rotulo ? <span className="block truncate text-[11.5px] font-semibold text-[var(--ks-color-text-primary)]">{rotulo}</span> : null}
            <span className="block text-[10.5px] uppercase tabular-nums text-[var(--ks-color-text-soft)]">{valor}</span>
          </span>
        )}
      </button>
      {aberta ? (
        <div className="absolute left-0 top-[calc(100%+6px)] z-50 w-[248px] rounded-2xl border border-[var(--ks-color-border)] bg-white p-3 shadow-[0_18px_40px_-12px_rgba(20,11,43,0.35)]">
          {recentes.length ? (
            <>
              <Rotulo>Recentes</Rotulo>
              <div className="mb-3 flex flex-wrap gap-1.5">
                {recentes.slice(0, 8).map((c) => (
                  <Amostra key={`r${c}`} cor={c} ativa={c === valor} aoClicar={() => escolher(c)} />
                ))}
              </div>
            </>
          ) : null}
          {daLoja.length ? (
            <>
              <Rotulo>Da loja</Rotulo>
              <div className="mb-3 flex flex-wrap gap-1.5">
                {daLoja.map((c) => (
                  <Amostra key={`l${c}`} cor={c} ativa={c === valor} aoClicar={() => escolher(c)} />
                ))}
              </div>
            </>
          ) : null}
          {usadas.length ? (
            <>
              <Rotulo>No banner</Rotulo>
              <div className="mb-3 flex flex-wrap gap-1.5">
                {usadas.slice(0, 14).map((c) => (
                  <Amostra key={`u${c}`} cor={c} ativa={c === valor} aoClicar={() => escolher(c)} />
                ))}
              </div>
            </>
          ) : null}
          <Rotulo>Cores</Rotulo>
          <div className="mb-3 grid grid-cols-8 gap-1.5">
            {PALETA_VIVA.map((c) => (
              <Amostra key={`p${c}`} cor={c} ativa={c === valor} aoClicar={() => escolher(c)} />
            ))}
          </div>
          <div className="flex items-center gap-2">
            <label className="relative h-9 w-9 shrink-0 cursor-pointer overflow-hidden rounded-lg border border-[var(--ks-color-border)]" title="Escolher qualquer cor" style={{ background: "conic-gradient(red, yellow, lime, cyan, blue, magenta, red)" }}>
              <input type="color" value={corValida(valor, "#000000")} onChange={(e) => escolher(e.target.value.toUpperCase())} className="absolute inset-0 h-full w-full cursor-pointer opacity-0" />
            </label>
            <BotaoContaGotas aoPegar={escolher} />
            <input
              value={rascunho}
              onChange={(e) => {
                setRascunho(e.target.value);
                const cor = corValida(e.target.value, "");
                if (cor) aoMudar(cor);
              }}
              maxLength={7}
              className="ks-field h-9 min-w-0 flex-1 font-mono text-[12.5px] uppercase"
              placeholder="#FFFFFF"
            />
          </div>
        </div>
      ) : null}
    </div>
  );
}

/* -------------------------------------------------------------- pintura */

/** Cor única, degradê (com direção) ou radial, para qualquer coisa. */
/** `permiteSem`: oferece "Sem cor" (forma só com borda, letra só com contorno). */
export function CampoDePintura({ valor, aoMudar, rotulo = "Cor", permiteSem = false }: { valor: Pintura; aoMudar: (p: Pintura) => void; rotulo?: string; permiteSem?: boolean }) {
  return (
    <div className="space-y-2.5">
      <Opcoes
        valor={valor.tipo}
        opcoes={[
          { valor: "solida", rotulo: "Cor" },
          { valor: "linear", rotulo: "Degradê" },
          { valor: "radial", rotulo: "Radial" },
          ...(permiteSem ? [{ valor: "nenhuma" as const, rotulo: "Sem", titulo: "Sem preenchimento" }] : []),
        ]}
        aoMudar={(tipo) => aoMudar({ ...valor, tipo, cor2: tipo !== "solida" && valor.cor2 === valor.cor ? "#FFFFFF" : valor.cor2 })}
      />
      {valor.tipo === "nenhuma" ? (
        <p className="text-[11.5px] leading-snug text-[var(--ks-color-text-soft)]">Sem preenchimento: fica só a borda (ou o contorno da letra).</p>
      ) : valor.tipo === "solida" ? (
        <Cor rotulo={rotulo} valor={valor.cor} aoMudar={(cor) => aoMudar({ ...valor, cor, cor2: cor })} />
      ) : (
        <>
          {/* A barra com todas as cores (as do meio também), da primeira à última. */}
          <div className="h-6 rounded-lg border border-[var(--ks-color-border)]" data-barra-do-degrade style={{ background: cssDaPintura({ ...valor, tipo: "linear", angulo: 90, pontos: undefined }) }} />
          <div className="flex items-center gap-1.5">
            <div className="min-w-0 flex-1">
              <Cor rotulo={valor.tipo === "radial" ? "Centro" : "Início"} valor={valor.cor} aoMudar={(cor) => aoMudar({ ...valor, cor })} />
            </div>
            <button type="button" title="Inverter as cores" onClick={() => aoMudar({ ...valor, cor: valor.cor2, cor2: valor.cor })} className="flex h-9 w-8 shrink-0 items-center justify-center rounded-lg text-[var(--ks-color-text-soft)] hover:bg-[var(--ks-color-bg-inset)] hover:text-[#5B21B6]">
              <ArrowLeftRight size={14} />
            </button>
            <div className="min-w-0 flex-1">
              <Cor rotulo={valor.tipo === "radial" ? "Borda" : "Fim"} valor={valor.cor2} aoMudar={(cor2) => aoMudar({ ...valor, cor2 })} />
            </div>
          </div>
          <CoresDoMeio valor={valor} aoMudar={aoMudar} />
          {valor.tipo === "linear" ? <Regua rotulo="Direção" valor={((valor.angulo % 360) + 360) % 360} min={0} max={360} aoMudar={(angulo) => aoMudar({ ...valor, angulo, pontos: undefined })} formato={(v) => `${Math.round(v)}°`} /> : null}
          {valor.tipo === "radial" ? <CentroDoRadial valor={valor} aoMudar={aoMudar} /> : null}
        </>
      )}
      {/* Transparência da tinta (a peça continua inteira; só a cor deixa ver o que está atrás). */}
      {valor.tipo === "solida" ? (
        <Regua rotulo="Cobertura da cor" valor={Math.round((valor.alfa ?? 1) * 100)} min={0} max={100} aoMudar={(v) => aoMudar({ ...valor, alfa: v / 100 })} formato={(v) => `${Math.round(v)}%`} />
      ) : valor.tipo !== "nenhuma" ? (
        <div className="grid grid-cols-2 gap-2">
          <Regua rotulo={valor.tipo === "radial" ? "Cobre no centro" : "Cobre no início"} valor={Math.round((valor.alfa ?? 1) * 100)} min={0} max={100} aoMudar={(v) => aoMudar({ ...valor, alfa: v / 100 })} formato={(v) => `${Math.round(v)}%`} />
          <Regua rotulo={valor.tipo === "radial" ? "Cobre na borda" : "Cobre no fim"} valor={Math.round((valor.alfa2 ?? valor.alfa ?? 1) * 100)} min={0} max={100} aoMudar={(v) => aoMudar({ ...valor, alfa2: v / 100 })} formato={(v) => `${Math.round(v)}%`} />
        </div>
      ) : null}
    </div>
  );
}

/** As cores do meio do degradê (3 ou mais cores): cada uma com a posição; o "+" põe uma no meio do caminho. */
function CoresDoMeio({ valor, aoMudar }: { valor: Pintura; aoMudar: (p: Pintura) => void }) {
  const paradas = valor.paradas || [];
  const mudar = (lista: ParadaDoDegrade[]) => aoMudar({ ...valor, paradas: lista.length ? [...lista].sort((a, b) => a.pos - b.pos) : undefined, ...(lista.length ? { meio: undefined } : {}) });
  return (
    <div className="space-y-2" data-cores-do-meio>
      {paradas.map((q, i) => (
        <div key={i} className="rounded-lg bg-[var(--ks-color-bg-inset)] p-2">
          <div className="flex items-center gap-1.5">
            <div className="min-w-0 flex-1">
              <Cor rotulo={`Cor do meio ${i + 1}`} valor={q.cor} aoMudar={(cor) => mudar(paradas.map((x, j) => (j === i ? { ...x, cor } : x)))} />
            </div>
            <button type="button" title="Tirar esta cor" aria-label={`Tirar a cor do meio ${i + 1}`} onClick={() => mudar(paradas.filter((_, j) => j !== i))} className="flex h-9 w-8 shrink-0 items-center justify-center rounded-lg text-[var(--ks-color-text-soft)] hover:bg-white hover:text-[#BE123C]">
              <X size={14} />
            </button>
          </div>
          <div className="mt-1.5">
            <Regua rotulo="Onde fica" valor={Math.round(q.pos * 100)} min={1} max={99} aoMudar={(v) => mudar(paradas.map((x, j) => (j === i ? { ...x, pos: v / 100 } : x)))} formato={(v) => `${Math.round(v)}%`} />
          </div>
        </div>
      ))}
      {paradas.length < 6 ? (
        <button
          type="button"
          onClick={() => {
            /* A nova entra no maior vão entre as cores que já existem. */
            const posicoes = [0, ...paradas.map((q) => q.pos), 1];
            let melhor = 0.5;
            let vao = 0;
            for (let i = 1; i < posicoes.length; i += 1) {
              if (posicoes[i] - posicoes[i - 1] > vao) {
                vao = posicoes[i] - posicoes[i - 1];
                melhor = (posicoes[i] + posicoes[i - 1]) / 2;
              }
            }
            mudar([...paradas, { pos: Math.round(melhor * 100) / 100, cor: misturarCores(valor.cor, valor.cor2) }]);
          }}
          className="flex h-8 w-full items-center justify-center gap-1.5 rounded-lg border border-dashed border-[var(--ks-color-border)] text-[12px] font-semibold text-[var(--ks-color-text-soft)] transition hover:border-[#A78BFA] hover:text-[#5B21B6]"
        >
          <Plus size={13} /> Cor no meio
        </button>
      ) : null}
    </div>
  );
}

/** O meio de duas cores (para a cor nova do degradê nascer combinando). */
function misturarCores(a: string, b: string) {
  const p = (c: string) => [1, 3, 5].map((i) => parseInt((/^#[0-9a-f]{6}$/i.test(c) ? c : "#888888").slice(i, i + 2), 16));
  const [x, y] = [p(a), p(b)];
  return `#${x.map((v, i) => Math.round((v + y[i]) / 2).toString(16).padStart(2, "0")).join("")}`.toUpperCase();
}

/** O radial com o centro onde quiser (o holofote fora do meio) e o tamanho do círculo. */
function CentroDoRadial({ valor, aoMudar }: { valor: Pintura; aoMudar: (p: Pintura) => void }) {
  const pt = valor.pontos;
  const cx = pt ? pt.x1 : 0.5;
  const cy = pt ? pt.y1 : 0.5;
  const raio = pt ? Math.hypot(pt.x2 - pt.x1, pt.y2 - pt.y1) : 0.5;
  const mudar = (x: number, y: number, r: number) => aoMudar({ ...valor, pontos: { x1: x, y1: y, x2: x + Math.max(0.02, r), y2: y } });
  return (
    <div className="space-y-1.5" data-centro-do-radial>
      <div className="grid grid-cols-2 gap-2">
        <Regua rotulo="Centro: lado" valor={Math.round(cx * 100)} min={-50} max={150} aoMudar={(v) => mudar(v / 100, cy, raio)} formato={(v) => `${Math.round(v)}%`} />
        <Regua rotulo="Centro: altura" valor={Math.round(cy * 100)} min={-50} max={150} aoMudar={(v) => mudar(cx, v / 100, raio)} formato={(v) => `${Math.round(v)}%`} />
      </div>
      <Regua rotulo="Tamanho do círculo" valor={Math.round(raio * 100)} min={5} max={200} aoMudar={(v) => mudar(cx, cy, v / 100)} formato={(v) => `${Math.round(v)}%`} />
      <p className="text-[11px] leading-snug text-[var(--ks-color-text-soft)]">Na arte, arraste as alças: a bolinha do começo é o centro, a do fim é a borda.</p>
    </div>
  );
}

/* --------------------------------------------------------------- sombra */

export function CampoDeSombra({ valor, aoMudar }: { valor: Sombra; aoMudar: (s: Sombra) => void }) {
  const tipo = !valor ? "nenhuma" : valor.desfoque === 0 ? "dura" : valor.x === 0 && valor.y === 0 ? "brilho" : "suave";
  return (
    <div className="space-y-2.5">
      <Opcoes
        valor={tipo}
        opcoes={[
          { valor: "nenhuma", rotulo: "Nenhuma" },
          { valor: "suave", rotulo: "Suave" },
          { valor: "dura", rotulo: "Marcada" },
          { valor: "brilho", rotulo: "Brilho" },
        ]}
        aoMudar={(v) =>
          aoMudar(v === "nenhuma" ? null : v === "suave" ? sombraSuave() : v === "dura" ? sombraDura() : { cor: "#FFFFFF", x: 0, y: 0, desfoque: 30, opacidade: 0.8 })
        }
      />
      {valor ? (
        <>
          <Cor rotulo="Cor da sombra" valor={valor.cor} aoMudar={(cor) => aoMudar({ ...valor, cor })} />
          <div className="grid grid-cols-2 gap-2">
            <Regua rotulo="Para o lado" valor={valor.x} min={-60} max={60} aoMudar={(x) => aoMudar({ ...valor, x })} />
            <Regua rotulo="Para baixo" valor={valor.y} min={-60} max={60} aoMudar={(y) => aoMudar({ ...valor, y })} />
          </div>
          <Regua rotulo="Desfoque" valor={valor.desfoque} min={0} max={120} aoMudar={(desfoque) => aoMudar({ ...valor, desfoque })} />
          <Regua rotulo="Força" valor={Math.round(valor.opacidade * 100)} min={5} max={100} aoMudar={(v) => aoMudar({ ...valor, opacidade: v / 100 })} formato={(v) => `${Math.round(v)}%`} />
        </>
      ) : null}
    </div>
  );
}

/* ---------------------------------------------------------------- borda */

export function CampoDeBorda({ valor, aoMudar, rotulo = "Borda", padrao = 6 }: { valor: Borda; aoMudar: (b: Borda) => void; rotulo?: string; padrao?: number }) {
  return (
    <div className="space-y-2.5">
      <Chave rotulo={rotulo} ligado={Boolean(valor)} aoMudar={(v) => aoMudar(v ? { cor: "#FFFFFF", largura: padrao } : null)} />
      {valor ? (
        <div className="flex items-end gap-2">
          <div className="w-[52px] shrink-0">
            <Cor compacta valor={valor.cor} aoMudar={(cor) => aoMudar({ ...valor, cor })} rotulo={`Cor da ${rotulo.toLowerCase()}`} />
          </div>
          <div className="min-w-0 flex-1">
            <Regua rotulo="Espessura" valor={valor.largura} min={1} max={80} aoMudar={(largura) => aoMudar({ ...valor, largura })} />
          </div>
        </div>
      ) : null}
    </div>
  );
}
