import {
  getPluginOptions,
  insertNodes,
  useEditorRef,
} from '@udecode/plate-common';

import { AudioPlugin, ELEMENT_ATTACHMENT_AUDIO } from '../audio';
import { ELEMENT_ATTACHMENT_IMAGE, ImagePlugin } from '../image';
import { ELEMENT_ATTACHMENT_VIDEO, VideoPlugin } from '../video';
import { AttachmentPlugin, TAttachmentElement } from './types';

const useAttachmentUpload = () => {
  const editor = useEditorRef();

  const imageUpload = getPluginOptions<ImagePlugin>(
    editor,
    ELEMENT_ATTACHMENT_IMAGE
  ).uploadAttachment;

  const audioUpload = getPluginOptions<AudioPlugin>(
    editor,
    ELEMENT_ATTACHMENT_AUDIO
  ).uploadAttachment;

  const videoUpload = getPluginOptions<VideoPlugin>(
    editor,
    ELEMENT_ATTACHMENT_VIDEO
  ).uploadAttachment;

  const attachmentUpload = getPluginOptions<AttachmentPlugin>(
    editor,
    ELEMENT_ATTACHMENT_IMAGE
  ).uploadAttachment;

  return {
    imageUpload,
    audioUpload,
    videoUpload,
    attachmentUpload,
  };
};

export const useAttachmentToolbarButton = () => {
  const editor = useEditorRef();

  // just one is also ok, for business need
  const { imageUpload, audioUpload, videoUpload, attachmentUpload } =
    useAttachmentUpload();

  const getInsertInitValues = (file: File) => {
    const fileType = file.type.split('/')[0] || '';

    const baseValue: Pick<
      TAttachmentElement,
      'id' | 'size' | 'name' | 'status' | 'fileType' | 'uploadStatus' | 'width'
    > = {
      id: `${Date.now()}`,
      size: file.size,
      name: file.name,
      status: 'thumbnail',
      width: '50%',
      fileType,
      uploadStatus: 'success',
    };

    return baseValue;
  };

  const uploadFile: AttachmentPlugin['uploadAttachment'] = async (
    file: File
  ) => {
    const { type } = file;

    const uploadFunctions: Record<string, any> = {
      'image/': imageUpload,
      'audio/': audioUpload,
      'video/': videoUpload,
      default: attachmentUpload,
    };

    const uploadFunction =
      Object.keys(uploadFunctions).find((key) => type.startsWith(key)) ||
      'default';

    return uploadFunctions[uploadFunction]?.(file) || {};
  };

  const insertAttachment = (value: Omit<TAttachmentElement, 'children'>) => {
    const text = { text: '' };
    const _value: TAttachmentElement = {
      ...(value as TAttachmentElement),
      children: [text],
    };
    insertNodes<TAttachmentElement>(editor, _value, {
      nextBlock: true,
    });
  };

  return {
    uploadFile,
    getInsertInitValues,
    insertAttachment,
  };
};
