"use client";

import Link from "next/link";
import { usePathname, useRouter } from "next/navigation";
import { Download, LogIn, PlayCircle } from "lucide-react";
import ClientPortalFavoriteButton from "@/components/ClientPortalFavoriteButton";
import { useVisaoDaLoja } from "@/components/VisaoDaLojaContext";
import { trackCatalogEvent } from "@/lib/catalog-analytics";
import { moedaDoVendor } from "./formato";
import { useMemo } from "react";

/*
  O card de produto do Vendor.

  Regra de ouro do bloco: `h-full flex flex-col` no card, `flex-1` no corpo e
  `mt-auto` no rodapé. É isso que faz todos os cards da fileira terminarem na
  mesma altura, com o botão alinhado — sem isso a grade fica com degraus.

  O título reserva duas linhas (`min-h-[2.6rem]`) mesmo quando tem uma só,
  senão o grid pula quando os nomes têm comprimentos diferentes.

  O preço obedece às regras da loja (lib/loja/regras-da-loja.ts): o produto
  chega aqui já sem preço quando o visitante não pode ver, e o card só
  escreve o texto que a loja escolheu no lugar dele. Quando o preço é só
  para quem entrou, esse lugar vira o caminho do login.
*/

/* Para onde o login manda de volta: a página em que o cliente estava. */
function enderecoDoLogin(slug: string, caminho: string | null) {
  return `/${slug}/cliente/login?next=${encodeURIComponent(caminho || `/${slug}`)}`;
}

/* "Sob consulta" cabe em letra grande; "Entre para ver o preço" não — o card
   estreito do celular quebraria em três linhas. */
function classeDoTextoSemPreco(texto: string, grande: boolean) {
  const longo = texto.length > 14;
  if (grande) return longo ? "text-sm font-semibold leading-snug sm:text-base" : "text-xl font-bold sm:text-2xl";
  return longo ? "text-[13px] font-semibold leading-snug" : "text-base font-bold";
}

export type VendorProduto = {
  id: string;
  name: string;
  price: number;
  image_url?: string | null;
  price_on_request?: boolean | null;
  unit_type?: string | null;
  product_images?: Array<{ image_url: string; is_primary?: boolean | null; sort_order?: number | null }> | null;
  product_price_tiers?: Array<{
    min_qty: number;
    max_qty: number | null;
    unit_price: number;
    active?: boolean | null;
  }> | null;
  min_sale_qty_enabled?: boolean | null;
  min_sale_qty?: number | null;
  /* "digital": selo no card e preço sem "a partir de" (é um preço só). */
  product_kind?: string | null;
  /* O tipo do digital ("curso" leva o selo "Curso"). */
  digital_tipo?: string | null;
  /* "encomenda" e a data da pré-venda: o card não promete "na hora". */
  digital_entrega?: string | null;
  digital_pre_venda?: string | null;
};

/* "Entrega na hora", "Sob encomenda" ou "Pré-venda" (a data passou: na hora). */
function entregaNoCard(produto: VendorProduto): string {
  const preVenda = produto.digital_pre_venda ? new Date(produto.digital_pre_venda).getTime() : NaN;
  if (Number.isFinite(preVenda) && preVenda > Date.now()) return "Pré-venda";
  if (produto.digital_entrega === "encomenda") return "Sob encomenda";
  return "Entrega na hora";
}

/* O selo do produto digital, sobre a foto. */
function SeloDigital({ curso = false }: { curso?: boolean }) {
  return (
    <span className="pointer-events-none absolute bottom-2 left-2 inline-flex items-center gap-1 rounded-full bg-slate-900/90 px-2 py-0.5 text-[10px] font-semibold text-white shadow-sm">
      {curso ? <PlayCircle className="h-2.5 w-2.5" strokeWidth={2.5} /> : <Download className="h-2.5 w-2.5" strokeWidth={2.5} />}
      {curso ? "Vídeo" : "Digital"}
    </span>
  );
}

export function fotoDoProduto(produto: VendorProduto) {
  const imagens = (produto.product_images || []).filter((img) => img?.image_url);
  const principal = imagens.find((img) => img.is_primary) || imagens[0];
  return principal?.image_url || produto.image_url || null;
}

/* O menor preço que a loja pratica: a menor faixa, se houver, ou o preço
   cheio. É o número que fica embaixo de "a partir de". */
export function precoInicial(produto: VendorProduto) {
  const faixas = (produto.product_price_tiers || []).filter(
    (faixa) => faixa && faixa.active !== false && Number(faixa.unit_price) > 0
  );
  if (!faixas.length) return Number(produto.price) || 0;
  return faixas.reduce(
    (menor, faixa) => Math.min(menor, Number(faixa.unit_price)),
    Number.POSITIVE_INFINITY
  );
}

/* A quantidade a que o preço inicial se refere: sai como "/ 1.000 un." */
export function quantidadeDoPrecoInicial(produto: VendorProduto) {
  const faixas = (produto.product_price_tiers || []).filter(
    (faixa) => faixa && faixa.active !== false && Number(faixa.unit_price) > 0
  );
  if (!faixas.length) {
    return produto.min_sale_qty_enabled && Number(produto.min_sale_qty) > 1
      ? Number(produto.min_sale_qty)
      : null;
  }
  const menor = faixas.reduce((a, b) => (Number(a.unit_price) <= Number(b.unit_price) ? a : b));
  return Number(menor.min_qty) > 1 ? Number(menor.min_qty) : null;
}

export function VendorCardDoProduto({
  produto,
  slug,
  clienteId,
  favoritos,
  corDaMarca,
}: {
  produto: VendorProduto;
  slug: string;
  /* Quem está logado no portal — sem isso o coração manda para o login. */
  clienteId?: string | null;
  favoritos?: string[] | null;
  corDaMarca?: string;
}) {
  const router = useRouter();
  const caminho = usePathname();
  const visao = useVisaoDaLoja();
  const foto = fotoDoProduto(produto);
  /* O clique no produto conta para os relatórios da loja, igual nos outros
     temas. É por este evento que o lojista sabe o que é olhado e não vendido. */
  const contarClique = () => {
    void trackCatalogEvent({ slug, eventName: "product_click", productId: produto.id });
  };
  const preco = useMemo(() => precoInicial(produto), [produto]);
  const quantidade = useMemo(() => quantidadeDoPrecoInicial(produto), [produto]);
  const unidade = produto.unit_type === "square_meter" ? "m²" : "un.";
  /* Sem preço: pelo cadastro ("sob consulta") ou pela regra da loja. Nos dois
     casos o que aparece é o texto da loja, nunca um número. */
  const semPreco = Boolean(produto.price_on_request) || !visao.mostrarPreco;
  const textoSemPreco = visao.textoNoLugarDoPreco;

  return (
    <div
      className="vd-lift group relative flex h-full flex-col border bg-[var(--vd-surface)]"
      style={{ borderColor: "var(--vd-border)", borderRadius: "var(--vd-radius-xl)" }}
    >
      <Link
        href={`/${slug}/p/${produto.id}`}
        onClick={contarClique}
        className="relative block aspect-square overflow-hidden bg-white"
        style={{ borderTopLeftRadius: "var(--vd-radius-xl)", borderTopRightRadius: "var(--vd-radius-xl)" }}
      >
        {foto ? (
          /* eslint-disable-next-line @next/next/no-img-element */
          <img
            src={foto}
            alt={produto.name}
            loading="lazy"
            className="h-full w-full object-cover object-center transition-transform duration-500 group-hover:scale-105"
          />
        ) : (
          <span className="flex h-full w-full items-center justify-center bg-[var(--vd-muted-bg)] text-xs text-[var(--vd-muted-fg)]">
            Sem imagem
          </span>
        )}
        {produto.product_kind === "digital" ? <SeloDigital curso={produto.digital_tipo === "curso"} /> : null}
      </Link>

      {/* O coração fica sobre a foto, como nos outros temas: favoritar é
          decisão de quem está passando o olho, não de quem já abriu. Fora do
          link, para o clique não virar navegação. */}
      <span className="absolute right-2 top-2 z-10">
        <ClientPortalFavoriteButton
          productId={produto.id}
          clientId={clienteId || null}
          initialFavorites={favoritos || null}
          primaryColor={corDaMarca || "#111827"}
          onRequireLogin={() => router.push(`/${slug}/cliente/login`)}
        />
      </span>

      <div className="flex flex-1 flex-col gap-3 p-3 sm:p-4">
        <Link
          href={`/${slug}/p/${produto.id}`}
          onClick={contarClique}
          className="min-h-[2.6rem] text-sm font-semibold leading-snug sm:text-base"
        >
          {produto.name}
        </Link>

        <div className="mt-auto space-y-3">
          <div>
            {semPreco ? (
              visao.precisaEntrar ? (
                /* Preço só para quem entrou: o lugar do preço leva ao login e
                   traz a pessoa de volta para esta página. */
                <Link
                  href={enderecoDoLogin(slug, caminho)}
                  className={`inline-flex items-center gap-1.5 underline-offset-2 hover:underline ${classeDoTextoSemPreco(textoSemPreco, true)}`}
                  style={{ color: "var(--vd-primary)" }}
                >
                  <LogIn className="h-4 w-4 shrink-0" />
                  {textoSemPreco}
                </Link>
              ) : (
                <p className={classeDoTextoSemPreco(textoSemPreco, true)} style={{ color: "var(--vd-primary)" }}>
                  {textoSemPreco}
                </p>
              )
            ) : (
              produto.product_kind === "digital" ? (
                <>
                  <p className="text-[11px] text-[var(--vd-muted-fg)]">{entregaNoCard(produto)}</p>
                  <p className="text-xl font-bold tabular-nums sm:text-2xl" style={{ color: "var(--vd-primary)" }}>
                    {preco > 0 ? moedaDoVendor(preco) : "Grátis"}
                  </p>
                </>
              ) : (
              <>
                <p className="text-[11px] text-[var(--vd-muted-fg)]">a partir de</p>
                <p className="flex flex-wrap items-baseline gap-x-1.5">
                  <span className="text-xl font-bold tabular-nums sm:text-2xl" style={{ color: "var(--vd-primary)" }}>
                    {moedaDoVendor(preco)}
                  </span>
                  {quantidade ? (
                    <span className="text-xs text-[var(--vd-muted-fg)]">
                      / {quantidade.toLocaleString("pt-BR")} {unidade}
                    </span>
                  ) : (
                    <span className="text-xs text-[var(--vd-muted-fg)]">/ {unidade}</span>
                  )}
                </p>
              </>
              )
            )}
          </div>

          <Link
            href={`/${slug}/p/${produto.id}`}
            className="inline-flex h-10 w-full items-center justify-center gap-2 whitespace-nowrap px-2 py-2 text-sm font-medium shadow-sm transition-all duration-200 hover:shadow-md sm:px-4 sm:text-base"
            style={{
              borderRadius: "var(--vd-radius-xl)",
              /* A cor do botão do card é uma escolha à parte na personalização
                 avançada; sem ela, vale a cor da marca. */
              backgroundColor: "var(--vd-card-button, var(--vd-primary))",
              color: "var(--vd-primary-fg)",
            }}
          >
            Ver detalhes
          </Link>
        </div>
      </div>
    </div>
  );
}

/* A variante compacta, usada em "Você também pode gostar": o cartão inteiro é
   o link, sem botão, e o preço é menor. É de propósito que ela não se pareça
   com o card da home — o olho precisa saber que aquilo é sugestão, não a
   vitrine principal. */
export function VendorCardCompacto({
  produto,
  slug,
  clienteId,
  favoritos,
  corDaMarca,
}: {
  produto: VendorProduto;
  slug: string;
  clienteId?: string | null;
  favoritos?: string[] | null;
  corDaMarca?: string;
}) {
  const rota = useRouter();
  const caminho = usePathname();
  const visao = useVisaoDaLoja();
  const foto = fotoDoProduto(produto);
  const preco = precoInicial(produto);
  const quantidade = quantidadeDoPrecoInicial(produto);
  const unidade = produto.unit_type === "square_meter" ? "m²" : "un.";
  const semPreco = Boolean(produto.price_on_request) || !visao.mostrarPreco;
  const textoSemPreco = visao.textoNoLugarDoPreco;

  return (
    <div className="relative">
    <span className="absolute right-2 top-2 z-10">
      <ClientPortalFavoriteButton
        productId={produto.id}
        clientId={clienteId || null}
        initialFavorites={favoritos || null}
        primaryColor={corDaMarca || "#111827"}
        onRequireLogin={() => rota.push(`/${slug}/cliente/login`)}
      />
    </span>
    <Link
      href={`/${slug}/p/${produto.id}`}
      onClick={() => {
        void trackCatalogEvent({ slug, eventName: "product_click", productId: produto.id });
      }}
      className="group flex h-full flex-col overflow-hidden border bg-[var(--vd-surface)] text-left transition-colors"
      style={{ borderColor: "var(--vd-border)", borderRadius: "var(--vd-radius-xl)" }}
    >
      <div className="relative w-full shrink-0 overflow-hidden bg-white" style={{ aspectRatio: "1 / 1" }}>
        {foto ? (
          /* eslint-disable-next-line @next/next/no-img-element */
          <img src={foto} alt={produto.name} loading="lazy" className="h-full w-full object-cover object-center" />
        ) : (
          <span className="flex h-full w-full items-center justify-center bg-[var(--vd-muted-bg)] text-xs text-[var(--vd-muted-fg)]">
            Sem imagem
          </span>
        )}
        {produto.product_kind === "digital" ? <SeloDigital curso={produto.digital_tipo === "curso"} /> : null}
      </div>
      <div className="flex flex-1 flex-col p-3">
        <p className="min-h-[2.5rem] text-sm font-medium leading-snug line-clamp-2">{produto.name}</p>
        <div className="mt-auto pt-1">
          {semPreco ? (
            visao.precisaEntrar ? (
              /* O cartão inteiro já é um link; um segundo link dentro dele
                 não existe em HTML. O lugar do preço faz o papel de link e
                 segura o clique antes que ele vire navegação para o produto. */
              <span
                role="link"
                tabIndex={0}
                onClick={(evento) => {
                  evento.preventDefault();
                  evento.stopPropagation();
                  rota.push(enderecoDoLogin(slug, caminho));
                }}
                onKeyDown={(evento) => {
                  if (evento.key !== "Enter" && evento.key !== " ") return;
                  evento.preventDefault();
                  evento.stopPropagation();
                  rota.push(enderecoDoLogin(slug, caminho));
                }}
                className={`inline-flex items-center gap-1 underline-offset-2 hover:underline ${classeDoTextoSemPreco(textoSemPreco, false)}`}
                style={{ color: "var(--vd-primary)" }}
              >
                <LogIn className="h-3.5 w-3.5 shrink-0" />
                {textoSemPreco}
              </span>
            ) : (
              <p className={classeDoTextoSemPreco(textoSemPreco, false)} style={{ color: "var(--vd-primary)" }}>
                {textoSemPreco}
              </p>
            )
          ) : (
            produto.product_kind === "digital" ? (
              <>
                <p className="text-xs text-[var(--vd-muted-fg)]">{entregaNoCard(produto)}</p>
                <p className="text-base font-bold tabular-nums" style={{ color: "var(--vd-primary)" }}>
                  {preco > 0 ? moedaDoVendor(preco) : "Grátis"}
                </p>
              </>
            ) : (
            <>
              <p className="text-xs text-[var(--vd-muted-fg)]">a partir de</p>
              <p className="flex flex-wrap items-baseline gap-x-1.5">
                <span className="text-base font-bold tabular-nums" style={{ color: "var(--vd-primary)" }}>
                  {moedaDoVendor(preco)}
                </span>
                <span className="text-xs text-[var(--vd-muted-fg)]">
                  / {quantidade ? `${quantidade.toLocaleString("pt-BR")} ${unidade}` : unidade}
                </span>
              </p>
            </>
            )
          )}
        </div>
      </div>
    </Link>
    </div>
  );
}
