import * as React from 'react';
import { FC, useState, useRef, useEffect } from 'react';
import { style } from 'typestyle';
import { useStore } from '../../../../services/store';
import { IMedia } from '../../../../types';
import Controls from '../components/Controls';
import MediaContainer from '../components/MediaContainer';
import ShopThisLookProductList, {
  ShopThisLookProductListHandle,
} from '../../../ShopThisLook/ProductList';
import MediaProgress from '../components/MediaProgress';
import useTapNavigation from '../../../../hooks/useTapNavigation';
import useSwipeNavigation from '../../../../hooks/useSwipeNavigation';
import NextIndicator from '../components/NextIndicator';
import { mobilePlayerPackshotHeightPercent, productListZIndex } from '../../../consts';
import usePlayerNavigation, {
  PLAYER_ANIMATION_DURATION_SEC,
} from '../../../../hooks/usePlayerNavigation';
import useWheelNavigation from '../../../../hooks/useWheelNavigation';
import { useDialogFocusTrap } from '../../../../hooks/useDialogFocusTrap';
import { useAccessibilityMessage } from '../../../../hooks/useAccessibilityMessage';
import { usePlayerKeyboardNavigation } from '../../../../hooks/usePlayerKeyboardNavigation';
import { usePostViewerEvents } from '../../../../hooks/usePostViewerEvents';
import Spinner from '../../../Icons/Spinner';

interface MobilePlayerProps {
  post: IMedia;
  settings: any;
  totalPosts: number;
  onClose: () => void;
  onPostChange: (post: IMedia | null) => void;
  classPrefix: string;
}

const MobilePlayer: FC<MobilePlayerProps> = ({
  post,
  settings,
  totalPosts,
  onClose,
  onPostChange,
  classPrefix,
}) => {
  const store = useStore();
  const { triggerStlToggleEvent } = usePostViewerEvents();
  const [showList, setShowList] = useState(false);
  const containerRef = useRef<HTMLDivElement>(null);
  const productListRef = useRef<ShopThisLookProductListHandle>(null);

  const swipeDirection: 'horizontal' | 'vertical' =
    settings.player_swipe_direction === 'horizontal' ? 'horizontal' : 'vertical';
  const isVertical = swipeDirection === 'vertical';

  const {
    currentDisplayPost,
    nextDisplayPost,
    prevDisplayPost,
    isMuted,
    isPlaying,
    isVisible,
    isClosing,
    showNextIndicator,
    slideOffset,
    isSliding,
    slideAxis,
    handleClose,
    handleNextPost,
    handlePreviousPost,
    toggleMute,
    togglePlay,
  } = usePlayerNavigation({ post, onClose, onPostChange, swipeDirection });

  const { medias } = store.data.content;

  const toggleList = () => {
    const opening = !showList;
    setShowList(opening);
    triggerStlToggleEvent(currentDisplayPost, opening);
  };

  // Focus trap keeps Tab navigation inside the dialog.
  useDialogFocusTrap({ active: isVisible, containerRef });

  // Screen-reader live-region announcements when navigating between posts.
  const { accessibilityMessage, announce } = useAccessibilityMessage();
  const isFirstAnnouncementRef = useRef(true);
  useEffect(() => {
    if (isFirstAnnouncementRef.current) { isFirstAnnouncementRef.current = false; return; }
    announce(
      `Post ${currentDisplayPost.postIndex + 1} of ${medias.length}${
        currentDisplayPost.username ? `, by ${currentDisplayPost.username}` : ''}`,
    );
  }, [currentDisplayPost.id]);

  usePlayerKeyboardNavigation({
    containerRef,
    isVertical,
    currentPostType: currentDisplayPost.type,
    handleClose,
    handleNextPost,
    handlePreviousPost,
    togglePlay,
    toggleMute,
  });

  // Tap navigation is disabled in vertical mode — swipe and wheel handle all navigation there.
  // In vertical mode, tapping a video will instead toggle play/pause via the video's own onClick.
  useTapNavigation({
    onNext: handleNextPost,
    onPrevious: handlePreviousPost,
    disabled: showList || isVertical,
    containerRef,
    axis: swipeDirection,
  });

  useSwipeNavigation({
    containerRef,
    onSwipeLeft: handleNextPost,
    onSwipeRight: handlePreviousPost,
    onSwipeUp: handleNextPost,
    onSwipeDown: handlePreviousPost,
    disabled: showList,
    threshold: 75,
    axis: swipeDirection,
  });

  // Mouse-wheel / trackpad scroll navigation (vertical mode only)
  useWheelNavigation({
    containerRef,
    onScrollDown: handleNextPost,
    onScrollUp: handlePreviousPost,
    disabled: showList || !isVertical,
  });

  let animationClass = styles.hidden;
  if (isClosing) animationClass = styles.closing;
  else if (isVisible) animationClass = styles.visible;

  const handleOverlayClick = () => productListRef.current?.close();

  return (
    <div
      ref={containerRef}
      role="dialog"
      aria-modal="true"
      aria-label={`Media viewer – ${currentDisplayPost.username ?? 'post'}`}
      tabIndex={-1}
      className={`${classPrefix}-mobile-player ${styles.container} ${animationClass}`}
    >
      <div aria-hidden="true" className={styles.darkBackground} />

      <div className={styles.contentContainer}>
        {!isVisible ? (
          <div className={styles.loaderOverlay} aria-hidden='true'><Spinner /></div>
        ) : null}

        {/* Progress bar is hidden in vertical mode */}
        {!isVertical ? (
          <MediaProgress
            totalItems={medias.length}
            currentIndex={currentDisplayPost.postIndex}
          />
        ) : null}

        {/*
         * When the packshot bar is visible we wrap MediaContainer in a
         * height-constrained clipping box (overflow: hidden, top 85 vh).
         * This keeps the strip + slides full-height inside that box so
         * next/prev slides are clipped before they enter the packshot
         * area, while the image centers naturally in the visible zone.
         */}
        {settings.mobile_player_product_cta === 'packshot' ? (
          <div className={styles.mediaClipWrapper}>
            <MediaContainer
              currentDisplayPost={currentDisplayPost}
              nextDisplayPost={nextDisplayPost}
              prevDisplayPost={prevDisplayPost}
              slideOffset={slideOffset}
              isSliding={isSliding}
              showList={showList}
              isMuted={isMuted}
              isPlaying={isPlaying}
              togglePlay={togglePlay}
              slideAxis={slideAxis}
              showDurationBar={isVertical ? true : undefined}
              durationBarAtTop={true}
              onVideoEnded={handleNextPost}
            />
          </div>
        ) : (
          <MediaContainer
            currentDisplayPost={currentDisplayPost}
            nextDisplayPost={nextDisplayPost}
            prevDisplayPost={prevDisplayPost}
            slideOffset={slideOffset}
            isSliding={isSliding}
            showList={showList}
            isMuted={isMuted}
            isPlaying={isPlaying}
            togglePlay={togglePlay}
            slideAxis={slideAxis}
            showDurationBar={isVertical ? true : undefined}
            durationBarAtTop={true}
            onVideoEnded={handleNextPost}
          />
        )}

        <Controls
          post={currentDisplayPost}
          showList={showList}
          onClose={handleClose}
          toggleList={toggleList}
          isMuted={isMuted}
          isPlaying={isPlaying}
          toggleMute={toggleMute}
          togglePlay={togglePlay}
        />

        {/* In vertical mode, nudge the indicator above the packshot bar (15 % of player height) */}
        {showNextIndicator ? (
          <NextIndicator
            direction={swipeDirection}
            bottomOffset={
              isVertical
              && settings?.mobile_player_product_cta === 'packshot'
                ? `calc(${mobilePlayerPackshotHeightPercent}% + 24px)`
                : undefined
            }
          />
        ) : null}

        {showList ? (
          <div
            aria-hidden="true"
            className={styles.overlay}
            onClick={handleOverlayClick}
          />
        ) : null}

        {showList ? (
          <ShopThisLookProductList
            ref={productListRef}
            post={currentDisplayPost}
            settings={settings}
            totalPosts={totalPosts}
            onClose={toggleList}
            onPostChange={onPostChange}
            classPrefix={classPrefix}
          />
        ) : null}

        {/* Visually-hidden live region – screen readers announce post changes here */}
        <div
          aria-live="polite"
          aria-atomic="true"
          className={styles.srOnly}
        >
          {accessibilityMessage}
        </div>
      </div>
    </div>
  );
};

export default MobilePlayer;

const styles = {
  loaderOverlay: style({
    position: 'absolute',
    inset: 0,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    pointerEvents: 'none',
    zIndex: 10,
  }),

  container: style({
    position: 'fixed',
    top: 0,
    left: 0,
    width: '100%',
    height: '100%',
    zIndex: 9999,
    overflow: 'hidden',
    transition: `transform ${PLAYER_ANIMATION_DURATION_SEC}s ease-in-out`,
  }),
  hidden: style({ transform: 'translateY(100%)' }),
  visible: style({ transform: 'translateY(0)' }),
  closing: style({ transform: 'translateY(100%)' }),
  contentContainer: style({
    position: 'relative',
    width: '100%',
    height: '100%',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    zIndex: 2,
  }),
  darkBackground: style({
    position: 'absolute',
    top: 0,
    left: 0,
    width: '100%',
    height: '100%',
    backgroundColor: 'rgba(0, 0, 0, 0.82)',
    backdropFilter: 'blur(6px)',
    '-webkit-backdrop-filter': 'blur(6px)',
    zIndex: 1,
  }),
  mediaClipWrapper: style({
    position: 'absolute',
    top: 0,
    left: 0,
    width: '100%',
    height: `${100 - mobilePlayerPackshotHeightPercent}vh`,
    overflow: 'hidden',
  }),
  overlay: style({
    position: 'fixed',
    top: 0,
    left: 0,
    width: '100%',
    height: '100%',
    backgroundColor: 'rgba(0, 0, 0, 0.5)',
    backdropFilter: 'blur(6px)',
    '-webkit-backdrop-filter': 'blur(6px)',
    zIndex: productListZIndex - 1,
    cursor: 'pointer',
  }),

  /* Visually hidden but readable by screen readers */
  srOnly: style({
    position: 'absolute',
    width: 1,
    height: 1,
    padding: 0,
    margin: -1,
    overflow: 'hidden',
    clip: 'rect(0,0,0,0)',
    whiteSpace: 'nowrap',
    border: 0,
  }),
};
