import * as React from 'react';
import { FC, useState } from 'react';
import { style } from 'typestyle';
import { IMedia } from '../../../../../types';
import VideoPlayer from './VideoPlayer';
import ImageDisplay from './ImageDisplay';
import UserName from '../../../../UserName';
import { pillBackgroundColor, pillFontColor } from '../../../../consts';
import { SLIDE_DURATION_MS } from '../../../../../hooks/usePlayerNavigation';

interface MediaContainerProps {
  currentDisplayPost: IMedia;
  nextDisplayPost: IMedia | null;
  prevDisplayPost: IMedia | null;
  slideOffset: number;
  isSliding: boolean;
  showList: boolean;
  isMuted: boolean;
  isPlaying: boolean;
  togglePlay: () => void;
  /** Controls how media fills its container.
   * Defaults to 'contain' (mobile). Use 'cover' for desktop. */
  objectFit?: 'contain' | 'cover';
  showUsernamePill?: boolean;
  /** Force-show the video duration bar regardless of the mobile_player_product_cta setting. */
  showDurationBar?: boolean;
  /** When true, clicking the video will not toggle play/pause (desktop tap-navigation mode). */
  disableClickToPlay?: boolean;
  /** CSS axis for the slide transition. 'X' = horizontal (default), 'Y' = vertical. */
  slideAxis?: 'X' | 'Y';
  /** When true, the duration bar is anchored to the top edge of the video. */
  durationBarAtTop?: boolean;
  /** Called when the current video reaches its end. */
  onVideoEnded?: () => void;
}

const MediaContainer: FC<MediaContainerProps> = ({
  currentDisplayPost,
  nextDisplayPost,
  prevDisplayPost,
  slideOffset,
  isSliding,
  showList,
  isMuted,
  isPlaying,
  togglePlay,
  objectFit = 'contain',
  showUsernamePill = true,
  showDurationBar,
  disableClickToPlay = false,
  slideAxis = 'X',
  durationBarAtTop = false,
  onVideoEnded,
}) => {
  const posts: { post: IMedia; baseOffset: number }[] = [
    ...(prevDisplayPost ? [{ post: prevDisplayPost, baseOffset: -100 }] : []),
    { post: currentDisplayPost, baseOffset: 0 },
    ...(nextDisplayPost ? [{ post: nextDisplayPost, baseOffset: 100 }] : []),
  ];

  const isSlidingToNext = isSliding && slideOffset < 0;
  const isSlidingToPrev = isSliding && slideOffset > 0;

  const [unlockedForPostId, setUnlockedForPostId] = useState<string | null>(null);

  // Unlock neighbour src only when the current video is ready and no slide is active.
  const neighbourSrcEnabled = !isSliding && unlockedForPostId === currentDisplayPost.id;

  return (
    <>
      <div
        className={styles.strip}
        style={{ filter: showList ? 'brightness(0.3)' : 'none' }}
      >
        {posts.map(({ post, baseOffset }) => {
          const isCurrent = post.id === currentDisplayPost.id;
          const isNext = post.id === nextDisplayPost?.id;
          const isPrev = post.id === prevDisplayPost?.id;

          // Start the target video playing while it slides in so it arrives
          // already running — no load(), no pause between posts.
          const videoIsPlaying =
            isCurrent ? isPlaying :
            (isNext && isSlidingToNext) || (isPrev && isSlidingToPrev);

          return (
            <div
              key={post.id}
              className={styles.slide}
              style={{
                transform: `translate${slideAxis}(${baseOffset + slideOffset}%)`,
                transition: isSliding
                  ? `transform ${SLIDE_DURATION_MS}ms ease-out`
                  : 'none',
              }}
            >
              {post.type === 'video' ? (
                <VideoPlayer
                  post={post}
                  preload={!isCurrent}
                  srcEnabled={isCurrent || videoIsPlaying || neighbourSrcEnabled}
                  onVideoReady={isCurrent ? () => setUnlockedForPostId(
                    currentDisplayPost.id,
                  ) : undefined}
                  isMuted={isCurrent ? isMuted : true}
                  isPlaying={videoIsPlaying}
                  togglePlay={isCurrent ? togglePlay : () => {}}
                  objectFit={objectFit}
                  showDurationBar={showDurationBar}
                  disableClickToPlay={disableClickToPlay}
                  durationBarAtTop={durationBarAtTop}
                  onVideoEnded={isCurrent ? onVideoEnded : undefined}
                />
              ) : (
                <ImageDisplay post={post} objectFit={objectFit} />
              )}
            </div>
          );
        })}
      </div>

      {showUsernamePill ? (
        <div className={styles.topLeft}>
          <UserName
            color={pillFontColor}
            padding='10px 12px'
            backgroundColor={pillBackgroundColor}
            username={currentDisplayPost.username}
            source={currentDisplayPost.source}
            postUrl={currentDisplayPost.post}
          />
        </div>
      ) : null}
    </>
  );
};

export default MediaContainer;

const styles = {
  strip: style({
    width: '100%',
    height: '100%',
    position: 'relative',
  }),

  slide: style({
    position: 'absolute',
    width: '100%',
    height: '100%',
    top: 0,
    left: 0,
  }),

  topLeft: style({
    position: 'absolute',
    top: 20,
    left: 20,
    zIndex: 10,
    height: '40px',
  }),
};
