"use client";

import { Blend, Circle, Diamond, Droplet, Grid3x3, Layers, Minus, PaintBucket, Plus, Sparkles, Square, SunMedium, Trash2 } from "lucide-react";
import { useMemo } from "react";
import type { Peca } from "@/lib/banner-editor/documento";
import { LIMITE_DE_PONTOS_VIVOS, PRONTOS_DA_RETICULA_VIVA, enderecoDaReticulaViva, reticulaVivaPronta, type FormaDoPontoVivo, type MisturaDaReticulaViva, type PontoVivo, type ReticulaViva } from "@/lib/banner-editor/reticula-viva";
import { BotaoDoPainel, Cor, Dica, Opcoes, Regua, Rotulo, Secao } from "./campos";

/*
  O painel da Retícula Viva (nov/2026, do vídeo do Natan: o degradê livre do
  Illustrator com a retícula colorida por cima). Liga com um clique (um
  pronto na medida da peça) e se ajusta aqui e na própria arte: os pontos de
  cor aparecem na peça para arrastar, o escolhido mostra o círculo tracejado
  do alcance com a alça, e clicar na peça põe outro ponto (palco.tsx).
*/

/** O ícone da Retícula Viva: as bolinhas crescendo perto de um canto. */
export function IconeDaReticulaViva({ size = 16, className }: { size?: number; className?: string }) {
  const bolinhas: Array<[number, number, number]> = [
    [5, 5, 3],
    [12, 5, 2.2],
    [19, 5, 1.4],
    [5, 12, 2.2],
    [12, 12, 1.7],
    [19, 12, 1.1],
    [5, 19, 1.4],
    [12, 19, 1.1],
    [19, 19, 0.8],
  ];
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" className={className} fill="currentColor" aria-hidden="true">
      {bolinhas.map(([x, y, r]) => (
        <circle key={`${x}-${y}`} cx={x} cy={y} r={r} />
      ))}
    </svg>
  );
}

/* As cores dos pontos novos (a primeira que a retícula ainda não usa). */
const CORES_NOVAS = ["#E40FD3", "#00E5FF", "#FFD400", "#FF3D6E", "#7C3AED", "#22C55E", "#FF8A00", "#111111"];

const FORMAS: Array<{ valor: FormaDoPontoVivo; rotulo: string; icone: typeof Circle }> = [
  { valor: "pontos", rotulo: "Bolinhas", icone: Circle },
  { valor: "quadrados", rotulo: "Quadrados", icone: Square },
  { valor: "losangos", rotulo: "Losangos", icone: Diamond },
  { valor: "linhas", rotulo: "Linhas", icone: Minus },
];

const MISTURAS: Array<{ valor: MisturaDaReticulaViva; rotulo: string; titulo: string; icone: typeof Blend }> = [
  { valor: "normal", rotulo: "Por cima", titulo: "As bolinhas por cima da peça", icone: Circle },
  { valor: "multiplicar", rotulo: "Escurece", titulo: "Multiplicar: as bolinhas tingem e escurecem (ótimo na foto)", icone: Droplet },
  { valor: "tela", rotulo: "Clareia", titulo: "Tela: as bolinhas clareiam", icone: SunMedium },
  { valor: "sobrepor", rotulo: "Contraste", titulo: "Sobrepor: contraste e cor juntos", icone: Blend },
];

/** Quatro escolhas lado a lado, cada uma com o ícone em cima e o nome embaixo (os nomes cabem inteiros). */
function GradeDeEscolhas<T extends string>({ valor, opcoes, aoMudar }: { valor: T; opcoes: Array<{ valor: T; rotulo: string; titulo?: string; icone: typeof Circle }>; aoMudar: (v: T) => void }) {
  return (
    <div className="grid grid-cols-4 gap-1" role="radiogroup">
      {opcoes.map(({ valor: v, rotulo, titulo, icone: Icone }) => (
        <button
          key={v}
          type="button"
          role="radio"
          aria-checked={valor === v}
          title={titulo ?? rotulo}
          onClick={() => aoMudar(v)}
          className={`flex flex-col items-center gap-1 rounded-[9px] px-1 py-2 text-[11px] font-semibold transition ${valor === v ? "bg-[#7C3AED] text-white shadow-sm" : "text-[#5A5470] ring-1 ring-[#E7E4EF] hover:bg-[#F6F5FA] hover:text-[#1F1B2E]"}`}
        >
          <Icone size={16} />
          <span className="w-full truncate text-center">{rotulo}</span>
        </button>
      ))}
    </div>
  );
}

/** O lugar do ponto novo: o meio da peça, ou o lugar mais longe dos pontos que já existem. */
function lugarDoPontoNovo(pontos: PontoVivo[]) {
  const candidatos: Array<[number, number]> = [];
  for (let x = 0.15; x <= 0.86; x += 0.175) for (let y = 0.15; y <= 0.86; y += 0.175) candidatos.push([x, y]);
  let melhor: [number, number] = [0.5, 0.5];
  let distancia = -1;
  for (const [x, y] of candidatos) {
    const d = Math.min(...pontos.map((q) => Math.hypot(q.x - x, q.y - y)), 9);
    if (d > distancia) {
      distancia = d;
      melhor = [x, y];
    }
  }
  return melhor;
}

export function PainelDaReticulaViva({ peca, mudar, ponto, aoEscolherPonto }: { peca: Peca; mudar: (campos: Partial<Peca>) => void; ponto: number | null; aoEscolherPonto: (i: number | null) => void }) {
  const r = peca.reticulaViva ?? null;
  const trocar = (campos: Partial<ReticulaViva>) => {
    if (r) mudar({ reticulaViva: { ...r, ...campos } } as Partial<Peca>);
  };
  const trocarPonto = (i: number, campos: Partial<PontoVivo>) => r && trocar({ pontos: r.pontos.map((q, j) => (j === i ? { ...q, ...campos } : q)) });
  const escolhido = r ? (ponto !== null && ponto < r.pontos.length ? ponto : 0) : null;
  /* As miniaturas dos prontos: a própria retícula de cada um (feita uma vez). */
  const miniaturas = useMemo(() => PRONTOS_DA_RETICULA_VIVA.map((p) => enderecoDaReticulaViva({ ...reticulaVivaPronta(p.chave, 120, 76), tamanho: 8 }, 120, 76)), []);
  const tamanhoMaximo = Math.max(12, Math.round(Math.min(peca.w, peca.h) / 4));
  const ligar = (v: boolean) => {
    mudar({ reticulaViva: v ? reticulaVivaPronta(peca.tipo === "imagem" ? "na-foto" : "magenta-e-azul", peca.w, peca.h) : null } as Partial<Peca>);
    aoEscolherPonto(v ? 0 : null);
  };
  const porPonto = () => {
    if (!r || r.pontos.length >= LIMITE_DE_PONTOS_VIVOS) return;
    const [x, y] = lugarDoPontoNovo(r.pontos);
    const cor = CORES_NOVAS.find((c) => !r.pontos.some((q) => q.cor === c)) ?? CORES_NOVAS[0];
    trocar({ pontos: [...r.pontos, { x, y, cor, alcance: 0.45 }] });
    aoEscolherPonto(r.pontos.length);
  };
  const tirarPonto = (i: number) => {
    if (!r || r.pontos.length <= 1) return;
    trocar({ pontos: r.pontos.filter((_, j) => j !== i) });
    aoEscolherPonto(Math.max(0, Math.min(i, r.pontos.length - 2)));
  };

  return (
    <div data-painel-da-reticula-viva>
      <Secao
        titulo="Retícula Viva"
        icone={IconeDaReticulaViva}
        ligado={Boolean(r)}
        aoLigar={ligar}
        dica="Pontos de cor soltos na peça: as bolinhas da retícula crescem perto de cada ponto e somem longe dele, na cor do ponto (o degradê livre com retícula do Illustrator). Vale para texto, forma, foto, ícone e desenho."
      >
        {r ? <Dica>Na arte: arraste os pontos, puxe a alça do círculo tracejado para mudar o alcance e clique na peça para pôr outro ponto. Delete tira o ponto escolhido.</Dica> : null}
      </Secao>

      {r ? (
        <>
          <Secao titulo="Prontos" icone={Sparkles} dica="Um clique troca as cores e os pontos (na medida da peça).">
            <div className="grid grid-cols-4 gap-1.5" data-prontos-da-reticula-viva>
              {PRONTOS_DA_RETICULA_VIVA.map((p, i) => (
                <button
                  key={p.chave}
                  type="button"
                  title={p.nome}
                  onClick={() => {
                    mudar({ reticulaViva: reticulaVivaPronta(p.chave, peca.w, peca.h) } as Partial<Peca>);
                    aoEscolherPonto(0);
                  }}
                  className="group flex flex-col items-center gap-1"
                  data-pronto-vivo={p.chave}
                >
                  <span
                    className="block h-11 w-full rounded-[8px] ring-1 ring-black/10 transition group-hover:ring-2 group-hover:ring-[#8B5CF6]"
                    style={{ background: `url("${miniaturas[i]}") center/cover no-repeat, ${p.papel ? p.papel : "linear-gradient(135deg,#D9D6E3,#9A93B5)"}` }}
                  />
                  <span className="w-full truncate text-center text-[10.5px] font-medium text-[#5A5470]">{p.nome}</span>
                </button>
              ))}
            </div>
          </Secao>

          <Secao
            titulo="Pontos de cor"
            icone={PaintBucket}
            acao={
              r.pontos.length < LIMITE_DE_PONTOS_VIVOS ? (
                <button type="button" title="Pôr outro ponto (ou clique na peça, na arte)" onClick={porPonto} className="flex h-7 items-center gap-1 rounded-[8px] px-2 text-[11.5px] font-semibold text-[#5B21B6] hover:bg-[#F5F3FF]" data-por-ponto-vivo>
                  <Plus size={14} /> Ponto
                </button>
              ) : null
            }
          >
            <div className="space-y-1" data-pontos-vivos>
              {r.pontos.map((q, i) => (
                <div
                  key={i}
                  role="button"
                  tabIndex={0}
                  onClick={() => aoEscolherPonto(i)}
                  onKeyDown={(e) => (e.key === "Enter" ? aoEscolherPonto(i) : undefined)}
                  className={`flex items-center gap-2 rounded-[10px] px-1.5 py-1 transition ${escolhido === i ? "bg-[#F5F3FF] ring-1 ring-[#C4B5FD]" : "hover:bg-[#F8F7FB]"}`}
                  data-ponto-vivo={i}
                >
                  <span onClick={(e) => e.stopPropagation()}>
                    <Cor compacta valor={q.cor} aoMudar={(cor) => trocarPonto(i, { cor })} />
                  </span>
                  <span className="min-w-0 flex-1 truncate text-[12px] font-semibold text-[#2B2640]">Ponto {i + 1}</span>
                  <span className="text-[11px] tabular-nums text-[#8A849E]">{Math.round(q.alcance * 100)}%</span>
                  {r.pontos.length > 1 ? (
                    <button
                      type="button"
                      title="Tirar este ponto"
                      onClick={(e) => {
                        e.stopPropagation();
                        tirarPonto(i);
                      }}
                      className="flex h-7 w-7 items-center justify-center rounded-[8px] text-[#8A849E] hover:bg-[#FFF1F2] hover:text-[#BE123C]"
                    >
                      <Trash2 size={14} />
                    </button>
                  ) : null}
                </div>
              ))}
            </div>
            {escolhido !== null ? (
              <div className="mt-3">
                <Regua rotulo={`Alcance do ponto ${escolhido + 1}`} valor={Math.round(r.pontos[escolhido].alcance * 100)} min={5} max={200} aoMudar={(v) => trocarPonto(escolhido, { alcance: v / 100 })} formato={(v) => `${Math.round(v)}%`} padrao={50} />
              </div>
            ) : null}
          </Secao>

          <Secao titulo="Bolinhas" icone={Grid3x3}>
            <div className="space-y-3.5">
              <GradeDeEscolhas<FormaDoPontoVivo> valor={r.forma} opcoes={FORMAS} aoMudar={(forma) => trocar({ forma })} />
              <Regua rotulo="Tamanho" valor={Math.round(Math.min(r.tamanho, tamanhoMaximo))} min={2} max={tamanhoMaximo} aoMudar={(tamanho) => trocar({ tamanho })} formato={(v) => `${Math.round(v)} px`} />
              <Regua rotulo="Ângulo da grade" valor={Math.round(r.angulo)} min={0} max={180} aoMudar={(angulo) => trocar({ angulo })} formato={(v) => `${Math.round(v)}°`} padrao={45} />
            </div>
          </Secao>

          <Secao titulo="Entre as bolinhas" icone={Layers}>
            <div className="space-y-3">
              <Opcoes<"peca" | "cor">
                valor={r.papel ? "cor" : "peca"}
                opcoes={[
                  { valor: "peca", rotulo: "Cor da peça", titulo: "Entre as bolinhas aparece a própria peça (a cor dela ou a foto)" },
                  { valor: "cor", rotulo: "Uma cor", titulo: "Um fundo de uma cor entre as bolinhas" },
                ]}
                aoMudar={(v) => trocar({ papel: v === "cor" ? (r.papel ?? "#1405C8") : null })}
              />
              {r.papel ? <Cor valor={r.papel} aoMudar={(papel) => trocar({ papel })} rotulo="Cor entre as bolinhas" /> : null}
              <div>
                <Rotulo>Mistura com a peça</Rotulo>
                <GradeDeEscolhas<MisturaDaReticulaViva> valor={r.mistura ?? "normal"} opcoes={MISTURAS} aoMudar={(mistura) => trocar({ mistura: mistura === "normal" ? undefined : mistura })} />
              </div>
            </div>
          </Secao>

          <div className="pt-1">
            <BotaoDoPainel icone={Trash2} tom="perigo" largo aoClicar={() => ligar(false)} data-tirar-reticula-viva>
              Tirar a Retícula Viva
            </BotaoDoPainel>
          </div>
        </>
      ) : null}
    </div>
  );
}
