"use client";

import { useRef, useState } from "react";
import { Loader2, Palette, Plus, Shuffle, Trash2, Upload, X } from "lucide-react";
import { getSupabaseClient } from "@/lib/supabase";
import { encolherParaUpload } from "@/lib/fotos/encolher";
import type { KitDaMarca } from "@/lib/banner-editor/kit";
import { enviarFonte } from "@/lib/banner-editor/kit";
import { PALETAS_PRONTAS } from "@/lib/banner-editor/trocar-paleta";
import { BotaoContaGotas, Cor } from "./campos";

/*
  O kit da marca no editor (como o do Canva): as cores, as fontes enviadas
  pela loja e os logos, num lugar só. Clicar numa cor pinta a peça escolhida;
  numa fonte, troca a fonte do texto escolhido (ou cria um texto com ela);
  num logo, põe o logo na arte. Tudo fica guardado para as próximas artes.
*/

function Secao({ titulo, children, acao }: { titulo: string; children: React.ReactNode; acao?: React.ReactNode }) {
  return (
    <section className="mb-6">
      <div className="mb-2.5 flex items-center justify-between">
        <h3 className="text-[13px] font-bold text-[#1F1B2E]">{titulo}</h3>
        {acao}
      </div>
      {children}
    </section>
  );
}

export function PainelDaMarca({
  kit,
  aoMudar,
  semTabela,
  temEscolhida,
  aoUsarCor,
  aoUsarFonte,
  aoUsarLogo,
  aoAvisar,
  aoTrocarPaleta,
  paginas = 1,
}: {
  /* Trocar a paleta da arte inteira (as cores, na ordem de força; `vezes` = quantas vezes já embaralhou). */
  aoTrocarPaleta?: (cores: string[], todas: boolean, vezes: number) => void;
  /* Quantas páginas o projeto tem (com mais de uma, dá para trocar em todas). */
  paginas?: number;
  kit: KitDaMarca;
  aoMudar: (kit: KitDaMarca) => void;
  /* A tabela do kit ainda não existe: vale só nesta visita. */
  semTabela: boolean;
  temEscolhida: boolean;
  aoUsarCor: (cor: string) => void;
  aoUsarFonte: (chave: string) => void;
  aoUsarLogo: (url: string) => void;
  aoAvisar: (texto: string, tom?: "bom" | "ruim") => void;
}) {
  const [novaCor, setNovaCor] = useState("#7C3AED");
  /* A última paleta usada: clicar de novo nela embaralha (outra cor vai na frente). */
  const [ultima, setUltima] = useState<{ chave: string; vezes: number } | null>(null);
  const [emTodas, setEmTodas] = useState(true);
  const usarPaleta = (chave: string, cores: string[]) => {
    if (!aoTrocarPaleta || cores.length < 1) return;
    const vezes = ultima?.chave === chave ? ultima.vezes + 1 : 0;
    setUltima({ chave, vezes });
    aoTrocarPaleta(cores, emTodas, vezes);
  };
  const [enviandoFonte, setEnviandoFonte] = useState(false);
  const [enviandoLogo, setEnviandoLogo] = useState(false);
  const arquivoDeFonte = useRef<HTMLInputElement | null>(null);
  const arquivoDeLogo = useRef<HTMLInputElement | null>(null);

  const porCor = (cor: string) => {
    if (kit.cores.includes(cor)) return;
    aoMudar({ ...kit, cores: [...kit.cores, cor].slice(0, 30) });
  };

  const subirFontes = async (lista: FileList | null) => {
    if (!lista?.length) return;
    setEnviandoFonte(true);
    try {
      const novas = [];
      for (const arquivo of Array.from(lista).slice(0, 20 - kit.fontes.length)) novas.push(await enviarFonte(arquivo));
      aoMudar({ ...kit, fontes: [...kit.fontes, ...novas].slice(0, 20) });
      aoAvisar(novas.length > 1 ? `${novas.length} fontes no kit.` : `Fonte "${novas[0].nome}" no kit.`);
    } catch (erro) {
      aoAvisar(erro instanceof Error ? erro.message : "Não deu para enviar a fonte.", "ruim");
    } finally {
      setEnviandoFonte(false);
      if (arquivoDeFonte.current) arquivoDeFonte.current.value = "";
    }
  };

  const subirLogo = async (lista: FileList | null) => {
    const arquivo = lista?.[0];
    if (!arquivo) return;
    if (!/^image\/(png|jpe?g|webp)$/.test(arquivo.type)) {
      aoAvisar("Use um logo em PNG, JPG ou WebP.", "ruim");
      return;
    }
    setEnviandoLogo(true);
    try {
      const pronto = await encolherParaUpload(arquivo);
      const supabase = getSupabaseClient();
      const caminho = `catalog/sections/pagina-inicial/editor/logos/${Math.random().toString(36).slice(2, 12)}_${Date.now()}.${pronto.name.split(".").pop() || "webp"}`;
      const { error } = await supabase.storage.from("products").upload(caminho, pronto);
      if (error) throw error;
      const url = supabase.storage.from("products").getPublicUrl(caminho).data.publicUrl;
      aoMudar({ ...kit, logos: [...kit.logos, url].slice(0, 30) });
    } catch {
      aoAvisar("Não deu para enviar o logo agora. Tente de novo.", "ruim");
    } finally {
      setEnviandoLogo(false);
      if (arquivoDeLogo.current) arquivoDeLogo.current.value = "";
    }
  };

  const remover = "absolute -right-1.5 -top-1.5 hidden h-5 w-5 items-center justify-center rounded-full bg-[#1F1B2E] text-white shadow group-hover:flex";
  const botaoDeEnviar = "flex h-10 w-full items-center justify-center gap-2 rounded-[10px] border-2 border-dashed border-[#C4B5FD] bg-[#F7F4FF] text-[12.5px] font-bold text-[#5B21B6] transition hover:border-[#8B5CF6] disabled:opacity-60";

  return (
    <div>
      {semTabela ? <p className="mb-4 rounded-[10px] bg-[#FFF7E6] px-3 py-2.5 text-[12px] leading-snug text-[#8A5300]">O kit ainda não fica guardado entre uma visita e outra (falta ligar no banco). Nesta visita ele funciona normalmente, e a arte leva as fontes que usar.</p> : null}
      <p className="mb-4 text-[12px] leading-snug text-[#8A849E]">{temEscolhida ? "Clique numa cor, fonte ou logo para usar na peça escolhida." : "Escolha uma peça na arte e clique numa cor ou fonte para usar nela."}</p>

      {aoTrocarPaleta ? (
        <Secao
          titulo="Paleta da arte"
          acao={
            paginas > 1 ? (
              <label className="flex items-center gap-1.5 text-[11.5px] font-semibold text-[#6B6584]">
                <input type="checkbox" checked={emTodas} onChange={(e) => setEmTodas(e.target.checked)} className="h-3.5 w-3.5 accent-[#7C3AED]" data-paleta-em-todas />
                Todas as {paginas} páginas
              </label>
            ) : null
          }
        >
          <p className="mb-2.5 text-[12px] leading-snug text-[#8A849E]">Um clique troca as cores da arte inteira. Clique de novo na mesma para embaralhar.</p>
          <div className="space-y-1.5" data-paletas>
            {kit.cores.length ? (
              <button type="button" onClick={() => usarPaleta("marca", kit.cores)} className="group flex w-full items-center gap-2.5 rounded-[10px] bg-[#F1ECFF] px-2.5 py-2 text-left transition hover:bg-[#E9E0FF]" data-paleta="marca">
                <span className="flex overflow-hidden rounded-[6px] ring-1 ring-black/10">
                  {kit.cores.slice(0, 5).map((c) => (
                    <span key={c} className="h-7 w-6" style={{ background: c }} />
                  ))}
                </span>
                <span className="flex-1 text-[12.5px] font-bold text-[#5B21B6]">Cores da marca</span>
                {ultima?.chave === "marca" ? <Shuffle size={14} className="text-[#7C3AED]" /> : <Palette size={14} className="text-[#7C3AED]" />}
              </button>
            ) : null}
            {PALETAS_PRONTAS.map((p) => (
              <button key={p.chave} type="button" onClick={() => usarPaleta(p.chave, p.cores)} className={`group flex w-full items-center gap-2.5 rounded-[10px] px-2.5 py-1.5 text-left transition hover:bg-[#F6F4FB] ${ultima?.chave === p.chave ? "bg-[#F6F4FB] ring-1 ring-[#C4B5FD]" : ""}`} data-paleta={p.chave}>
                <span className="flex overflow-hidden rounded-[6px] ring-1 ring-black/10">
                  {p.cores.map((c) => (
                    <span key={c} className="h-6 w-6" style={{ background: c }} />
                  ))}
                </span>
                <span className="flex-1 text-[12.5px] font-semibold text-[#2B2640]">{p.nome}</span>
                {ultima?.chave === p.chave ? <Shuffle size={14} className="text-[#7C3AED]" /> : null}
              </button>
            ))}
          </div>
        </Secao>
      ) : null}

      <Secao titulo="Cores da marca">
        <div className="flex flex-wrap gap-2">
          {kit.cores.map((cor) => (
            <div key={cor} className="group relative">
              <button type="button" title={`Usar ${cor}`} onClick={() => aoUsarCor(cor)} className="h-10 w-10 rounded-[10px] ring-1 ring-black/10 transition hover:scale-110" style={{ background: cor }} />
              <button type="button" title="Tirar do kit" onClick={() => aoMudar({ ...kit, cores: kit.cores.filter((c) => c !== cor) })} className={remover}>
                <X size={11} />
              </button>
            </div>
          ))}
        </div>
        <div className="mt-3 flex items-center gap-2">
          <div className="min-w-0 flex-1">
            <Cor valor={novaCor} aoMudar={setNovaCor} rotulo="Cor nova" />
          </div>
          <BotaoContaGotas aoPegar={(cor) => porCor(cor)} />
          <button type="button" onClick={() => porCor(novaCor)} title="Pôr no kit" className="flex h-9 shrink-0 items-center gap-1 rounded-[10px] bg-[#7C3AED] px-3 text-[12px] font-bold text-white hover:bg-[#6D28D9]">
            <Plus size={14} /> Pôr
          </button>
        </div>
      </Secao>

      <Secao titulo="Fontes da marca">
        <input ref={arquivoDeFonte} type="file" accept=".ttf,.otf,.woff,.woff2,font/ttf,font/otf,font/woff,font/woff2" multiple className="hidden" onChange={(e) => void subirFontes(e.target.files)} aria-label="Arquivo de fonte" />
        <div className="space-y-1.5">
          {kit.fontes.map((f) => (
            <div key={f.chave} className="group flex items-center gap-2 rounded-[10px] bg-[#F6F4FB] px-3 py-2">
              <button type="button" onClick={() => aoUsarFonte(f.chave)} className="min-w-0 flex-1 text-left" title="Usar esta fonte">
                <span className="block truncate text-[20px] leading-tight text-[#1F1B2E]" style={{ fontFamily: `'${f.chave}', sans-serif` }}>
                  {f.nome}
                </span>
                <span className="text-[10.5px] text-[#9A94AE]">Clique para usar</span>
              </button>
              <input
                defaultValue={f.nome}
                onBlur={(e) => {
                  const nome = e.target.value.replace(/[<>"'`]/g, "").trim().slice(0, 60);
                  if (nome && nome !== f.nome) aoMudar({ ...kit, fontes: kit.fontes.map((x) => (x.chave === f.chave ? { ...x, nome } : x)) });
                }}
                className="hidden w-24 rounded-[6px] border border-[#E6E3EE] bg-white px-1.5 py-1 text-[11px] group-hover:block"
                aria-label="Nome da fonte"
              />
              <button type="button" title="Tirar do kit" onClick={() => aoMudar({ ...kit, fontes: kit.fontes.filter((x) => x.chave !== f.chave) })} className="flex h-7 w-7 shrink-0 items-center justify-center rounded-[8px] text-[#8A849E] hover:bg-[#FFE4E6] hover:text-[#BE123C]">
                <Trash2 size={14} />
              </button>
            </div>
          ))}
        </div>
        <button type="button" disabled={enviandoFonte || kit.fontes.length >= 20} onClick={() => arquivoDeFonte.current?.click()} className={`${botaoDeEnviar} mt-2`}>
          {enviandoFonte ? <Loader2 size={15} className="animate-spin" /> : <Upload size={15} />}
          {enviandoFonte ? "Enviando a fonte…" : "Enviar fonte (TTF, OTF, WOFF)"}
        </button>
        <p className="mt-1.5 text-[11px] leading-snug text-[#9A94AE]">Envie só fontes que a loja tem direito de usar (a do cliente ou uma de licença livre).</p>
      </Secao>

      <Secao titulo="Logos">
        <input ref={arquivoDeLogo} type="file" accept="image/png,image/jpeg,image/webp" className="hidden" onChange={(e) => void subirLogo(e.target.files)} aria-label="Arquivo do logo" />
        <div className="grid grid-cols-2 gap-2">
          {kit.logos.map((url) => (
            <div key={url} className="group relative">
              <button type="button" title="Pôr na arte" onClick={() => aoUsarLogo(url)} className="flex h-20 w-full items-center justify-center rounded-[12px] bg-[repeating-conic-gradient(#EEEBF5_0%_25%,#FFFFFF_0%_50%)] bg-[length:14px_14px] p-2 ring-1 ring-black/5 transition hover:ring-2 hover:ring-[#8B5CF6]">
                {/* eslint-disable-next-line @next/next/no-img-element */}
                <img src={url} alt="Logo" className="max-h-full max-w-full object-contain" />
              </button>
              <button type="button" title="Tirar do kit" onClick={() => aoMudar({ ...kit, logos: kit.logos.filter((l) => l !== url) })} className={remover}>
                <X size={11} />
              </button>
            </div>
          ))}
        </div>
        <button type="button" disabled={enviandoLogo || kit.logos.length >= 30} onClick={() => arquivoDeLogo.current?.click()} className={`${botaoDeEnviar} mt-2`}>
          {enviandoLogo ? <Loader2 size={15} className="animate-spin" /> : <Upload size={15} />}
          {enviandoLogo ? "Enviando…" : "Enviar logo"}
        </button>
      </Secao>
    </div>
  );
}
