import { useCallback, useEffect, useMemo } from 'react';
import { Editor, NodeViewWrapper, NodeViewProps } from '@tiptap/react';
import MediaInsert from '@features/media/components/media-insert/media-insert';
import { MediaItem, MediaViewFileType } from '@features/media/types';
import { ButtonV2 as Button } from '@components/button-v2';
import { Icon } from '@features/block-editor/components/ui/Icon';
import { useMediaSelect, useFileUpload, useDropZone } from './hooks';
import { insertMediaBlocks } from './insertMediaBlocks';
import { filterFilesByMediaType } from './filterFilesByMediaType';
import DropZone from '../../../../../components/drop-zone/drop-zone';

export const Dropzone = ({
  getPos,
  editor,
  node,
}: {
  getPos: () => number;
  editor: Editor;
  node: NodeViewProps['node'];
}) => {
  const className = node?.attrs?.class || '';
  const { isInsertModalOpen, files, tab, uploadFile, handleModalClose, handleSelectClick } = useMediaSelect();
  const pastedFiles = useMemo(() => {
    return node.attrs.__pastedFiles || [];
  }, [node.attrs.__pastedFiles]);
  const mediaType: MediaViewFileType = useMemo(() => {
    if (node.attrs.__mediaType === 'file') return 'file';
    if (node.attrs.__mediaType === 'all') return 'all';
    return 'image';
  }, [node.attrs.__mediaType]);

  // 枠の種別に合わないファイルはアップロード前に弾く（画像枠は画像のみ・ファイル枠は画像以外のみ）
  const acceptUpload = useCallback(
    (uploadingFiles: File[]) => {
      const accepted = filterFilesByMediaType(uploadingFiles, mediaType);
      if (accepted.length > 0) {
        uploadFile(accepted);
      }
    },
    [mediaType, uploadFile]
  );
  const { fileInputRef, handleUploadClick, handleUploadFile } = useFileUpload({ uploader: acceptUpload });
  const { onDrop } = useDropZone({ uploader: acceptUpload });

  useEffect(() => {
    if (pastedFiles.length > 0) {
      acceptUpload(pastedFiles);
    }
  }, [pastedFiles, acceptUpload]);

  const handleInsertMedia = useCallback(
    (items: MediaItem[]) => {
      const from = getPos();
      const to = from + node.nodeSize;
      insertMediaBlocks(editor, items, mediaType, className, { from, to });
      handleModalClose();
    },
    [editor, mediaType, getPos, node, handleModalClose, className]
  );

  return (
    <NodeViewWrapper>
      {/* D&D・ペースト経由 (__pastedFiles あり) は即モーダルへ進むため、ドロップ枠 UI は描画しない */}
      {pastedFiles.length === 0 && (
        <DropZone onComplete={onDrop}>
          <div className="acms-admin-block-editor-image-drop" style={{ width: '100%' }}>
            <p className="acms-admin-block-editor-image-drop-text">
              {mediaType === 'image' && (
                <span className="acms-admin-block-editor-image-drop-text-main">ここに画像をドラッグ</span>
              )}
              {mediaType === 'file' && (
                <span className="acms-admin-block-editor-image-drop-text-main">ここにファイルをドラッグ</span>
              )}
              <span className="acms-admin-block-editor-image-drop-text-sub">または</span>
            </p>
            <div className="acms-admin-block-editor-button-group">
              <Button onClick={handleSelectClick} variant="outlined" size="default" type="button">
                <Icon name="perm_media" />
                メディア選択
              </Button>
              <Button onClick={handleUploadClick} variant="filled" size="default" type="button">
                <Icon name="upload" />
                アップロード
              </Button>
            </div>
            <input
              id="media-upload-input"
              ref={fileInputRef}
              type="file"
              multiple
              accept={mediaType === 'image' ? 'image/*' : undefined}
              onChange={handleUploadFile}
              style={{ display: 'none' }}
            />
          </div>
        </DropZone>
      )}
      <MediaInsert
        isOpen={isInsertModalOpen}
        onInsert={handleInsertMedia}
        files={files}
        onClose={handleModalClose}
        tab={tab}
        filetype={mediaType}
      />
    </NodeViewWrapper>
  );
};

export default Dropzone;
