import * as React from 'react';
import { TextFilePreview } from '../TextFilePreview';
import { ImageFilePreview } from '../ImageFilePreview';
import { AudioFilePreview } from '../AudioFilePreview';
import { VideoFilePreview } from '../VideoFilePreview';
import { BinaryFilePreview } from '../BinaryFilePreview';
import {AugmentedFile, augmentFile, ContentType, getContentType} from '@/utils/blob';

const FILE_PREVIEW_COMPONENTS: Record<ContentType, React.ElementType> = {
  [ContentType.TEXT]: TextFilePreview,
  [ContentType.IMAGE]: ImageFilePreview,
  [ContentType.AUDIO]: AudioFilePreview,
  [ContentType.VIDEO]: VideoFilePreview,
  [ContentType.BINARY]: BinaryFilePreview,
};

const useFilePreviews = (fileList?: FileList) => {
  const [selectedFiles, setSelectedFiles] = React.useState([] as AugmentedFile[]);
  React.useEffect(() => {
    const loadFilePreviews = async (fileList: FileList) => {
      const files = Array.from(fileList);
      return Promise.all(
        files.map(async (f) => {
          const augmentedFile = await augmentFile(f);
          if (augmentedFile.resolvedType === ContentType.TEXT && augmentedFile.metadata?.scheme) {
            await import(`prismjs/components/prism-${augmentedFile.metadata.scheme}`);
          }
          return augmentedFile;
        })
      );
    }

    if (fileList) {
      loadFilePreviews(fileList).then((fileResult) => {
        setSelectedFiles(fileResult);
      });
    }
  }, [fileList]);

  return React.useMemo(() => ({
    files: selectedFiles,
  }), [selectedFiles]);
};

export interface FilePreviewProps {
  fileList?: FileList;
}

export const FilePreview: React.FC<FilePreviewProps> = ({
  fileList,
}) => {
  const { files } = useFilePreviews(fileList);
  if (files.length < 1) {
    return null;
  }

  const f = fileList?.[0];
  const contentType = getContentType(f?.type, f?.name);
  const FilePreviewComponent = FILE_PREVIEW_COMPONENTS[contentType] ?? BinaryFilePreview;

  return (
    <FilePreviewComponent file={f} />
  );
};
