"use client";

import dynamic from "next/dynamic";
import { useEffect, useRef, useState } from "react";
import { Check, Loader2, Palette, RefreshCw, Sparkles, X } from "lucide-react";
import { useDesignLiberado } from "@/components/design/liberacao-do-design";
import { ColorField } from "@/components/ui/color-field";
import { Switch } from "@/components/ui/switch";
import { MODELOS } from "@/lib/assistentes/ferramentas/gerador-de-banner-modelos";
import { CampoDeImagem, Escolha, Segmentos, Texto } from "./campos";
import { useEditorDoPainel } from "./contexto";

/* O editor de artes só baixa para quem tem o KtaloguDesign liberado. */
const EditorDeBanner = dynamic(() => import("./editor-de-banner/editor-de-banner").then((m) => m.EditorDeBanner), { ssr: false });

/*
  O banner dentro de um campo de imagem do editor (banner, carrossel,
  imagens lado a lado), no tamanho exato da imagem da seção; o pronto já vai
  para o depósito da loja.

  - Com o KtaloguDesign liberado (beta, lib/banner-editor/liberacao.ts):
    "Criar banner" abre o editor de artes (editor-de-banner/), com os modelos
    prontos e todas as peças soltas para arrastar, girar e pintar.
  - Sem ele: "Gerar banner com IA", o formulário pequeno que chama o mesmo
    gerador do assistente (/api/loja/editor/banner). A pessoa vê a prévia e
    decide: usar, ou gerar de novo com outro texto, modelo ou cor.
*/

type Foto = "nenhuma" | "produto" | "enviada";

const NOME_DO_MODELO: Record<string, string> = {
  "imagem à direita": "Foto à direita",
  "imagem de fundo com degradê": "Foto de fundo",
  centralizado: "Centralizado",
  "oferta com selo de desconto": "Oferta com selo",
  minimalista: "Minimalista",
};

export function BotaoDeGerarBanner({ largura, altura, aoUsar }: { largura: number; altura: number; aoUsar: (url: string) => void }) {
  const painel = useEditorDoPainel();
  const comDesign = useDesignLiberado();
  const [aberto, setAberto] = useState(false);
  if (!painel?.podeGerarBanner) return null;
  const Janela = comDesign ? EditorDeBanner : JanelaDoGerador;
  return (
    <>
      <button
        type="button"
        onClick={() => setAberto(true)}
        className="mt-2 inline-flex items-center gap-1.5 rounded-full bg-[linear-gradient(135deg,#7346e8,#5228bd)] px-3 py-1.5 text-[12px] font-bold text-white shadow-[0_6px_16px_-6px_rgba(91,47,214,0.7)] transition hover:brightness-110"
      >
        {comDesign ? <Palette size={14} /> : <Sparkles size={14} />} {comDesign ? "Criar banner" : "Gerar banner com IA"}
      </button>
      {aberto ? (
        <Janela
          largura={largura}
          altura={altura}
          aoFechar={() => setAberto(false)}
          aoUsar={(url) => {
            aoUsar(url);
            setAberto(false);
          }}
        />
      ) : null}
    </>
  );
}

function JanelaDoGerador({ largura, altura, aoFechar, aoUsar }: { largura: number; altura: number; aoFechar: () => void; aoUsar: (url: string) => void }) {
  const painel = useEditorDoPainel();
  const [titulo, setTitulo] = useState("");
  const [subtitulo, setSubtitulo] = useState("");
  const [botao, setBotao] = useState("");
  const [selo, setSelo] = useState("");
  const [modelo, setModelo] = useState<string>("imagem à direita");
  const [foto, setFoto] = useState<Foto>("nenhuma");
  const [produtoId, setProdutoId] = useState<string | null>(null);
  const [enviada, setEnviada] = useState("");
  const [fundo, setFundo] = useState(painel?.corDaLoja || "");
  const [texto, setTexto] = useState("");
  const [destaque, setDestaque] = useState("");
  const [usarLogo, setUsarLogo] = useState(true);
  const [gerando, setGerando] = useState(false);
  const [segundos, setSegundos] = useState(0);
  const [falha, setFalha] = useState("");
  const [pronto, setPronto] = useState<string | null>(null);
  const relogio = useRef<number | null>(null);

  useEffect(() => {
    const aoTeclar = (e: KeyboardEvent) => {
      if (e.key === "Escape" && !gerando) aoFechar();
    };
    window.addEventListener("keydown", aoTeclar);
    return () => window.removeEventListener("keydown", aoTeclar);
  }, [aoFechar, gerando]);

  useEffect(() => () => {
    if (relogio.current) window.clearInterval(relogio.current);
  }, []);

  const gerar = async () => {
    if (!titulo.trim()) {
      setFalha("Escreva o título do banner.");
      return;
    }
    if (foto === "produto" && !produtoId) {
      setFalha("Escolha o produto da foto.");
      return;
    }
    if (foto === "enviada" && !enviada) {
      setFalha("Envie a foto (ou escolha outra opção).");
      return;
    }
    setFalha("");
    setPronto(null);
    setGerando(true);
    setSegundos(0);
    relogio.current = window.setInterval(() => setSegundos((s) => s + 1), 1000);
    try {
      const resposta = await fetch("/api/loja/editor/banner", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({
          titulo,
          subtitulo,
          botao,
          selo,
          modelo,
          largura,
          altura,
          produto_id: foto === "produto" ? produtoId : undefined,
          imagem: foto === "enviada" ? enviada : undefined,
          usar_logo: usarLogo,
          cores: { fundo, texto, destaque },
        }),
      });
      const corpo = (await resposta.json().catch(() => ({}))) as { url?: string; error?: string };
      if (!resposta.ok || !corpo.url) throw new Error(corpo.error || "Não deu para gerar o banner agora. Tente de novo em instantes.");
      setPronto(corpo.url);
    } catch (erro) {
      setFalha(erro instanceof Error && erro.message !== "Failed to fetch" ? erro.message : "Sem conexão com o painel. Confira a internet e tente de novo.");
    } finally {
      if (relogio.current) window.clearInterval(relogio.current);
      relogio.current = null;
      setGerando(false);
    }
  };

  const rotulo = (texto: string) => <span className="mb-1.5 block text-[11px] font-bold uppercase tracking-[0.12em] text-[var(--ks-color-text-soft)]">{texto}</span>;

  return (
    <div className="fixed inset-0 z-[95] flex items-end justify-center sm:items-center" role="dialog" aria-modal="true" aria-label="Gerar banner com IA" data-editor="gerador">
      <button type="button" aria-label="Fechar" className="absolute inset-0 bg-[rgba(12,8,24,0.5)]" onClick={() => (gerando ? null : aoFechar())} />
      <div className="relative flex max-h-[92dvh] w-full max-w-[520px] flex-col overflow-hidden rounded-t-[26px] bg-[var(--ks-color-bg-elevated)] shadow-[var(--ks-shadow-overlay)] sm:rounded-[24px]">
        <div className="flex items-center gap-3 border-b border-[var(--ks-n-100)] px-5 py-4">
          <span className="flex h-9 w-9 items-center justify-center rounded-xl text-white" style={{ background: "linear-gradient(135deg,#7346e8,#5228bd)" }}>
            <Sparkles size={17} />
          </span>
          <div className="min-w-0 flex-1">
            <p className="text-[15px] font-extrabold text-[var(--ks-color-text-primary)]">Gerar banner</p>
            <p className="text-[11.5px] text-[var(--ks-color-text-soft)]">
              {largura} × {altura} px, no formato desta imagem · cores, fonte e logo da loja
            </p>
          </div>
          <button type="button" aria-label="Fechar" disabled={gerando} onClick={aoFechar} className="flex h-8 w-8 items-center justify-center rounded-lg text-[var(--ks-color-text-soft)] hover:bg-[var(--ks-color-bg-hover)] disabled:opacity-40">
            <X size={17} />
          </button>
        </div>

        <div className="min-h-0 flex-1 space-y-4 overflow-y-auto px-5 py-4">
          {pronto ? (
            <div>
              {rotulo("Pronto")}
              {/* eslint-disable-next-line @next/next/no-img-element */}
              <img src={pronto} alt="Banner gerado" className="w-full rounded-xl ring-1 ring-black/5" style={{ aspectRatio: `${largura} / ${altura}` }} />
              <p className="mt-2 text-[11.5px] text-[var(--ks-color-text-soft)]">Gostou? Use no campo. Para mudar, ajuste o texto, o modelo ou as cores embaixo e gere de novo.</p>
            </div>
          ) : null}

          <div>
            {rotulo("Texto")}
            <div className="space-y-2">
              <Texto valor={titulo} aoMudar={setTitulo} placeholder="Título (3 a 6 palavras vendem mais)" max={60} rotulo="Título do banner" />
              <Texto valor={subtitulo} aoMudar={setSubtitulo} placeholder="Frase de apoio (opcional)" max={120} rotulo="Subtítulo" />
              <div className="grid grid-cols-2 gap-2">
                <Texto valor={botao} aoMudar={setBotao} placeholder="Botão (ex.: Peça já)" max={24} rotulo="Texto do botão" />
                <Texto valor={selo} aoMudar={setSelo} placeholder="Selo (ex.: -20%)" max={16} rotulo="Selo" />
              </div>
            </div>
          </div>

          <div>
            {rotulo("Modelo")}
            <div className="grid grid-cols-2 gap-1.5 sm:grid-cols-3">
              {MODELOS.map((nome) => (
                <button
                  key={nome}
                  type="button"
                  aria-pressed={modelo === nome}
                  onClick={() => setModelo(nome)}
                  className={`rounded-xl border px-2.5 py-2 text-left text-[12px] font-bold transition ${
                    modelo === nome
                      ? "border-[var(--ks-color-primary)] bg-[var(--ks-brand-50)] text-[var(--ks-color-primary)]"
                      : "border-[var(--ks-color-border-subtle)] text-[var(--ks-color-text-secondary)] hover:border-[var(--ks-brand-300)]"
                  }`}
                >
                  {NOME_DO_MODELO[nome] || nome}
                </button>
              ))}
            </div>
          </div>

          <div>
            {rotulo("Foto")}
            <Segmentos<Foto>
              rotulo="Foto do banner"
              valor={foto}
              aoMudar={setFoto}
              opcoes={[
                { valor: "nenhuma", rotulo: "Sem foto" },
                { valor: "produto", rotulo: "De um produto" },
                { valor: "enviada", rotulo: "Enviar" },
              ]}
            />
            {foto === "produto" ? (
              <div className="mt-2">
                <Escolha
                  valor={produtoId}
                  itens={(painel?.produtos || []).filter((p) => p.image_url)}
                  aoEscolher={(p) => setProdutoId(p.id)}
                  textoDoItem={(p) => p.name}
                  fotoDoItem={(p) => p.image_url}
                  placeholder="Escolher o produto"
                  vazio="Nenhum produto com foto."
                />
              </div>
            ) : foto === "enviada" ? (
              <div className="mt-2 w-44">
                <CampoDeImagem valor={enviada} aoMudar={setEnviada} proporcao={1} largura={1200} altura={1200} dica="A foto que entra no banner." />
              </div>
            ) : null}
          </div>

          <div>
            {rotulo("Cores")}
            <div className="grid grid-cols-1 gap-2.5">
              <ColorField label="Fundo" value={fundo} onChange={setFundo} description="Começa com a cor da loja." />
              <details className="rounded-xl bg-[var(--ks-color-bg-inset)] px-3 py-2">
                <summary className="cursor-pointer text-[12px] font-semibold text-[var(--ks-color-text-secondary)]">Texto e destaque (automático)</summary>
                <div className="mt-2 grid gap-2.5">
                  <ColorField label="Texto" value={texto} onChange={setTexto} description="Automático: o que se lê melhor no fundo." />
                  <ColorField label="Botão e selo" value={destaque} onChange={setDestaque} description="Automático: contrasta com o fundo." />
                </div>
              </details>
            </div>
          </div>

          <label className="flex items-center justify-between gap-3">
            <span className="text-[12.5px] font-semibold text-[var(--ks-color-text-primary)]">Pôr o logo da loja</span>
            <Switch checked={usarLogo} onCheckedChange={setUsarLogo} aria-label="Pôr o logo da loja" />
          </label>

          {falha ? <p className="rounded-xl bg-[#fde8ec] px-3 py-2.5 text-[12.5px] font-semibold text-[#9f1239]">{falha}</p> : null}
        </div>

        <div className="flex items-center gap-2 border-t border-[var(--ks-n-100)] px-5 py-3.5">
          {gerando ? (
            <span className="flex flex-1 items-center gap-2 text-[12.5px] font-semibold text-[var(--ks-color-text-secondary)]">
              <Loader2 size={16} className="animate-spin text-[var(--ks-color-primary)]" />
              {segundos < 4 ? "Abrindo o gerador…" : segundos < 12 ? "Montando o banner com as cores da loja…" : "Quase pronto…"} {segundos}s
            </span>
          ) : (
            <span className="flex-1" />
          )}
          {pronto && !gerando ? (
            <>
              <button type="button" onClick={gerar} className="ks-button ks-button-ghost ks-button-sm">
                <RefreshCw size={14} /> Gerar de novo
              </button>
              <button type="button" onClick={() => aoUsar(pronto)} className="ks-button ks-button-primary ks-button-sm">
                <Check size={14} strokeWidth={3} /> Usar este banner
              </button>
            </>
          ) : (
            <button type="button" onClick={gerar} disabled={gerando} className="ks-button ks-button-primary ks-button-sm disabled:opacity-50">
              <Sparkles size={14} /> {gerando ? "Gerando" : "Gerar banner"}
            </button>
          )}
        </div>
      </div>
    </div>
  );
}
