import { observer } from 'mobx-react-lite';
import { useCallback, useContext } from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import HookFormContext, {
  MAX_VIDEO_DURATION_SECONDS,
  MAX_VIDEO_UPLOAD_FILESIZE_MB,
  MIN_VIDEO_DURATION_SECONDS,
} from '@/app/(root)/hooks/create/useHookForm';
import Button, {
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '@/components/button/Button';
import Avatar from '@/components/image/Avatar';
import { ModalTypes } from '@/components/modal/constants/ModalTypes';
import {
  SelectorComponentProps,
  VideoSelector,
} from '@/components/video/VideoSelector';
import { ArrowLeftIcon, UploadIcon } from '@/icons';
import { getClipTitle } from '@/utils/clip';
import { FALLBACK_IMAGE_URL, SMALL_IMAGE } from '@/utils/constants';

export const UploadHookVideoScreenHeader = () => {
  const { navigateTo, selectedSong, currentScreen } =
    useContext(HookFormContext);

  const handleBack = () => {
    navigateTo('selectSongInFlow');
  };

  return (
    <div className='flex w-full flex-row justify-between gap-4'>
      {currentScreen === 'uploadVideoInFlow' && (
        <div className='absolute top-1 left-1 m-4'>
          <Button
            variant={ButtonVariant.Standard}
            onClick={handleBack}
            icon={ArrowLeftIcon}
            shape={ButtonShape.Pill}
          />
        </div>
      )}
      <div className='flex h-fit w-full flex-col items-center p-2 pt-4'>
        <h1 className='text-2xl'>Upload a Video</h1>
        <div className='flex flex-row gap-2'>
          <div className='flex flex-row items-center justify-center gap-2'>
            <Avatar
              imageSize={SMALL_IMAGE}
              className='h-5 w-5 object-cover'
              src={selectedSong?.image_url || ''}
              alt='Persona image'
              fallbackSrc={FALLBACK_IMAGE_URL}
            />
            <div>{selectedSong ? getClipTitle(selectedSong) : ''}</div>
          </div>
        </div>
      </div>
    </div>
  );
};

export const UploadHookVideoScreenBody = observer(() => {
  const { menus } = useStores();
  const VIDEO_WIDTH = 282;
  const VIDEO_HEIGHT = (VIDEO_WIDTH * 16) / 9;
  const { selectedVideo, updateSelectedVideo } = useContext(HookFormContext);

  const handleFileChange = (file: File | null) => {
    if (file) {
      updateSelectedVideo(file, {
        onError: () => {
          // Reopen modal when there is an error
          menus.openModal(ModalTypes.SELECT_HOOK_SONG);
        },
      });
      menus.closeModal(ModalTypes.SELECT_HOOK_SONG);
    }
  };

  const selectorComponent = useCallback((props: SelectorComponentProps) => {
    return (
      <div
        {...props.getRootProps()}
        className='flex h-full w-full flex-col items-center justify-center gap-1'
      >
        <input {...props.getInputProps()} />
        <Button
          icon={UploadIcon}
          iconClassName='w-8 h-8'
          shape={ButtonShape.Pill}
          size={ButtonSize.Large}
          variant={ButtonVariant.Primary}
        />
        <div className='flex flex-col items-center justify-center gap-0 py-2 text-base leading-normal'>
          <p className='font-semibold'>Select a video to upload</p>
          <p className='text-foreground-secondary'>or drag and drop here</p>
          <p className='max-w-60 text-center text-xs text-foreground-tertiary'>
            (
            {[
              '9:16 portrait aspect ratio',
              `duration between ${MIN_VIDEO_DURATION_SECONDS} seconds and ${Math.round(MAX_VIDEO_DURATION_SECONDS / 60)} minutes`,
              `max file size ${MAX_VIDEO_UPLOAD_FILESIZE_MB} MB`,
            ].join(', ')}
            )
          </p>
        </div>
        <Button
          shape={ButtonShape.Pill}
          size={ButtonSize.Medium}
          variant={ButtonVariant.Primary}
        >
          Select Video
        </Button>
      </div>
    );
  }, []);

  return (
    <div className='flex h-full w-full flex-col items-center justify-center gap-1 text-foreground-primary'>
      <VideoSelector
        selectedVideo={selectedVideo}
        onVideoSelect={handleFileChange}
        width={VIDEO_WIDTH}
        height={VIDEO_HEIGHT}
        maxDuration={MAX_VIDEO_DURATION_SECONDS}
        selectorComponent={selectorComponent}
      />
    </div>
  );
});

export const UploadHookVideoScreen = () => {
  return (
    <div className='flex h-full w-full flex-col gap-4'>
      <UploadHookVideoScreenHeader />
      <UploadHookVideoScreenBody />
    </div>
  );
};
