"use client";

import { useEffect, useMemo, useState } from "react";
import { Check, ChevronRight, Copy, Flame, Percent, Tag } from "lucide-react";

/*
  A faixa de aviso do topo — a mesma que o lojista já configura no catálogo.

  Não é um slogan fixo: é a promessa do dia com relógio correndo, o cupom que
  o cliente copia com um toque e o botão que leva à oferta. É a barra que o
  Padrão e o Vitrine mostram, com os mesmos campos e as mesmas cores.

  O código é do Vendor — nada aqui é importado dos outros templates nem
  exportado para eles. O que se repete é a configuração, não o arquivo.

  O texto aceita **negrito** entre asteriscos, para o lojista destacar o
  número sem precisar de um campo separado.

  Quem decide se a faixa acompanha a rolagem é o shell: fixa, ela entra dentro
  do cabeçalho grudado; solta, entra acima dele e sobe junto com a página.
*/

export type VendorCupomDoAviso = {
  code?: string | null;
  type?: string | null;
  value?: number | null;
};

function corValida(valor: string | null | undefined, padrao: string) {
  const bruto = String(valor || "").trim();
  const hex = bruto.startsWith("#") ? bruto.slice(1) : bruto;
  if (/^[0-9a-f]{6}$/i.test(hex)) return `#${hex.toLowerCase()}`;
  if (/^[0-9a-f]{3}$/i.test(hex)) {
    return `#${hex
      .toLowerCase()
      .split("")
      .map((c) => c + c)
      .join("")}`;
  }
  return padrao;
}

function textoSobre(cor: string) {
  const hex = cor.replace("#", "");
  const r = parseInt(hex.slice(0, 2), 16);
  const g = parseInt(hex.slice(2, 4), 16);
  const b = parseInt(hex.slice(4, 6), 16);
  const luz = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
  return luz > 0.62 ? "#111827" : "#ffffff";
}

function comAlfa(cor: string, alfa: number) {
  const hex = cor.replace("#", "");
  const r = parseInt(hex.slice(0, 2), 16);
  const g = parseInt(hex.slice(2, 4), 16);
  const b = parseInt(hex.slice(4, 6), 16);
  return `rgba(${r}, ${g}, ${b}, ${alfa})`;
}

function comDestaque(texto: string) {
  return texto
    .split(/(\*\*[^*]+\*\*)/g)
    .filter(Boolean)
    .map((parte, indice) =>
      parte.startsWith("**") && parte.endsWith("**") ? (
        <strong key={`forte-${indice}`} className="font-extrabold">
          {parte.slice(2, -2)}
        </strong>
      ) : (
        <span key={`normal-${indice}`}>{parte}</span>
      )
    );
}

function fraseDoCupom(cupom: VendorCupomDoAviso | null | undefined) {
  if (!cupom?.code) return "";
  if (cupom.type === "free_shipping") return `Use o cupom ${cupom.code} e ganhe frete grátis`;
  if (cupom.type === "percent") return `Use o cupom ${cupom.code} e ganhe ${Number(cupom.value || 0)}% OFF`;
  return `Use o cupom ${cupom.code} e ganhe R$ ${Number(cupom.value || 0).toFixed(2)} OFF`;
}

/* O botão pode apontar para um produto ou categoria do próprio catálogo. */
function enderecoDoBotao(url: string | null | undefined, slug: string) {
  const bruto = String(url || "").trim();
  if (!bruto) return "";
  const produto = bruto.match(/^catalog:\/\/product\/([^/?#]+)/i);
  if (produto?.[1]) return `/${slug}/p/${decodeURIComponent(produto[1])}`;
  const categoria = bruto.match(/^catalog:\/\/(?:category|subcategory)\/([^/?#]+)/i);
  if (categoria?.[1]) return `/${slug}/c/${decodeURIComponent(categoria[1])}`;
  return bruto;
}

function pedacosDaContagem(fim: string, agora: number) {
  const alvo = new Date(fim).getTime();
  if (!Number.isFinite(alvo) || agora <= 0) {
    return [
      { rotulo: "D", valor: "00" },
      { rotulo: "H", valor: "00" },
      { rotulo: "M", valor: "00" },
      { rotulo: "S", valor: "00" },
    ];
  }
  const segundos = Math.floor(Math.max(0, alvo - agora) / 1000);
  const doisDigitos = (n: number) => String(n).padStart(2, "0");
  return [
    { rotulo: "D", valor: doisDigitos(Math.floor(segundos / 86400)) },
    { rotulo: "H", valor: doisDigitos(Math.floor((segundos % 86400) / 3600)) },
    { rotulo: "M", valor: doisDigitos(Math.floor((segundos % 3600) / 60)) },
    { rotulo: "S", valor: doisDigitos(segundos % 60) },
  ];
}

export function VendorAviso({
  slug,
  ligado,
  texto,
  corDeFundo,
  corDoTexto,
  botaoRotulo,
  botaoUrl,
  cupom,
  mostrarSelo,
  corDoSelo,
  contagemLigada,
  contagemAte,
}: {
  slug: string;
  ligado?: boolean | null;
  texto?: string | null;
  corDeFundo?: string | null;
  corDoTexto?: string | null;
  botaoRotulo?: string | null;
  botaoUrl?: string | null;
  cupom?: VendorCupomDoAviso | null;
  mostrarSelo?: boolean | null;
  corDoSelo?: string | null;
  contagemLigada?: boolean | null;
  contagemAte?: string | null;
}) {
  const [agora, setAgora] = useState(0);
  const [copiado, setCopiado] = useState(false);
  const [marqueeParado, setMarqueeParado] = useState(false);

  const temContagem = Boolean(contagemLigada && contagemAte);

  /* O relógio só anda quando existe contagem para mostrar. E começa fora da
     primeira renderização: o servidor não tem a mesma hora do navegador. */
  useEffect(() => {
    if (!temContagem) return;
    const marcar = () => setAgora(Date.now());
    const primeiro = window.setTimeout(marcar, 0);
    const relogio = window.setInterval(marcar, 1000);
    return () => {
      window.clearTimeout(primeiro);
      window.clearInterval(relogio);
    };
  }, [temContagem]);

  useEffect(() => {
    if (!copiado) return;
    const volta = window.setTimeout(() => setCopiado(false), 2000);
    return () => window.clearTimeout(volta);
  }, [copiado]);

  /* O texto volta a correr sozinho depois que a pessoa larga o cupom. */
  useEffect(() => {
    if (!marqueeParado) return;
    const volta = window.setTimeout(() => setMarqueeParado(false), 6000);
    return () => window.clearTimeout(volta);
  }, [marqueeParado]);

  const fundo = corValida(corDeFundo, "#111827");
  const frente = corValida(corDoTexto, "#ffffff");
  const fundoDoSelo = corValida(corDoSelo, "#fb7185");
  const frenteDoSelo = textoSobre(fundoDoSelo);
  const bordaDoSelo = comAlfa(frenteDoSelo, 0.45);
  const apagado = comAlfa(frente, 0.65);
  const veu = comAlfa(frente, 0.15);

  const frase = String(texto || "").trim();
  const temCupom = Boolean(cupom?.code);
  const fraseDoDesconto = temCupom ? fraseDoCupom(cupom) : "";
  const selo = Boolean(mostrarSelo !== false && temCupom);
  const contagem = useMemo(
    () => (temContagem ? pedacosDaContagem(String(contagemAte || ""), agora) : []),
    [temContagem, contagemAte, agora]
  );
  const endereco = enderecoDoBotao(botaoUrl, slug);
  const botao = Boolean(String(botaoRotulo || "").trim() && endereco);

  const temConteudo = Boolean(frase || fraseDoDesconto || selo || temContagem || botao);
  if (!ligado || !temConteudo) return null;

  const copiarCupom = async () => {
    const codigo = String(cupom?.code || "");
    if (!codigo || typeof navigator === "undefined" || !navigator.clipboard) return;
    setMarqueeParado(true);
    try {
      await navigator.clipboard.writeText(codigo);
      setCopiado(true);
    } catch {
      /* Sem permissão de área de transferência o código continua à vista,
         que é o que o cliente precisa para digitar. */
    }
  };

  const textoCorrido = (
    <span className="flex min-w-0 flex-col">
      <span className="text-[14px] font-bold leading-tight">{frase ? comDestaque(frase) : "Oferta especial!"}</span>
      {fraseDoDesconto ? (
        <span className="mt-0.5 text-[11px] font-medium leading-tight opacity-90">{fraseDoDesconto}</span>
      ) : null}
    </span>
  );

  return (
    <div className="relative overflow-hidden" style={{ backgroundColor: fundo, color: frente }}>
      {/* A marca d água só entra quando há desconto: é o que ela anuncia. */}
      {temCupom ? (
        <div className="pointer-events-none absolute inset-0 flex items-center justify-center overflow-hidden opacity-10">
          <Percent size={140} className="rotate-12" />
        </div>
      ) : null}

      <div className="relative z-10 mx-auto w-full max-w-6xl px-3 py-1.5 sm:px-5">
        {/* desktop — tudo numa linha centralizada */}
        <div className="hidden min-w-0 items-center justify-center gap-2.5 text-center md:flex">
          {frase ? <span className="text-sm font-medium leading-tight">{comDestaque(frase)}</span> : null}

          {fraseDoDesconto ? (
            <>
              {frase ? (
                <span className="text-sm" style={{ color: apagado }}>
                  •
                </span>
              ) : null}
              <span className="text-sm font-semibold">{fraseDoDesconto}</span>
            </>
          ) : null}

          {selo ? (
            <>
              <span className="text-sm" style={{ color: apagado }}>
                •
              </span>
              <button
                type="button"
                onClick={copiarCupom}
                onMouseEnter={() => setMarqueeParado(true)}
                className="relative inline-flex items-center gap-1.5 rounded-md border-2 border-dashed px-2.5 py-1 text-[11px] font-extrabold tracking-wide"
                style={{ backgroundColor: fundoDoSelo, color: frenteDoSelo, borderColor: bordaDoSelo }}
              >
                <span>{cupom?.code}</span>
                <span className="inline-flex h-3.5 w-px" style={{ backgroundColor: bordaDoSelo }} />
                {copiado ? <Check size={12} /> : <Copy size={12} />}
              </button>
            </>
          ) : null}

          {temContagem ? (
            <div className="ml-2 inline-flex shrink-0 items-center gap-1" suppressHydrationWarning>
              {contagem.map((parte) => (
                <span key={parte.rotulo} className="inline-flex items-center gap-0.5">
                  <span
                    className="inline-flex h-8 w-8 items-center justify-center rounded-md border text-[12px] font-bold tabular-nums"
                    style={{ borderColor: comAlfa(frente, 0.45), backgroundColor: veu }}
                  >
                    {parte.valor}
                  </span>
                  <span
                    className="text-[9px] font-semibold uppercase tracking-wide"
                    style={{ color: comAlfa(frente, 0.8) }}
                  >
                    {parte.rotulo}
                  </span>
                </span>
              ))}
            </div>
          ) : null}

          {botao ? (
            <a
              href={endereco}
              className="ml-2 shrink-0 rounded-full border px-4 py-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors"
              style={{ borderColor: comAlfa(frente, 0.3), backgroundColor: veu }}
            >
              {String(botaoRotulo || "").trim()}
            </a>
          ) : null}
        </div>

        {/* celular — o texto corre, o cupom e o botão ficam parados embaixo */}
        <div className="flex w-full flex-col gap-2 py-0.5 md:hidden">
          <div className="flex w-full items-center gap-2.5">
            {temCupom ? (
              <span
                className="flex h-7 w-7 shrink-0 items-center justify-center rounded-full text-yellow-300"
                style={{ backgroundColor: veu }}
              >
                <Flame size={14} className="fill-yellow-400" />
              </span>
            ) : null}

            <div
              className="relative min-w-0 flex-1 overflow-hidden"
              style={{ WebkitMaskImage: "linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent)" }}
            >
              <div
                className={`vd-aviso-trilho ${marqueeParado ? "" : "vd-aviso-correndo"}`}
                style={{ animationPlayState: marqueeParado ? "paused" : "running" }}
              >
                <span className="inline-flex items-center whitespace-nowrap pr-8">{textoCorrido}</span>
                <span className="inline-flex items-center whitespace-nowrap pr-8">{textoCorrido}</span>
              </div>
            </div>

            {temContagem ? (
              <div className="inline-flex shrink-0 items-center gap-1" suppressHydrationWarning>
                {contagem.map((parte) => (
                  <div key={parte.rotulo} className="flex flex-col items-center">
                    <span
                      className="inline-flex h-[26px] w-[26px] items-center justify-center rounded-[4px] border text-[11px] font-bold tabular-nums"
                      style={{ borderColor: comAlfa(frente, 0.2), backgroundColor: "rgba(0,0,0,0.2)" }}
                    >
                      {parte.valor}
                    </span>
                    <span className="mt-0.5 text-[7px] font-bold uppercase opacity-80">{parte.rotulo}</span>
                  </div>
                ))}
              </div>
            ) : null}
          </div>

          {selo || botao ? (
            <div className="mt-0.5 flex w-full items-center justify-between gap-2">
              {selo ? (
                <button
                  type="button"
                  onClick={copiarCupom}
                  onTouchStart={() => setMarqueeParado(true)}
                  className="relative flex shrink-0 items-center overflow-hidden rounded-md border-2 border-dashed p-1 transition-transform active:scale-[0.97]"
                  style={{
                    backgroundColor: fundoDoSelo,
                    color: frenteDoSelo,
                    borderColor: bordaDoSelo,
                    boxShadow: `0 4px 12px ${comAlfa(fundoDoSelo, 0.2)}`,
                  }}
                >
                  <span className="z-10 flex min-w-0 items-center gap-1.5 px-1.5">
                    <Tag size={12} className="shrink-0 opacity-80" />
                    <span className="truncate text-[12px] font-extrabold tracking-widest">{cupom?.code}</span>
                  </span>
                  <span
                    className="z-10 ml-1.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-[4px]"
                    style={{ backgroundColor: "rgba(0,0,0,0.1)" }}
                  >
                    {copiado ? <Check size={12} /> : <Copy size={12} />}
                  </span>
                </button>
              ) : (
                <span className="flex-1" />
              )}

              {botao ? (
                <a
                  href={endereco}
                  className="ml-auto inline-flex shrink-0 items-center gap-1 rounded-full border px-3.5 py-1.5 text-[9px] font-bold uppercase tracking-wide"
                  style={{ borderColor: comAlfa(frente, 0.2), backgroundColor: veu }}
                >
                  <span className="relative z-10">{String(botaoRotulo || "Ver ofertas").trim()}</span>
                  <ChevronRight size={12} className="relative z-10" />
                </a>
              ) : null}
            </div>
          ) : null}
        </div>
      </div>
    </div>
  );
}
