"use client";

import { useEffect, useRef, type RefObject } from "react";

/*
  Dois ganchos de comportamento dos blocos da home da Boutique (só lógica de
  tela; o desenho fica em cada bloco):

  - useArrastoComMouse: o trilho horizontal anda arrastando com o mouse, como
    na referência (cursor de "mão"). No dedo quem rola é o próprio navegador.
    Um arrasto de verdade não vira clique no card que estava embaixo.
  - useJanela: a janela por cima da página (player de vídeo, "shop the look"):
    trava a rolagem do fundo, fecha com Esc, prende o Tab dentro dela e
    devolve o foco a quem a abriu.
*/

export function useArrastoComMouse(trilho: RefObject<HTMLElement | null>) {
  const estado = useRef<{ x: number; inicio: number; moveu: boolean } | null>(null);

  useEffect(() => {
    const caixa = trilho.current;
    if (!caixa) return;

    const aoMover = (e: PointerEvent) => {
      const atual = estado.current;
      if (!atual) return;
      const dx = e.clientX - atual.x;
      if (!atual.moveu && Math.abs(dx) > 5) {
        atual.moveu = true;
        caixa.setAttribute("data-arrastando", "");
      }
      if (atual.moveu) caixa.scrollLeft = atual.inicio - dx;
    };
    const aoSoltar = () => {
      const atual = estado.current;
      window.removeEventListener("pointermove", aoMover);
      window.removeEventListener("pointerup", aoSoltar);
      caixa.removeAttribute("data-arrastando");
      /* O clique que vem logo depois do arrasto é engolido (aoClicar). */
      window.setTimeout(() => {
        if (estado.current === atual) estado.current = null;
      }, 0);
    };
    const aoApertar = (e: PointerEvent) => {
      if (e.pointerType !== "mouse" || e.button !== 0) return;
      estado.current = { x: e.clientX, inicio: caixa.scrollLeft, moveu: false };
      window.addEventListener("pointermove", aoMover);
      window.addEventListener("pointerup", aoSoltar);
    };
    const aoClicar = (e: MouseEvent) => {
      if (estado.current?.moveu) {
        e.preventDefault();
        e.stopPropagation();
        estado.current = null;
      }
    };
    /* Imagem e vídeo arrastáveis pelo navegador brigariam com o trilho. */
    const aoComecarArrasto = (e: DragEvent) => e.preventDefault();

    caixa.addEventListener("pointerdown", aoApertar);
    caixa.addEventListener("click", aoClicar, true);
    caixa.addEventListener("dragstart", aoComecarArrasto);
    return () => {
      caixa.removeEventListener("pointerdown", aoApertar);
      caixa.removeEventListener("click", aoClicar, true);
      caixa.removeEventListener("dragstart", aoComecarArrasto);
      window.removeEventListener("pointermove", aoMover);
      window.removeEventListener("pointerup", aoSoltar);
    };
  }, [trilho]);
}

const FOCAVEIS = 'a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"]), video[controls]';

export function useJanela(
  aberta: boolean,
  aoFechar: () => void,
  caixa: RefObject<HTMLElement | null>,
  primeiroFoco?: RefObject<HTMLElement | null>
) {
  const fechar = useRef(aoFechar);
  useEffect(() => {
    fechar.current = aoFechar;
  }, [aoFechar]);

  useEffect(() => {
    if (!aberta) return;
    const quemAbriu = document.activeElement as HTMLElement | null;
    const html = document.documentElement;
    const antes = { html: html.style.overflow, body: document.body.style.overflow };
    html.style.overflow = "hidden";
    document.body.style.overflow = "hidden";
    const foco = window.setTimeout(() => (primeiroFoco?.current || caixa.current)?.focus({ preventScroll: true }), 30);

    const aoTeclar = (e: KeyboardEvent) => {
      if (e.key === "Escape") {
        e.preventDefault();
        fechar.current();
        return;
      }
      if (e.key !== "Tab" || !caixa.current) return;
      const lista = Array.from(caixa.current.querySelectorAll<HTMLElement>(FOCAVEIS)).filter((el) => el.offsetParent !== null);
      if (!lista.length) return;
      const primeiro = lista[0];
      const ultimo = lista[lista.length - 1];
      if (e.shiftKey && document.activeElement === primeiro) {
        e.preventDefault();
        ultimo.focus();
      } else if (!e.shiftKey && document.activeElement === ultimo) {
        e.preventDefault();
        primeiro.focus();
      } else if (!caixa.current.contains(document.activeElement)) {
        e.preventDefault();
        primeiro.focus();
      }
    };
    document.addEventListener("keydown", aoTeclar);
    return () => {
      window.clearTimeout(foco);
      document.removeEventListener("keydown", aoTeclar);
      html.style.overflow = antes.html;
      document.body.style.overflow = antes.body;
      if (quemAbriu && document.contains(quemAbriu)) quemAbriu.focus({ preventScroll: true });
    };
  }, [aberta, caixa, primeiroFoco]);
}
