// @design-system: feedback/LoadingOverlay
// Registered at /design-system#loadingoverlay-feedback
'use client';

import { Spinner } from '@/components/ui/feedback/Spinner';
import { useT } from '@/lib/i18n/react';
import { useLoadingOverlayStore } from '@/lib/store/loadingOverlayStore';
import { cn } from '@/lib/cn';

export interface LoadingOverlayProps {
  /** When true, renders a controlled overlay regardless of the global store. */
  open?: boolean;
  /** Override label. Defaults to the active store label, then i18n `common.loading_overlay_label`. */
  label?: string;
  className?: string;
}

/**
 * LoadingOverlay — full-viewport blocking spinner shown during long async work.
 *
 * Multideal hard rule: spinners never render inline inside buttons. Always show as
 * a full-screen overlay layer above the page. Mounted once inside `HydratedIsland`
 * and driven by `useLoadingOverlayStore`; any island can call `show()` / `hide()`.
 *
 * a11y: `role="status"` + `aria-live="polite"` so screen readers announce the label
 * when the overlay appears. Inert content underneath (pointer-events: auto on the
 * backdrop blocks clicks).
 *
 * Tokens-only styling: backdrop uses `bg-overlay-scrim` (scrim token), spinner uses
 * brand-primary via `<Spinner variant="bounce" />`.
 */
export function LoadingOverlay({ open, label, className }: LoadingOverlayProps) {
  const t = useT('common');
  const storeCount = useLoadingOverlayStore((s) => s.count);
  const storeLabel = useLoadingOverlayStore((s) => s.label);

  const isOpen = open ?? storeCount > 0;
  if (!isOpen) return null;

  const resolvedLabel = label ?? storeLabel ?? t('loading_overlay_label');

  return (
    <div
      role="status"
      aria-live="polite"
      aria-busy="true"
      aria-label={resolvedLabel}
      className={cn(
        'fixed inset-0 z-50 flex flex-col items-center justify-center gap-4',
        'bg-surface-base/70 backdrop-blur-sm',
        className,
      )}
      data-testid="loading-overlay"
    >
      <div aria-hidden="true">
        <Spinner variant="bounce" size="md" label={resolvedLabel} />
      </div>
      <span className="text-text-primary text-sm font-medium">{resolvedLabel}</span>
    </div>
  );
}
