"use client";

import { useEffect, useState } from "react";
import type { ComponentType, CSSProperties } from "react";

export type InfoStripMobileItem = {
  title: string;
  subtitle: string;
  Icon: ComponentType<{ size?: number; className?: string; style?: CSSProperties }>;
};

const INTERVALO_MS = 4500;

/**
 * A faixa de vantagens no celular, um item por vez.
 *
 * Empilhar os tres itens custava 158px de altura e virava uma lista chapada
 * logo abaixo do header colorido. Lado a lado, cada um ficava com um terco da
 * tela e o texto era cortado no meio de uma palavra.
 *
 * Mostrando um de cada vez o texto tem a largura inteira, nada e abreviado, e a
 * faixa cabe em ~60px.
 *
 * Os itens ficam todos empilhados na mesma celula de grid, e so a opacidade
 * muda. Isso importa: numa primeira versao o texto saia, esperava, e o proximo
 * entrava — o cartao aparecia vazio por um quarto de segundo a cada volta. Com
 * a pilha, um entra enquanto o outro sai e nunca existe quadro em branco. O
 * grid tambem deixa o item mais alto definir a altura, sem numero fixo que
 * cortaria um titulo mais longo.
 *
 * O rodizio para quando o visitante toca (ele assume o controle pelos pontos) e
 * nao comeca se o aparelho pedir menos animacao, porque conteudo que se move
 * sozinho sem pausa atrapalha quem le devagar.
 */
export default function CatalogInfoStripMobile({
  items,
  accentColor,
  tintColor,
  borderColor,
}: {
  items: InfoStripMobileItem[];
  accentColor: string;
  tintColor: string;
  borderColor: string;
}) {
  const [indiceAtivo, setIndiceAtivo] = useState(0);
  /* Le a preferencia ja na inicializacao, e nao dentro de um efeito: setState
     sincrono em efeito dispara render em cascata. O valor nao entra no HTML,
     so liga ou desliga o intervalo, entao nao ha divergencia de hidratacao. */
  const [autoRodizio, setAutoRodizio] = useState(() => {
    if (typeof window === "undefined") return true;
    return !window.matchMedia("(prefers-reduced-motion: reduce)").matches;
  });

  useEffect(() => {
    const semAnimacao = window.matchMedia("(prefers-reduced-motion: reduce)");
    const aoMudar = (evento: MediaQueryListEvent) => setAutoRodizio(!evento.matches);
    semAnimacao.addEventListener("change", aoMudar);
    return () => semAnimacao.removeEventListener("change", aoMudar);
  }, []);

  useEffect(() => {
    if (!autoRodizio || items.length < 2) return;
    const intervalo = window.setInterval(() => {
      setIndiceAtivo((atual) => (atual + 1) % items.length);
    }, INTERVALO_MS);
    return () => window.clearInterval(intervalo);
  }, [autoRodizio, items.length]);

  if (items.length === 0) return null;

  return (
    <div
      className="md:hidden flex items-center gap-3 rounded-2xl border px-3.5 py-3"
      style={{ backgroundColor: "#FFFFFF", borderColor }}
    >
      <span
        className="grid h-9 w-9 shrink-0 place-items-center rounded-full"
        style={{ backgroundColor: tintColor, color: accentColor }}
      >
        {items.map((item, indice) => {
          const { Icon } = item;
          const ativo = indice === indiceAtivo;
          return (
            <span
              key={`icone-${item.title}-${indice}`}
              aria-hidden
              className="col-start-1 row-start-1 transition-all duration-500 ease-out"
              style={{ opacity: ativo ? 1 : 0, transform: ativo ? "scale(1)" : "scale(0.8)" }}
            >
              <Icon size={16} />
            </span>
          );
        })}
      </span>

      <span className="grid min-w-0 flex-1" aria-live="polite">
        {items.map((item, indice) => {
          const ativo = indice === indiceAtivo;
          return (
            <span
              key={`texto-${item.title}-${indice}`}
              aria-hidden={!ativo}
              className="col-start-1 row-start-1 transition-all duration-500 ease-out"
              style={{
                opacity: ativo ? 1 : 0,
                transform: ativo ? "translateY(0)" : "translateY(5px)",
              }}
            >
              <span className="block text-[13px] font-semibold leading-snug text-zinc-900">
                {item.title}
              </span>
              {item.subtitle ? (
                <span className="block text-[11.5px] leading-snug text-zinc-500">{item.subtitle}</span>
              ) : null}
            </span>
          );
        })}
      </span>

      {items.length > 1 ? (
        <span className="flex shrink-0 items-center gap-1.5">
          {items.map((item, indice) => {
            const ativo = indice === indiceAtivo;
            return (
              <button
                key={`ponto-${item.title}-${indice}`}
                type="button"
                onClick={() => {
                  setAutoRodizio(false);
                  setIndiceAtivo(indice);
                }}
                aria-label={`Ver: ${item.title}`}
                aria-current={ativo}
                /* Alvo de toque de 24px de altura com o ponto de 5px desenhado
                   dentro: um ponto de 5px sozinho nao se acerta com o dedo. */
                className="flex h-6 w-3 items-center justify-center"
              >
                <span
                  className="block rounded-full transition-all duration-500 ease-out"
                  style={{
                    width: ativo ? 14 : 5,
                    height: 5,
                    backgroundColor: ativo ? accentColor : "#E4E4E7",
                  }}
                />
              </button>
            );
          })}
        </span>
      ) : null}
    </div>
  );
}
