import { useRef, type KeyboardEvent } from 'react';

export interface TabItem<T extends string> {
  id: T;
  label: string;
}

export interface TabsProps<T extends string> {
  items: Array<TabItem<T>>;
  activeId: T;
  onChange: (id: T) => void;
  ariaLabel: string;
}

export function Tabs<T extends string>({
  items,
  activeId,
  onChange,
  ariaLabel,
}: TabsProps<T>) {
  const refs = useRef<Array<HTMLButtonElement | null>>([]);

  function moveFocus(currentId: T, direction: 1 | -1) {
    const currentIndex = items.findIndex((item) => item.id === currentId);
    const nextIndex = (currentIndex + direction + items.length) % items.length;
    const next = items[nextIndex];
    if (!next) return;
    onChange(next.id);
    window.requestAnimationFrame(() => refs.current[nextIndex]?.focus());
  }

  function handleKeyDown(event: KeyboardEvent<HTMLButtonElement>, id: T) {
    if (event.key === 'ArrowRight') {
      event.preventDefault();
      moveFocus(id, 1);
    } else if (event.key === 'ArrowLeft') {
      event.preventDefault();
      moveFocus(id, -1);
    } else if (event.key === 'Home') {
      event.preventDefault();
      const first = items[0];
      if (!first) return;
      onChange(first.id);
      window.requestAnimationFrame(() => refs.current[0]?.focus());
    } else if (event.key === 'End') {
      event.preventDefault();
      const last = items[items.length - 1];
      if (!last) return;
      onChange(last.id);
      window.requestAnimationFrame(() => refs.current[items.length - 1]?.focus());
    }
  }

  return (
    <div className="ui-tabs" role="tablist" aria-label={ariaLabel}>
      {items.map((item, index) => {
        const active = item.id === activeId;
        return (
          <button
            type="button"
            role="tab"
            id={`tab-${item.id}`}
            aria-controls={`panel-${item.id}`}
            aria-selected={active}
            tabIndex={active ? 0 : -1}
            className={`ui-tab ${active ? 'is-active' : ''}`.trim()}
            key={item.id}
            ref={(node) => {
              refs.current[index] = node;
            }}
            onClick={() => onChange(item.id)}
            onKeyDown={(event) => handleKeyDown(event, item.id)}
          >
            {item.label}
          </button>
        );
      })}
    </div>
  );
}

