// @design-system: domain/CountdownTimer

'use client';

import { Fragment, useEffect, useRef } from 'react';
import { cn } from '@/lib/cn';
import { useT, useLocale } from '@/lib/i18n/react';
import { Spinner } from '@/components/ui/feedback/Spinner';
import { formatCountdownSeconds, type CountdownStage } from '@/lib/countdown';
import { useCountdown } from '@/lib/hooks/useCountdown';

/** Props for CountdownTimer */
export interface CountdownTimerProps {
  /** ISO 8601 end datetime string. */
  endIso: string;
  /** Called once when the timer reaches zero. */
  onExpire?: () => void;
  /** Additional class names. */
  className?: string;
}

const stagePillClass: Record<CountdownStage, string> = {
  cool: 'bg-brand-primary-700',
  warm: 'bg-danger-500',
  hot: 'bg-danger-600',
  expired: 'bg-danger-600',
};

function getLocalCountdownStage(secondsLeft: number): CountdownStage {
  if (secondsLeft <= 0) return 'expired';
  if (secondsLeft <= 600) return 'hot';
  if (secondsLeft <= 3600) return 'warm';
  return 'cool';
}

function formatClockText(totalSeconds: number): string {
  const clampedSeconds = Math.max(0, totalSeconds);
  const totalMinutes = Math.floor(clampedSeconds / 60);
  const seconds = clampedSeconds % 60;
  return `${String(totalMinutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
}

/**
 * CountdownTimer — pill badge timer with animated dot.
 *
 * Three urgency stages (FDS 4.2):
 * - Cool   (> 1h):           brand-primary-700 · shows days+hours or hours+minutes
 * - Warm   (≤ 1h, > 10min):  danger-500        · shows MM:SS
 * - Hot    (≤ 10min):        danger-600 + pulse · shows MM:SS
 *
 * Adaptive tick rate: 60 s when ≥ 1 h remaining, 1 s otherwise.
 * Respects `prefers-reduced-motion`.
 *
 * @example
 * ```tsx
 * <CountdownTimer endIso={deal.windowEnd} onExpire={() => setExpired(true)} />
 * ```
 */
export function CountdownTimer({ endIso, onExpire, className }: CountdownTimerProps) {
  const secondsLeft = useCountdown(endIso);
  const expiredRef = useRef(false);
  const t = useT('time');
  const { locale } = useLocale();

  useEffect(() => {
    expiredRef.current = false;
  }, [endIso]);

  useEffect(() => {
    if (secondsLeft === null) return;
    if (secondsLeft <= 0 && !expiredRef.current) {
      expiredRef.current = true;
      onExpire?.();
    }
  }, [secondsLeft, onExpire]);

  const stage = secondsLeft === null ? null : getLocalCountdownStage(secondsLeft);
  const labels = {
    days: t('days'),
    hours: t('hours'),
    minutes: t('minutes'),
    seconds: t('seconds'),
  };
  const countdown =
    secondsLeft === null
      ? null
      : stage === 'warm' || stage === 'hot'
        ? { text: formatClockText(secondsLeft), hasWords: false }
        : formatCountdownSeconds(secondsLeft, labels);

  if (secondsLeft === null) {
    return (
      <span
        aria-hidden="true"
        className={cn(
          'inline-flex items-center gap-2.5',
          'rounded-full px-4 py-2.5',
          stagePillClass['cool'],
          className,
        )}
      >
        <Spinner variant="inline" size="sm" />
      </span>
    );
  }

  const resolvedStage = stage as CountdownStage;
  const resolvedCountdown = countdown as NonNullable<typeof countdown>;

  const stageLabel: Partial<Record<CountdownStage, string>> = {
    warm: t('urgency_warm'),
    hot: t('urgency_urgent'),
  };

  return (
    <span role="status" aria-live="polite" className="contents">
      {/*
        Keyframe animations injected once per render.
        motion-safe variants in Tailwind guard these from applying
        when prefers-reduced-motion: reduce is set.
      */}
      <style>{`
        @keyframes md-dot-pulse {
          50% { opacity: 0.45; transform: scale(1.15); }
        }
        @keyframes md-countdown-breathe {
          0%, 100% { filter: brightness(1); opacity: 1; }
          50% { filter: brightness(1.08); opacity: 0.92; }
        }
        @keyframes md-countdown-digit-flip {
          0% { transform: rotateX(0deg); opacity: 1; }
          45% { transform: rotateX(-90deg); opacity: 0.35; }
          100% { transform: rotateX(0deg); opacity: 1; }
        }
      `}</style>
      {/* Visually-hidden announcement for screen readers; keyed to stage so it
          re-mounts and re-announces on every transition (cool→warm→hot). */}
      {stageLabel[resolvedStage] && (
        <span key={stage} className="sr-only">
          {stageLabel[resolvedStage]}
        </span>
      )}
      <time
        dateTime={endIso}
        data-testid="countdown"
        data-stage={resolvedStage}
        className={cn(
          'inline-flex items-center gap-2.5',
          'rounded-full px-4 py-2.5',
          'text-lg font-bold text-white',
          resolvedCountdown.hasWords
            ? locale === 'he'
              ? 'font-[family-name:var(--font-he)]'
              : 'font-[family-name:var(--font-en)]'
            : 'tracking-countdown-numeric font-[family-name:var(--font-en)] tabular-nums',
          stagePillClass[resolvedStage],
          resolvedStage === 'hot' &&
            'origin-center motion-safe:[animation:md-countdown-breathe_var(--motion-duration-countdown-breathe)_ease-in-out_infinite]',
          className,
        )}
      >
        <span
          aria-hidden="true"
          className="size-2 shrink-0 rounded-full bg-white/85 motion-safe:[animation:md-dot-pulse_var(--motion-duration-countdown-dot-pulse)_ease-in-out_infinite]"
        />
        <span
          className={cn(
            !resolvedCountdown.hasWords && 'inline-block min-w-[6ch] text-center',
            !resolvedCountdown.hasWords && 'tracking-countdown-numeric tabular-nums',
            resolvedStage === 'hot' && 'motion-safe:[perspective:12rem]',
          )}
        >
          {resolvedStage === 'hot' ? (
            <>
              <span className="sr-only">{resolvedCountdown.text}</span>
              <span key={resolvedCountdown.text} aria-hidden="true" className="inline-flex">
                {resolvedCountdown.text.split('').map((char, index) => (
                  <span
                    key={`${index}-${char}`}
                    data-countdown-char={/\d/.test(char) ? 'digit' : 'separator'}
                    className={cn(
                      'inline-flex justify-center',
                      char === ':' ? 'w-[0.55ch]' : 'w-[1ch]',
                      /\d/.test(char) &&
                        'origin-center motion-safe:[animation:md-countdown-digit-flip_var(--motion-duration-countdown-digit-flip)_cubic-bezier(0.22,1,0.36,1)]',
                    )}
                  >
                    {char}
                  </span>
                ))}
              </span>
            </>
          ) : (
            <Fragment>{resolvedCountdown.text}</Fragment>
          )}
        </span>
      </time>
    </span>
  );
}
