import { Check } from 'lucide-preact';
import { COPY } from './copy.js';

/**
 * Los puntos de progreso verticales del borde derecho (skill progressive-survey):
 * aparecen al llegar a cada paso, se pueden elegir para volver, y distinguen
 * actual / completo / requiere atención. Son la forma principal de volver atrás:
 * no hay botones Anterior/Siguiente fijos.
 *
 * El estado nunca va solo por color: el completo lleva un check, el que pide
 * atención un «!», el actual un anillo; y cada punto dice su estado en
 * `aria-label` y en el rótulo que aparece al pasar el mouse o enfocarlo.
 * Con el teclado, las flechas arriba/abajo recorren los puntos.
 *
 * @param {{
 *   steps: import('./steps.js').VisibleStep[],
 *   activeId: string,
 *   labelOf: (step: import('./steps.js').VisibleStep) => string,
 *   onSelect: (id: string) => void,
 * }} props
 */
export default function ProgressDots({ steps, activeId, labelOf, onSelect }) {
  const revealed = steps.filter((step) => step.revealed);

  /** @param {KeyboardEvent} event */
  const onKeyDown = (event) => {
    if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') return;
    const buttons = [
      .../** @type {HTMLElement} */ (event.currentTarget).querySelectorAll('button'),
    ];
    const index = buttons.indexOf(/** @type {HTMLButtonElement} */ (document.activeElement));
    if (index === -1) return;
    event.preventDefault();
    const next = event.key === 'ArrowDown' ? index + 1 : index - 1;
    buttons[(next + buttons.length) % buttons.length]?.focus();
  };

  return (
    <nav aria-label={COPY.section.stepsNav} class="flex max-h-full items-center">
      <ol
        class="flex max-h-full flex-col items-center gap-2.5 overflow-y-auto py-2"
        onKeyDown={onKeyDown}
      >
        {revealed.map((step) => {
          const current = step.id === activeId;
          const state = current
            ? COPY.steps.current
            : step.attention
              ? COPY.steps.attention
              : step.complete
                ? COPY.steps.complete
                : '';
          const label = `${labelOf(step)}${state ? ` — ${state}` : ''}`;

          return (
            <li key={step.id} class="flex">
              <button
                type="button"
                onClick={() => onSelect(step.id)}
                aria-label={label}
                aria-current={current ? 'step' : undefined}
                class="group relative flex size-6 cursor-pointer items-center justify-center rounded-full transition focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand-light motion-reduce:transition-none starting:scale-0 starting:opacity-0"
              >
                <Dot current={current} attention={step.attention} complete={step.complete} />
                <span
                  aria-hidden="true"
                  class="pointer-events-none absolute right-full mr-2 hidden rounded-md border border-line bg-deep-3 px-2.5 py-1 text-xs whitespace-nowrap text-fg opacity-0 shadow-lg transition group-hover:opacity-100 group-focus-visible:opacity-100 lg:block"
                >
                  {label}
                </span>
              </button>
            </li>
          );
        })}
      </ol>
    </nav>
  );
}

/**
 * @param {{ current: boolean, attention: boolean, complete: boolean }} props
 */
function Dot({ current, attention, complete }) {
  if (attention) {
    return (
      <span class="flex size-4 items-center justify-center rounded-full bg-red-500 text-[0.6rem] leading-none font-bold text-white ring-2 ring-red-500/30">
        !
      </span>
    );
  }
  if (current) {
    return <span class="size-3.5 rounded-full bg-brand ring-4 ring-brand/25" />;
  }
  if (complete) {
    return (
      <span class="flex size-4 items-center justify-center rounded-full bg-brand-light/80 text-surface">
        <Check class="size-2.5" strokeWidth={4} />
      </span>
    );
  }
  return <span class="size-3 rounded-full border-2 border-muted-2" />;
}
