import { type FC, useEffect, useMemo } from 'react';
import { useFormContext } from 'react-hook-form';

import { IconButton, Stack, useTheme } from '@mui/material';
import { IconPlayerPlay, IconX } from '@tabler/icons-react';

import { type CompleteFile } from '../../../types/attachments';
import { FileTypes, getFileType } from '../../../utils/files';
import Spinner from '../../design-system/ProgressIndicators/Spinner';

import { type FieldValues } from './CreatePost';
import Sortable from './Sortable';

const VIDEO_ICON_SIZE = 24;
const itemSize = {
  width: '70px',
  height: '70px',
  objectFit: 'cover',
  cursor: 'pointer',
  borderRadius: 1,
};

type SortableItemProps = { item: CompleteFile };
const SortableItem: FC<SortableItemProps> = ({ item }) => {
  const form = useFormContext<FieldValues>();
  const isLoading = !item.attachment;
  const fileType = item.attachment?.type || getFileType(item.file!);
  let content = null;
  const src = useMemo(() => {
    if (item.file) return URL.createObjectURL(item.file);
    return item.attachment!.url;
  }, [item.id]);

  useEffect(
    () => () => {
      if (item.file) {
        URL.revokeObjectURL(src);
      }
    },
    [],
  );

  switch (fileType) {
    case FileTypes.IMAGE:
      content = (
        <Stack
          component="img"
          src={src}
          alt={item.file?.name || item.attachment?.name}
          sx={itemSize}
        />
      );
      break;
    case FileTypes.VIDEO:
      content = (
        <>
          <Stack
            sx={{
              ...itemSize,
              position: 'relative',
            }}
          >
            <Stack
              component="video"
              src={src}
              sx={{ ...itemSize }}
            />
            <Stack
              sx={{
                position: 'absolute',
                top: '50%',
                left: '50%',
                transform: 'translate(-50%, -50%)',
              }}
            >
              <IconPlayerPlay
                size={VIDEO_ICON_SIZE}
                color="white"
              />
            </Stack>
          </Stack>
        </>
      );
      break;
  }

  const media = form.watch('media');
  const theme = useTheme();

  return (
    <Stack sx={{ position: 'relative', mt: 1.5 }}>
      <IconButton
        sx={{
          position: 'absolute',
          top: '-12px',
          right: '-12px',
          backgroundColor: theme.palette.base!.greyTransparent['300p50'],
          zIndex: 1,
          width: '24px',
          height: '24px',
          borderRadius: 1,
          p: 0,
        }}
        onClick={() =>
          form.setValue(
            'media',
            media.filter(f => f !== item),
          )
        }
      >
        <IconX
          color={theme.palette.new.text.neutral.default}
          size={16}
        />
      </IconButton>
      {content}
      {isLoading && (
        <Spinner
          sx={{ position: 'absolute', top: '25%', left: '25%' }}
          darkBackground
        />
      )}
    </Stack>
  );
};

export const EditMediaCarrousel: FC = () => {
  const form = useFormContext<FieldValues>();
  const { media } = form.watch();
  if (!media.length) return null;

  return (
    <Sortable
      items={media}
      onSort={newItems => form.setValue('media', newItems)}
      ItemComponent={SortableItem}
    />
  );
};

export default EditMediaCarrousel;
