// @design-system: domain/HeroCarousel

/**
 * HeroCarousel - auto-playing full-width featured carousel for desktop hero areas.
 *
 * Features:
 * - Auto-advances every `interval` ms (default 4000).
 * - Pauses when the browser tab is hidden (visibility API).
 * - `prefers-reduced-motion`: no auto-advance, no CSS transition.
 * - WCAG 2.2.2: pause/play button always visible (not hover-only).
 * - RTL-aware slide transform (inverted direction for Hebrew).
 * - Two modes: `deals` (shows PriceDisplay + CountdownTimer overlay) /
 *              `gallery` (shows vendor/deal name only).
 *
 * @example
 * <HeroCarousel slides={featuredDeals.slice(0, 5)} mode="deals" />
 */

'use client';

import { useCallback, useEffect, useRef, useState } from 'react';
import { usePrefersReducedMotion } from '@/lib/hooks/useHydrated';
import { cn } from '@/lib/cn';
import { Image } from '@/components/ui/primitives/Image';
import { PriceDisplay } from '../PriceDisplay';
import { CountdownTimer } from '../CountdownTimer';
import { useT } from '@/lib/i18n/react';
import { useLocale } from '@/lib/i18n/react';
import { dirForLocale } from '@/lib/i18n';
import type { DealCardDeal } from '../DealCard';

export interface HeroCarouselSlide {
  id: string;
  /** Deal data - required in 'deals' mode, optional in 'gallery' mode. */
  deal?: DealCardDeal;
  /** Absolute image URL. */
  imageSrc: string;
  /** Descriptive alt text for the slide image. */
  imageAlt: string;
  /** Optional overlay label (used in gallery mode). */
  label?: string;
  /** Focal point for object-position. Default 0.5 each. */
  focalX?: number;
  focalY?: number;
}

export interface HeroCarouselProps {
  slides: HeroCarouselSlide[];
  /**
   * - `deals`: shows PriceDisplay + CountdownTimer overlay on each slide.
   * - `gallery`: shows a simple label overlay (e.g. vendor/business name).
   * @default 'deals'
   */
  mode?: 'deals' | 'gallery';
  /** Auto-advance interval in ms. Set to Infinity to disable. @default 4000 */
  interval?: number;
  /** Called when a slide is activated (click or Enter). */
  onSelectDeal?: (id: string) => void;
  className?: string;
}

export function HeroCarousel({
  slides,
  mode = 'deals',
  interval = 4000,
  onSelectDeal,
  className,
}: HeroCarouselProps) {
  const t = useT('hero_carousel');
  const { locale } = useLocale();
  const isRTL = dirForLocale(locale) === 'rtl';

  const [activeIndex, setActiveIndex] = useState(0);
  const [isPaused, setIsPaused] = useState(false);
  const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);

  // Detect prefers-reduced-motion
  const prefersReducedMotion = usePrefersReducedMotion();

  const goToSlide = useCallback(
    (index: number) => {
      setActiveIndex(((index % slides.length) + slides.length) % slides.length);
    },
    [slides.length],
  );

  const goNext = useCallback(() => {
    goToSlide(activeIndex + 1);
  }, [activeIndex, goToSlide]);

  const goPrev = useCallback(() => {
    goToSlide(activeIndex - 1);
  }, [activeIndex, goToSlide]);

  const handleKeyDown = useCallback(
    (e: React.KeyboardEvent<HTMLDivElement>) => {
      switch (e.key) {
        case 'ArrowRight':
          e.preventDefault();
          if (isRTL) {
            goPrev();
          } else {
            goNext();
          }
          break;
        case 'ArrowLeft':
          e.preventDefault();
          if (isRTL) {
            goNext();
          } else {
            goPrev();
          }
          break;
        case 'Home':
          e.preventDefault();
          goToSlide(0);
          break;
        case 'End':
          e.preventDefault();
          goToSlide(slides.length - 1);
          break;
      }
    },
    [isRTL, goNext, goPrev, goToSlide, slides.length],
  );

  // Auto-play
  useEffect(() => {
    if (slides.length <= 1 || isPaused || prefersReducedMotion || interval === Infinity) return;

    const startAutoPlay = () => {
      intervalRef.current = setInterval(goNext, interval);
    };

    const stopAutoPlay = () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
        intervalRef.current = null;
      }
    };

    const handleVisibilityChange = () => {
      if (document.visibilityState === 'hidden') {
        stopAutoPlay();
      } else {
        stopAutoPlay();
        startAutoPlay();
      }
    };

    startAutoPlay();
    document.addEventListener('visibilitychange', handleVisibilityChange);

    return () => {
      stopAutoPlay();
      document.removeEventListener('visibilitychange', handleVisibilityChange);
    };
  }, [goNext, interval, isPaused, prefersReducedMotion, slides.length]);

  if (slides.length === 0) return null;

  const translateX = isRTL ? `calc(${activeIndex} * 100%)` : `calc(-${activeIndex} * 100%)`;

  return (
    <div role="region" aria-label={t('label')}>
      {/* Keyboard-navigable carousel container. tabIndex required by ARIA APG carousel pattern;
        jsx-a11y doesn't model this keyboard-focusable region exemption. */}
      <div
        aria-roledescription="carousel"
        role="button"
        aria-label={t('label')}
        tabIndex={0}
        onKeyDown={handleKeyDown}
        className={cn('relative h-full w-full overflow-hidden', className)}
      >
        {/* Slide track */}
        <div
          className="flex h-full"
          style={{
            transform: `translateX(${translateX})`,
            transition: prefersReducedMotion
              ? 'none'
              : 'transform var(--duration-slow) var(--ease-emphasized)',
          }}
          aria-live="polite"
          aria-atomic="false"
        >
          {slides.map((slide, index) => {
            const isActive = index === activeIndex;
            return (
              <button
                key={slide.id}
                type="button"
                aria-label={slide.deal?.title ?? slide.label ?? slide.imageAlt}
                aria-current={isActive ? 'true' : undefined}
                aria-hidden={!isActive}
                tabIndex={isActive ? 0 : -1}
                onClick={() => {
                  if (slide.deal && onSelectDeal) onSelectDeal(slide.deal.id);
                  else if (slide.deal)
                    window.location.href = slide.deal.heSlug
                      ? `/deals/${slide.deal.heSlug}`
                      : '/deals';
                }}
                className={cn(
                  'relative h-full w-full shrink-0',
                  'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-white',
                )}
              >
                {/* Slide image */}
                <Image
                  src={slide.imageSrc}
                  alt={slide.imageAlt}
                  loading="eager"
                  fetchpriority="high"
                  className="absolute inset-0 h-full w-full object-cover"
                  sizes="100vw"
                  style={{
                    objectPosition: `${(slide.focalX ?? 0.5) * 100}% ${(slide.focalY ?? 0.5) * 100}%`,
                  }}
                />

                {/* Gradient overlay for readability */}
                <div
                  className="absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent"
                  aria-hidden="true"
                />

                {/* Content overlay */}
                <div
                  className={cn(
                    'absolute inset-x-0 bottom-0',
                    'px-8 py-6',
                    'bg-glass-bg-light backdrop-blur-[var(--glass-blur-sm)]',
                    'border-glass-border-white border-t',
                  )}
                >
                  {mode === 'deals' && slide.deal ? (
                    <div className="flex items-end justify-between gap-4">
                      <div className="text-start">
                        <p className="text-text-muted mb-1 text-xs font-medium">
                          {slide.deal.vendorName} · {slide.deal.city}
                        </p>
                        <p className="text-text-primary text-xl leading-[var(--line-height-tight)] font-bold">
                          {slide.deal.title}
                        </p>
                      </div>
                      <div className="flex shrink-0 flex-col items-end gap-2">
                        <PriceDisplay
                          original={slide.deal.originalPrice}
                          discounted={slide.deal.discountedPrice}
                          layout="stacked"
                          size="lg"
                        />
                        {slide.deal.windowEnd && <CountdownTimer endIso={slide.deal.windowEnd} />}
                      </div>
                    </div>
                  ) : (
                    <p className="text-text-primary text-lg font-bold">
                      {slide.label ?? slide.imageAlt}
                    </p>
                  )}
                </div>
              </button>
            );
          })}
        </div>

        {/* Dot indicators */}
        {slides.length > 1 && (
          <div
            className="absolute inset-x-0 bottom-4 mx-auto flex w-fit gap-2"
            aria-label={t('slide_n_of_total')
              .replace('{n}', String(activeIndex + 1))
              .replace('{total}', String(slides.length))}
          >
            {slides.map((slide, index) => (
              <button
                key={slide.id}
                type="button"
                aria-label={t('go_to_slide_n').replace('{n}', String(index + 1))}
                aria-current={index === activeIndex ? 'true' : undefined}
                onClick={() => goToSlide(index)}
                className={cn(
                  'rounded-full transition-all duration-[var(--duration-fast)]',
                  'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white',
                  index === activeIndex
                    ? 'h-[var(--spacing-2)] w-[var(--spacing-6)] bg-white'
                    : 'size-[var(--spacing-2)] bg-white/50 hover:bg-white/75',
                )}
              />
            ))}
          </div>
        )}

        {/* Pause / play toggle - always visible for WCAG 2.2.2 */}
        {slides.length > 1 && !prefersReducedMotion && (
          <button
            type="button"
            aria-label={isPaused ? t('play') : t('pause')}
            onClick={() => setIsPaused((p) => !p)}
            className={cn(
              'absolute end-[var(--spacing-4)] bottom-4',
              'flex items-center justify-center',
              'size-[var(--spacing-8)] rounded-full',
              'bg-glass-bg-medium backdrop-blur-[var(--glass-blur-sm)]',
              'border-glass-border-white border',
              'text-white',
              'transition-colors duration-[var(--duration-fast)]',
              'hover:bg-glass-bg-light',
              'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white',
            )}
          >
            {isPaused ? (
              /* Play icon - two vertical bars */
              <svg
                width="16"
                height="16"
                viewBox="0 0 16 16"
                fill="currentColor"
                aria-hidden="true"
              >
                <polygon points="4,2 13,8 4,14" />
              </svg>
            ) : (
              /* Pause icon - triangle pointing right */
              <svg
                width="16"
                height="16"
                viewBox="0 0 16 16"
                fill="currentColor"
                aria-hidden="true"
              >
                <rect x="3" y="2" width="4" height="12" rx="1" />
                <rect x="9" y="2" width="4" height="12" rx="1" />
              </svg>
            )}
          </button>
        )}
      </div>
    </div>
  );
}
