import React, { PropsWithChildren } from 'react';
import { cn } from '@udecode/cn';
import { focusEditor, useEditorRef } from '@udecode/plate-common';
import Upload from 'rc-upload';

import { Icons } from '@/components/icons';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuTrigger,
  useOpenState,
} from '@/components/plate-ui/dropdown-menu';
import { ToolbarButton } from '@/components/plate-ui/toolbar';

import { useAttachmentToolbarButton } from '../logic';

const attachmentUploadItems = [
  {
    label: '图片',
    accept: 'image/*',
    description: '图片',
    icon: Icons.image,
  },
  {
    label: '音频',
    accept: 'audio/mp3,audio/*;capture=microphone',
    description: '音频',
    icon: Icons.audio,
  },
  {
    label: '视频',
    accept: 'video/mp4,video/x-m4v,video/*',
    description: '视频',
    icon: Icons.video,
  },
  {
    label: '文件',
    accept: '*',
    description: '文件',
    icon: Icons.file,
  },
];

export function AttachmentToolbarUploadButton() {
  const editor = useEditorRef();
  const openState = useOpenState();

  const { getInsertInitValues, insertAttachment, uploadFile } =
    useAttachmentToolbarButton();

  const beforeFileUpload = async (file: File, _fileList: File[]) => {
    const initValues = getInsertInitValues(file);
    const uploadParams = await uploadFile(file);

    insertAttachment({
      ...initValues,
      ...uploadParams,
    });

    openState.onOpenChange(false);
    focusEditor(editor);
    return false;
  };

  return (
    <DropdownMenu modal={false} {...openState}>
      <DropdownMenuTrigger asChild>
        <ToolbarButton pressed={openState.open} isDropdown>
          <Icons.fileInsert />
        </ToolbarButton>
      </DropdownMenuTrigger>
      <DropdownMenuContent
        align="start"
        className="flex max-h-[500px] min-w-0 flex-col gap-0.5 overflow-y-auto"
      >
        {attachmentUploadItems.map(
          ({ label: itemLabel, accept, icon: Icon }) => {
            return (
              <React.Fragment key={itemLabel}>
                <Upload
                  multiple
                  accept={accept}
                  beforeUpload={(file, files) => beforeFileUpload(file, files)}
                >
                  <DropdownMenuFileItem>
                    <Icon className="mr-2 h-4 w-4" />
                    {itemLabel}
                  </DropdownMenuFileItem>
                </Upload>
              </React.Fragment>
            );
          }
        )}
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

function DropdownMenuFileItem({ children, ...props }: PropsWithChildren<any>) {
  return (
    <div
      className={cn(
        'relative flex h-9 cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-slate-100',
        'min-w-[180px] focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50'
      )}
      {...props}
    >
      {children}
    </div>
  );
}
