"use client";

/*
  A etiqueta do valor mínimo do item no tema padrão e na vitrine (o Vendor tem
  a dele, em templates/vendor). Cor cheia da loja, texto legível em cima, e
  uma "i" que explica a regra:
  - no computador abre ao passar o mouse e também no clique (o clique deixa
    aberta até clicar fora, apertar Esc ou no X);
  - no celular abre no toque e fecha no toque fora ou no X;
  - a caixa vai para o <body> (portal) com posição fixa: nenhum card com
    overflow escondido corta a explicação.
  Nunca mostra quanto o item "daria": isso derruba a venda.
*/
import { useCallback, useEffect, useId, useLayoutEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";
import { Info, X } from "lucide-react";
import { explicacaoDoMinimo, ROTULO_DO_MINIMO, textoDoMinimoDoItem } from "@/lib/adicionais";
import { getReadableTextColor } from "@/lib/color-contrast";

type Props = {
  minimo: number;
  /* Cor de destaque da loja. */
  cor: string;
  /* "produto": "Valor mínimo deste item: R$ 70,00"; "linha": "Valor mínimo do item". */
  modo?: "produto" | "linha";
  className?: string;
};

const LARGURA = 280;
const MARGEM = 12;

export default function ValorMinimoDoItem({ minimo, cor, modo = "produto", className = "" }: Props) {
  const [aberto, setAberto] = useState(false);
  const [preso, setPreso] = useState(false);
  const [posicao, setPosicao] = useState<{ top: number; left: number; acima: boolean } | null>(null);
  const botao = useRef<HTMLButtonElement | null>(null);
  const caixa = useRef<HTMLDivElement | null>(null);
  const id = useId();
  const corDoTexto = getReadableTextColor(cor);

  const posicionar = useCallback(() => {
    const ancora = botao.current?.getBoundingClientRect();
    if (!ancora) return;
    const largura = Math.min(LARGURA, window.innerWidth - MARGEM * 2);
    const left = Math.min(Math.max(MARGEM, ancora.left + ancora.width / 2 - largura / 2), window.innerWidth - largura - MARGEM);
    const altura = caixa.current?.offsetHeight ?? 140;
    const acima = ancora.bottom + 8 + altura > window.innerHeight - MARGEM && ancora.top - 8 - altura > MARGEM;
    setPosicao({ top: acima ? ancora.top - 8 - altura : ancora.bottom + 8, left, acima });
  }, []);

  const fechar = useCallback((devolverFoco = false) => {
    setAberto(false);
    setPreso(false);
    if (devolverFoco) botao.current?.focus();
  }, []);

  useLayoutEffect(() => {
    if (aberto) posicionar();
  }, [aberto, posicionar]);

  useEffect(() => {
    if (!aberto) return;
    const foraDaqui = (evento: PointerEvent) => {
      const alvo = evento.target as Node;
      if (botao.current?.contains(alvo) || caixa.current?.contains(alvo)) return;
      fechar();
    };
    const tecla = (evento: KeyboardEvent) => {
      if (evento.key === "Escape") fechar(true);
    };
    window.addEventListener("pointerdown", foraDaqui);
    window.addEventListener("keydown", tecla);
    window.addEventListener("scroll", posicionar, true);
    window.addEventListener("resize", posicionar);
    return () => {
      window.removeEventListener("pointerdown", foraDaqui);
      window.removeEventListener("keydown", tecla);
      window.removeEventListener("scroll", posicionar, true);
      window.removeEventListener("resize", posicionar);
    };
  }, [aberto, fechar, posicionar]);

  const texto = modo === "produto" ? textoDoMinimoDoItem(minimo) : ROTULO_DO_MINIMO;

  return (
    <span
      className={`inline-flex max-w-full items-center gap-1.5 rounded-full py-1 pl-3 pr-1 text-xs font-bold leading-tight shadow-sm ${className}`}
      style={{ backgroundColor: cor, color: corDoTexto }}
    >
      <span className="min-w-0">{texto}</span>
      <button
        ref={botao}
        type="button"
        aria-label="Como funciona o valor mínimo"
        aria-expanded={aberto}
        aria-controls={aberto ? id : undefined}
        onPointerEnter={(evento) => {
          if (evento.pointerType === "mouse") setAberto(true);
        }}
        onPointerLeave={(evento) => {
          if (evento.pointerType === "mouse" && !preso) setAberto(false);
        }}
        onClick={() => {
          if (preso) fechar();
          else {
            setAberto(true);
            setPreso(true);
          }
        }}
        className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full transition-opacity hover:opacity-80 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-1"
        style={{ backgroundColor: "rgba(255,255,255,0.22)", color: corDoTexto, outlineColor: corDoTexto }}
      >
        <Info size={14} strokeWidth={2.5} />
      </button>
      {aberto && typeof document !== "undefined"
        ? createPortal(
            <div
              ref={caixa}
              id={id}
              role="dialog"
              aria-label="Valor mínimo do item"
              onPointerEnter={() => setAberto(true)}
              onPointerLeave={(evento) => {
                if (evento.pointerType === "mouse" && !preso) setAberto(false);
              }}
              className="fixed z-[2147483000] rounded-2xl bg-zinc-950 p-4 pr-9 text-left text-[13px] font-medium leading-relaxed text-white shadow-2xl"
              style={{
                top: posicao?.top ?? -9999,
                left: posicao?.left ?? -9999,
                width: `min(${LARGURA}px, calc(100vw - ${MARGEM * 2}px))`,
                borderTop: posicao?.acima ? undefined : `4px solid ${cor}`,
                borderBottom: posicao?.acima ? `4px solid ${cor}` : undefined,
              }}
            >
              {explicacaoDoMinimo(minimo)}
              <button
                type="button"
                aria-label="Fechar"
                onClick={() => fechar(true)}
                className="absolute right-2 top-2 inline-flex h-7 w-7 items-center justify-center rounded-full text-white/80 hover:bg-white/10 hover:text-white"
              >
                <X size={15} />
              </button>
            </div>,
            document.body
          )
        : null}
    </span>
  );
}
