'use client';

import { useEffect, useRef, useState } from 'react';
import { useTranslations } from 'next-intl';
import { Timer } from 'lucide-react';

import { cn } from '@/lib/utils';
import { useUnmountSafeTimeout } from '@/components/ui/useUnmountSafeTimeout';

export interface FlashSaleCountdownProps {
  /** ISO 8601 UTC end timestamp. */
  endsAt: string;
  /** Fires once when the countdown first reaches zero. */
  onExpire?: () => void;
  size?: 'sm' | 'md' | 'lg';
  className?: string;
}

type Remaining = { days: number; hours: number; minutes: number; seconds: number; total: number };

function computeRemaining(endsAtMs: number): Remaining {
  const total = Math.max(0, endsAtMs - Date.now());
  const seconds = Math.floor((total / 1000) % 60);
  const minutes = Math.floor((total / (1000 * 60)) % 60);
  const hours = Math.floor((total / (1000 * 60 * 60)) % 24);
  const days = Math.floor(total / (1000 * 60 * 60 * 24));
  return { days, hours, minutes, seconds, total };
}

const SIZE_CLASSES: Record<NonNullable<FlashSaleCountdownProps['size']>, string> = {
  sm: 'text-xs gap-1',
  md: 'text-sm gap-1.5',
  lg: 'text-base gap-2',
};

/**
 * Feature 054 — US11 (C4). Reusable live countdown for active promotions.
 * Ticks every second through the unmount-safe scheduler so it never leaks a timer.
 */
export function FlashSaleCountdown({ endsAt, onExpire, size = 'md', className }: FlashSaleCountdownProps) {
  const t = useTranslations('offers.countdown');
  const schedule = useUnmountSafeTimeout();
  const endsAtMs = new Date(endsAt).getTime();
  const [remaining, setRemaining] = useState<Remaining>(() => computeRemaining(endsAtMs));
  const expiredRef = useRef(false);

  useEffect(() => {
    expiredRef.current = false;
    setRemaining(computeRemaining(endsAtMs));

    let cancel: (() => void) | undefined;
    const tick = () => {
      const next = computeRemaining(endsAtMs);
      setRemaining(next);
      if (next.total <= 0) {
        if (!expiredRef.current) {
          expiredRef.current = true;
          onExpire?.();
        }
        return;
      }
      cancel = schedule(tick, 1000);
    };
    cancel = schedule(tick, 1000);
    return () => cancel?.();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [endsAt]);

  const ended = remaining.total <= 0;

  return (
    <div
      role="timer"
      aria-live="polite"
      aria-atomic="true"
      className={cn('inline-flex items-center font-medium tabular-nums', SIZE_CLASSES[size], className)}
    >
      <Timer aria-hidden="true" className="h-4 w-4 shrink-0" />
      {ended ? (
        <span>{t('ended')}</span>
      ) : (
        <span className="inline-flex items-center gap-1">
          <span className="text-neutral-500">{t('ends_in')}</span>
          {remaining.days > 0 && <span>{t('days', { count: remaining.days })}</span>}
          <span>{t('hours', { count: remaining.hours })}</span>
          <span>{t('minutes', { count: remaining.minutes })}</span>
          <span>{t('seconds', { count: remaining.seconds })}</span>
        </span>
      )}
    </div>
  );
}
