'use client';

import {
  type ReactNode,
  createContext,
  useCallback,
  useContext,
  useEffect,
  useId,
  useMemo,
  useRef,
  useState,
} from 'react';

import { useTranslations } from 'next-intl';

import { Maximize2, Minimize2, X } from 'lucide-react';
import { createPortal } from 'react-dom';

import YouTubeVideo from '@/components/YoutubeVideo';
import { Text } from '@/components/ui/typography';
import { cn } from '@/lib/utils';

/**
 * VideoModalPlayer stays separate from the shared Modal because the video iframe
 * must remain mounted while switching between the large modal view and the docked
 * mini player. The common Modal would unmount its content on close, which would
 * stop playback instead of letting visitors keep listening while browsing.
 */
type VideoPlayerMode = 'closed' | 'modal' | 'mini';

interface VideoPlayerOpenOptions {
  videoId: string;
  title: string;
}

interface ActiveVideo extends VideoPlayerOpenOptions {
  requestId: number;
}

interface VideoPlayerContextValue {
  openVideo: (video: VideoPlayerOpenOptions) => void;
  closeVideo: () => void;
}

interface VideoModalPlayerProps {
  videoId: string;
  title: string;
  onClose: () => void;
}

const FOCUSABLE_SELECTOR =
  'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';

const VideoPlayerContext = createContext<VideoPlayerContextValue | null>(null);

export function VideoPlayerProvider({ children }: { children: ReactNode }) {
  const [activeVideo, setActiveVideo] = useState<ActiveVideo | null>(null);

  const openVideo = useCallback((video: VideoPlayerOpenOptions) => {
    setActiveVideo((current) => ({
      ...video,
      requestId: (current?.requestId ?? 0) + 1,
    }));
  }, []);

  const closeVideo = useCallback(() => {
    setActiveVideo(null);
  }, []);

  const contextValue = useMemo(
    () => ({
      openVideo,
      closeVideo,
    }),
    [closeVideo, openVideo]
  );

  return (
    <VideoPlayerContext.Provider value={contextValue}>
      {children}
      {activeVideo && (
        <VideoModalPlayer
          key={activeVideo.requestId}
          videoId={activeVideo.videoId}
          title={activeVideo.title}
          onClose={closeVideo}
        />
      )}
    </VideoPlayerContext.Provider>
  );
}

export function useVideoPlayer() {
  const context = useContext(VideoPlayerContext);

  if (!context) {
    throw new Error('useVideoPlayer must be used within VideoPlayerProvider');
  }

  return context;
}

function VideoModalPlayer({ videoId, title, onClose }: VideoModalPlayerProps) {
  const [mode, setMode] = useState<VideoPlayerMode>('modal');
  const contentRef = useRef<HTMLDivElement>(null);
  const titleId = useId();
  const tAccessibility = useTranslations('accessibility');

  const handleClose = useCallback(() => {
    setMode('closed');
    onClose();
  }, [onClose]);

  const isModal = mode === 'modal';
  const isMini = mode === 'mini';
  const controlButtonClassName = cn(
    'flex items-center justify-center rounded-full bg-white/10 text-white transition hover:bg-white/25 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/80',
    isMini ? 'h-7 w-7 sm:h-8 sm:w-8' : 'h-9 w-9'
  );

  useEffect(() => {
    if (!isModal) return;

    const previouslyFocused = document.activeElement as HTMLElement | null;
    const originalOverflow = document.body.style.overflow;
    const originalPaddingRight = document.body.style.paddingRight;
    const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;

    document.body.style.overflow = 'hidden';
    if (scrollbarWidth > 0) {
      document.body.style.paddingRight = `${scrollbarWidth}px`;
    }

    const content = contentRef.current;
    const firstFocusable = content?.querySelector<HTMLElement>(FOCUSABLE_SELECTOR);
    (firstFocusable || content)?.focus();

    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === 'Escape') {
        handleClose();
        return;
      }

      if (event.key !== 'Tab' || !content) return;

      const focusable = Array.from(
        content.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)
      ).filter((element) => element.offsetParent !== null);

      if (focusable.length === 0) {
        event.preventDefault();
        content.focus();
        return;
      }

      const first = focusable[0];
      const last = focusable[focusable.length - 1];
      const active = document.activeElement;

      if (event.shiftKey && (active === first || active === content)) {
        event.preventDefault();
        last.focus();
      } else if (!event.shiftKey && active === last) {
        event.preventDefault();
        first.focus();
      }
    };

    window.addEventListener('keydown', handleKeyDown);

    return () => {
      document.body.style.overflow = originalOverflow;
      document.body.style.paddingRight = originalPaddingRight;
      window.removeEventListener('keydown', handleKeyDown);
      previouslyFocused?.focus?.();
    };
  }, [handleClose, isModal]);

  if (typeof document === 'undefined' || mode === 'closed') return null;

  const player = (
    <div
      className={cn(
        'flex w-full flex-col overflow-hidden bg-black text-white shadow-2xl outline-none',
        isModal ? 'max-h-[95vh] max-w-[960px] rounded-lg' : 'relative rounded-lg border border-white/15'
      )}
    >
      <div
        className={cn(
          'flex items-center justify-between bg-[#151720]',
          isMini
            ? 'absolute inset-x-0 top-0 z-10 h-8 min-h-0 gap-2 bg-black/55 px-2 py-1 backdrop-blur-sm sm:relative sm:h-auto sm:min-h-10 sm:bg-[#151720] sm:backdrop-blur-none'
            : 'min-h-12 gap-3 px-3 py-2'
        )}
      >
        <Text
          id={isModal ? titleId : undefined}
          as="div"
          variant="bodySm"
          tone="inverseMuted"
          className={cn('line-clamp-1 min-w-0 font-semibold', isMini && 'text-[11px] sm:text-xs')}
        >
          {title}
        </Text>
        <div
          className={cn('flex flex-shrink-0 items-center', isMini ? 'gap-1 sm:gap-1.5' : 'gap-1.5')}
        >
          {isModal ? (
            <button
              type="button"
              onClick={() => setMode('mini')}
              aria-label={tAccessibility('minimizeVideo')}
              className={controlButtonClassName}
            >
              <Minimize2 className="h-4 w-4" aria-hidden="true" />
            </button>
          ) : (
            <button
              type="button"
              onClick={() => setMode('modal')}
              aria-label={tAccessibility('restoreVideo')}
              className={controlButtonClassName}
            >
              <Maximize2 className={isMini ? 'h-3.5 w-3.5' : 'h-4 w-4'} aria-hidden="true" />
            </button>
          )}
          <button
            type="button"
            onClick={handleClose}
            aria-label={tAccessibility('closeVideo')}
            className={controlButtonClassName}
          >
            <X className={isMini ? 'h-4 w-4' : 'h-5 w-5'} aria-hidden="true" />
          </button>
        </div>
      </div>

      <div className="relative aspect-video w-full bg-black">
        <YouTubeVideo id={videoId} title={title} autoplay />
      </div>
    </div>
  );

  return createPortal(
    <div
      ref={contentRef}
      tabIndex={isModal ? -1 : undefined}
      role={isModal ? 'dialog' : 'region'}
      aria-modal={isModal ? true : undefined}
      aria-labelledby={isModal ? titleId : undefined}
      aria-label={isMini ? tAccessibility('miniVideoPlayer') : undefined}
      className={cn(
        isModal
          ? 'fixed inset-0 z-[1000] flex items-center justify-center bg-black/80 p-4 backdrop-blur-md'
          : 'fixed bottom-5 right-4 z-[1000] w-[clamp(168px,52vw,190px)] max-w-[calc(100vw-2rem)] sm:bottom-6 sm:right-6 sm:w-[380px]'
      )}
      onClick={(event) => {
        if (isModal && event.target === event.currentTarget) {
          handleClose();
        }
      }}
    >
      {player}
    </div>,
    document.body
  );
}
