import { observer } from 'mobx-react-lite';
import { useCallback } from 'react';
import { createPortal } from 'react-dom';
import { useTranslation } from 'react-i18next';
import { twMerge } from 'tailwind-merge';

import { useStores } from '@/app/(root)/AppProviders';
import Button, {
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '@/components/button/Button';
import { ModalTypes } from '@/components/modal/constants/ModalTypes';
import { useModalContext } from '@/context/ModalContext';
import { CloseIcon } from '@/icons';

import OmniPlayer, { Props as BaseOmniplayerProps } from './Omniplayer';

export type OmniplayerProps = {
  innerClassName?: string;
};

export type Props = Omit<
  React.HTMLAttributes<HTMLDivElement>,
  keyof OmniplayerProps | keyof BaseOmniplayerProps
> &
  BaseOmniplayerProps &
  OmniplayerProps;

const OmniplayerModal: React.FC<Props> = observer((props) => {
  const { className, innerClassName, ...restProps } = props;

  const {
    playbar: playbarStore,
    clips: clipsStore,
    queue: queueStore,
  } = useStores();

  const { isModalOpen, closeModal } = useModalContext();
  const { t } = useTranslation();

  const isOpen = isModalOpen(ModalTypes.OMNIPLAYER);

  const clipId = playbarStore.clip?.id;

  const handleCloseClick = useCallback(() => {
    closeModal(ModalTypes.OMNIPLAYER);
  }, [closeModal]);

  const handlePlayPauseClick = useCallback(() => {
    const clipId = playbarStore.clip?.id;
    const clip = clipId ? clipsStore.clipById[clipId] : null;
    if (clip && !playbarStore.isClipPreloaded) {
      playbarStore.togglePlay();
    } else {
      playbarStore.noClipPlayCallback?.();
    }
  }, [clipsStore, playbarStore]);

  const handlePreviousClick = useCallback(() => {
    playbarStore.stepBackward();
  }, [playbarStore]);
  const handleNextClick = useCallback(() => {
    playbarStore.stepForward();
  }, [playbarStore]);
  const handleVolumeClick = useCallback(() => {
    playbarStore.setVolume(playbarStore.displayVolume ? 0 : 1);
  }, [playbarStore]);

  const handleShuffleClick = useCallback(() => {
    playbarStore.toggleShuffle();
  }, [playbarStore]);
  const handleRepeatClick = useCallback(() => {
    playbarStore.toggleRepeat();
  }, [playbarStore]);
  const handleAutoplayClick = useCallback(() => {
    queueStore.toggleAutoplay();
  }, [queueStore]);

  // const handleQueueClick = useCallback(() => {}, [playbarStore]);
  // const handleMoreActionsClick = useCallback(() => {}, [playbarStore]);
  // const handleLikeClick = useCallback(() => {}, [playbarStore]);
  // const handleDislikeClick = useCallback(() => {}, [playbarStore]);
  // const handleCommentsClick = useCallback(() => {}, [playbarStore]);
  // const handleShareClick = useCallback(() => {}, [playbarStore]);

  if (!isOpen) {
    return null;
  }

  return createPortal(
    <div
      className={twMerge(
        'fixed inset-0 flex items-center justify-center',
        'z-50 bg-opacity-black-60',
        className
      )}
    >
      <OmniPlayer
        className={twMerge(
          'w-full max-w-[calc(min(100vw-4rem,40rem))] rounded-3xl',
          innerClassName
        )}
        visualizerClassName='rounded-[inherit] overflow-clip'
        metadataClassName='pr-16'
        clipId={clipId}
        isPlaying={playbarStore.isPlaying}
        volume={playbarStore.volume}
        muted={playbarStore.muted}
        shuffle={queueStore.shuffle}
        repeat={playbarStore.repeat}
        autoplay={queueStore.autoplay}
        // isLiked={isLiked} // @TODO
        // isDisliked={isDisliked} // @TODO
        onPlayPauseClick={handlePlayPauseClick}
        onPreviousClick={handlePreviousClick}
        onNextClick={handleNextClick}
        onVolumeClick={handleVolumeClick}
        onShuffleClick={handleShuffleClick}
        onRepeatClick={handleRepeatClick}
        onAutoplayClick={handleAutoplayClick}
        currentTime={playbarStore.currentTime}
        duration={
          playbarStore.loadingDuration ? undefined : playbarStore.duration
        }
        estimatedDuration={
          playbarStore.loadingDuration ? playbarStore.duration : undefined
        }
        {...restProps}
      >
        <Button
          className='absolute top-4 right-4'
          variant={ButtonVariant.Fog}
          shape={ButtonShape.Pill}
          size={ButtonSize.Small}
          icon={CloseIcon}
          aria-label={t('cta.close')}
          onClick={handleCloseClick}
        />
      </OmniPlayer>
    </div>,
    document.body
  );
});

export default OmniplayerModal;
