"use client";

import { useEffect, useId, useRef, useState } from "react";
import { Check, Pipette, RotateCcw } from "lucide-react";

/**
 * Campo de cor da personalizacao do catalogo.
 *
 * O `<input type="color">` cru resolve, mas entrega o quadradinho do sistema
 * operacional: tamanho diferente em cada navegador, sem estado de "automatico"
 * e sem nenhuma relacao com o resto do painel. Aqui a amostra e um botao
 * desenhado por nos e a escolha acontece num painel proprio, com paleta pronta,
 * campo hexadecimal e — para quem quiser liberdade total — o seletor do sistema
 * atras de um botao secundario.
 *
 * Valor vazio significa AUTOMATICO, nao "sem cor". A amostra mostra a cor que o
 * sistema aplicaria (`fallback`) por baixo de um xadrez discreto, para o lojista
 * enxergar o que vai acontecer sem precisar salvar e conferir na loja.
 */

const PALETA_NEUTRA = ["#FFFFFF", "#F8FAFC", "#E2E8F0", "#CBD5E1", "#94A3B8", "#64748B", "#475569", "#1E293B", "#0F172A"];

const PALETA_CORES = [
  ["#FFE4E6", "#FDA4AF", "#F43F5E", "#BE123C", "#881337"],
  ["#FFEDD5", "#FDBA74", "#F97316", "#C2410C", "#7C2D12"],
  ["#FEF3C7", "#FCD34D", "#F59E0B", "#B45309", "#78350F"],
  ["#DCFCE7", "#86EFAC", "#22C55E", "#15803D", "#14532D"],
  ["#CCFBF1", "#5EEAD4", "#14B8A6", "#0F766E", "#134E4A"],
  ["#E0F2FE", "#7DD3FC", "#0EA5E9", "#0369A1", "#0C4A6E"],
  ["#E0E7FF", "#A5B4FC", "#6366F1", "#4338CA", "#312E81"],
  ["#F3E8FF", "#D8B4FE", "#A855F7", "#7E22CE", "#581C87"],
  ["#FCE7F3", "#F9A8D4", "#EC4899", "#BE185D", "#831843"],
];

function normalizarHex(valor: string) {
  const bruto = String(valor || "").trim().replace(/^#/, "");
  const expandido = bruto.length === 3 ? bruto.split("").map((c) => c + c).join("") : bruto;
  if (!/^[0-9a-fA-F]{6}$/.test(expandido)) return null;
  return `#${expandido.toUpperCase()}`;
}

function textoLegivel(hex: string) {
  const seguro = normalizarHex(hex) || "#FFFFFF";
  const canal = (i: number) => {
    const v = parseInt(seguro.slice(1 + i * 2, 3 + i * 2), 16) / 255;
    return v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
  };
  const luminancia = 0.2126 * canal(0) + 0.7152 * canal(1) + 0.0722 * canal(2);
  return luminancia > 0.45 ? "#0F172A" : "#FFFFFF";
}

export function ColorField({
  label,
  value,
  onChange,
  fallback = "#FFFFFF",
  description,
  allowAuto = true,
}: {
  label: string;
  value: string;
  onChange: (valor: string) => void;
  fallback?: string;
  description?: string;
  allowAuto?: boolean;
}) {
  const [aberto, setAberto] = useState(false);
  const [abrirParaCima, setAbrirParaCima] = useState(false);
  const [rascunhoHex, setRascunhoHex] = useState("");
  const containerRef = useRef<HTMLDivElement | null>(null);
  const inputNativoRef = useRef<HTMLInputElement | null>(null);
  const idPainel = useId();

  const ehAutomatico = !String(value || "").trim();
  const corAtual = normalizarHex(value) || normalizarHex(fallback) || "#FFFFFF";

  useEffect(() => {
    if (!aberto) return;
    const aoClicarFora = (evento: MouseEvent) => {
      if (!containerRef.current?.contains(evento.target as Node)) setAberto(false);
    };
    const aoTeclar = (evento: KeyboardEvent) => {
      if (evento.key === "Escape") setAberto(false);
    };
    document.addEventListener("mousedown", aoClicarFora);
    document.addEventListener("keydown", aoTeclar);
    return () => {
      document.removeEventListener("mousedown", aoClicarFora);
      document.removeEventListener("keydown", aoTeclar);
    };
  }, [aberto]);

  const aplicar = (hex: string) => {
    const normalizado = normalizarHex(hex);
    if (!normalizado) return;
    onChange(normalizado);
  };

  const confirmarRascunho = () => {
    const normalizado = normalizarHex(rascunhoHex);
    if (normalizado) onChange(normalizado);
    setRascunhoHex("");
  };

  return (
    <div ref={containerRef} className="relative">
      <button
        type="button"
        onClick={(evento) => {
          /* Abre para cima quando nao ha espaco abaixo: sem isso a paleta fica
             cortada pela borda da janela nos campos do fim da pagina. */
          const caixa = evento.currentTarget.getBoundingClientRect();
          setAbrirParaCima(window.innerHeight - caixa.bottom < 340 && caixa.top > 340);
          setRascunhoHex(ehAutomatico ? "" : corAtual.replace("#", ""));
          setAberto((atual) => !atual);
        }}
        aria-expanded={aberto}
        aria-controls={idPainel}
        className="group flex w-full items-center gap-3 rounded-2xl border border-[var(--ks-color-border-subtle)] bg-white p-2.5 text-left transition hover:border-[var(--ks-color-primary)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ks-color-primary)]"
      >
        <span
          className="relative flex h-10 w-10 shrink-0 items-center justify-center overflow-hidden rounded-xl ring-1 ring-black/10"
          style={{ backgroundColor: corAtual }}
        >
          {/* Xadrez so no automatico: sinaliza "ninguem escolheu ainda" sem
              esconder qual cor o sistema vai usar. */}
          {ehAutomatico ? (
            <span
              aria-hidden
              className="absolute inset-0 opacity-45"
              style={{
                backgroundImage:
                  "linear-gradient(45deg, rgba(255,255,255,.9) 25%, transparent 25%, transparent 75%, rgba(255,255,255,.9) 75%), linear-gradient(45deg, rgba(255,255,255,.9) 25%, transparent 25%, transparent 75%, rgba(255,255,255,.9) 75%)",
                backgroundSize: "8px 8px",
                backgroundPosition: "0 0, 4px 4px",
              }}
            />
          ) : null}
        </span>

        <span className="min-w-0 flex-1">
          <span className="block truncate text-sm font-medium text-[var(--ks-color-text-primary)]">{label}</span>
          <span className="mt-0.5 flex items-center gap-1.5">
            {ehAutomatico ? (
              <span className="inline-flex items-center rounded-full bg-[var(--ks-color-surface-subtle)] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-[var(--ks-color-text-soft)]">
                Automático
              </span>
            ) : (
              <span className="font-mono text-[11px] text-[var(--ks-color-text-soft)]">{corAtual}</span>
            )}
          </span>
        </span>
      </button>

      {description ? (
        <p className="mt-1 px-1 text-[11px] leading-snug text-[var(--ks-color-text-soft)]">{description}</p>
      ) : null}

      {aberto ? (
        <div
          id={idPainel}
          /* No celular vira folha inferior, que e onde o dedo alcanca; do `sm`
             para cima ancora no proprio campo. */
          className={`fixed inset-x-3 bottom-3 z-50 rounded-2xl border border-[var(--ks-color-border-subtle)] bg-white p-4 shadow-[0_24px_60px_rgba(15,23,42,0.18)] sm:absolute sm:inset-x-auto sm:left-0 sm:w-[288px] ${
            abrirParaCima ? "sm:bottom-[calc(100%+8px)] sm:top-auto" : "sm:bottom-auto sm:top-[calc(100%+8px)]"
          }`}
        >
          <div className="mb-3 flex items-center justify-between gap-2">
            <span className="text-xs font-semibold uppercase tracking-wide text-[var(--ks-color-text-soft)]">
              {label}
            </span>
            {allowAuto ? (
              <button
                type="button"
                onClick={() => {
                  onChange("");
                  setAberto(false);
                }}
                className="inline-flex items-center gap-1 rounded-full px-2 py-1 text-[11px] font-semibold text-[var(--ks-color-text-muted)] transition hover:bg-[var(--ks-color-surface-subtle)]"
              >
                <RotateCcw size={12} />
                Automático
              </button>
            ) : null}
          </div>

          <div className="grid grid-cols-9 gap-1">
            {PALETA_NEUTRA.map((cor) => (
              <Amostra key={cor} cor={cor} ativa={!ehAutomatico && corAtual === cor} onSelecionar={aplicar} />
            ))}
          </div>

          {/* Matriz: cada coluna e um matiz, cada linha um tom. Transpor deixa
              as familias de cor alinhadas na vertical, que e como o olho
              compara. */}
          <div className="mt-1 grid grid-cols-9 gap-1">
            {[0, 1, 2, 3, 4].map((tom) =>
              PALETA_CORES.map((matiz) => (
                <Amostra
                  key={`${tom}-${matiz[tom]}`}
                  cor={matiz[tom]}
                  ativa={!ehAutomatico && corAtual === matiz[tom]}
                  onSelecionar={aplicar}
                />
              ))
            )}
          </div>

          <div className="mt-3 flex items-center gap-2">
            <div className="flex h-9 min-w-0 flex-1 items-center gap-1 rounded-xl border border-[var(--ks-color-border-subtle)] px-2">
              <span className="text-xs font-semibold text-[var(--ks-color-text-soft)]">#</span>
              <input
                value={rascunhoHex}
                onChange={(e) => setRascunhoHex(e.target.value.replace(/[^0-9a-fA-F]/g, "").slice(0, 6))}
                onBlur={confirmarRascunho}
                onKeyDown={(e) => {
                  if (e.key === "Enter") {
                    e.preventDefault();
                    confirmarRascunho();
                  }
                }}
                placeholder="FFFFFF"
                spellCheck={false}
                className="w-full min-w-0 bg-transparent font-mono text-xs uppercase text-[var(--ks-color-text-primary)] outline-none"
              />
            </div>
            <button
              type="button"
              onClick={() => inputNativoRef.current?.click()}
              title="Escolher no seletor do sistema"
              className="inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-xl border border-[var(--ks-color-border-subtle)] text-[var(--ks-color-text-muted)] transition hover:bg-[var(--ks-color-surface-subtle)]"
            >
              <Pipette size={14} />
            </button>
            {/* Seletor nativo continua acessivel, mas escondido atras do botao:
                liberdade total de cor sem o quadradinho do sistema na tela. */}
            <input
              ref={inputNativoRef}
              type="color"
              value={corAtual}
              onChange={(e) => aplicar(e.target.value)}
              className="sr-only"
              tabIndex={-1}
              aria-hidden
            />
          </div>
        </div>
      ) : null}
    </div>
  );
}

function Amostra({
  cor,
  ativa,
  onSelecionar,
}: {
  cor: string;
  ativa: boolean;
  onSelecionar: (cor: string) => void;
}) {
  return (
    <button
      type="button"
      onClick={() => onSelecionar(cor)}
      title={cor}
      aria-label={cor}
      className="flex h-6 w-full items-center justify-center rounded-md ring-1 ring-inset ring-black/10 transition hover:scale-[1.12]"
      style={{ backgroundColor: cor }}
    >
      {ativa ? <Check size={12} style={{ color: textoLegivel(cor) }} /> : null}
    </button>
  );
}
