import {
  Check,
  ChevronDown,
  ChevronRight,
  Folder,
  ImagePlus,
  PencilLine,
  Trash2,
  X,
} from 'lucide-react';
import type { Dispatch, SetStateAction } from 'react';

import { PlatformTextField } from '../common/PlatformTextField';
import { EditorIconButton } from './ImageCanvasEditorPrimitives';
import {
  ASSET_DRAG_MIME_TYPE,
  getDraggedAssetId,
  hasDataTransferType,
} from './ImageCanvasEditorModel';
import type {
  AssetPointerDragState,
  EditorAsset,
  EditorAssetFolder,
  UploadTarget,
} from './ImageCanvasEditorTypes';
import { ImageCanvasAssetRowView } from './ImageCanvasAssetRowView';
import type {
  GroupedEditorAssetFolder,
  UploadFilesOptions,
} from './ImageCanvasAssetLibraryPanelView';

type ImageCanvasAssetFolderSectionViewProps = {
  folder: GroupedEditorAssetFolder;
  assetPointerDragRef: { current: AssetPointerDragState | null };
  suppressAssetClickRef: { current: boolean };
  isAssetSelectionMode: boolean;
  selectedAssetIds: Set<string>;
  assetMoveDropFolderId: string | null;
  renamingFolder: { folderId: string; value: string } | null;
  renamingAsset: { assetId: string; value: string } | null;
  setRenamingFolder: Dispatch<
    SetStateAction<{ folderId: string; value: string } | null>
  >;
  setRenamingAsset: Dispatch<
    SetStateAction<{ assetId: string; value: string } | null>
  >;
  setActiveUploadFolderId: Dispatch<SetStateAction<string>>;
  setUploadDropTarget: Dispatch<SetStateAction<'canvas' | 'assets' | null>>;
  setAssetPointerDrag: Dispatch<SetStateAction<AssetPointerDragState | null>>;
  setSelectedAssetIds: Dispatch<SetStateAction<Set<string>>>;
  updateAssetMoveDropFolder: (folderId: string | null) => void;
  addUploadedFiles: (files: FileList | File[], options?: UploadFilesOptions) => void;
  requestUpload: (target: UploadTarget) => void;
  moveAssetToFolder: (assetId: string, folderId: string) => void;
  toggleAssetFolder: (folderId: string) => void;
  startRenamingFolder: (folder: EditorAssetFolder) => void;
  commitFolderRename: (folder: EditorAssetFolder) => void;
  deleteAssetFolder: (folder: EditorAssetFolder) => void;
  startRenamingAsset: (asset: EditorAsset) => void;
  commitAssetRename: (asset: EditorAsset) => void;
  deleteUploadedAsset: (asset: EditorAsset) => void;
  toggleAssetSelected: (assetId: string) => void;
  addAssetLayer: (asset: EditorAsset) => void;
};

export function ImageCanvasAssetFolderSectionView({
  folder,
  assetPointerDragRef,
  suppressAssetClickRef,
  isAssetSelectionMode,
  selectedAssetIds,
  assetMoveDropFolderId,
  renamingFolder,
  renamingAsset,
  setRenamingFolder,
  setRenamingAsset,
  setActiveUploadFolderId,
  setUploadDropTarget,
  setAssetPointerDrag,
  setSelectedAssetIds,
  updateAssetMoveDropFolder,
  addUploadedFiles,
  requestUpload,
  moveAssetToFolder,
  toggleAssetFolder,
  startRenamingFolder,
  commitFolderRename,
  deleteAssetFolder,
  startRenamingAsset,
  commitAssetRename,
  deleteUploadedAsset,
  toggleAssetSelected,
  addAssetLayer,
}: ImageCanvasAssetFolderSectionViewProps) {
  return (
    <section
      className={[
        'image-canvas-editor__asset-folder',
        assetMoveDropFolderId === folder.id
          ? 'image-canvas-editor__asset-folder--move-target'
          : '',
      ]
        .filter(Boolean)
        .join(' ')}
      aria-label={folder.label}
      data-asset-folder-id={folder.id}
      onDragOver={(event) => {
        if (hasDataTransferType(event.dataTransfer, ASSET_DRAG_MIME_TYPE)) {
          event.preventDefault();
          event.stopPropagation();
          setUploadDropTarget(null);
          updateAssetMoveDropFolder(folder.id);
          event.dataTransfer.dropEffect = 'move';
          return;
        }
        if (hasDataTransferType(event.dataTransfer, 'Files')) {
          event.preventDefault();
          event.stopPropagation();
          setUploadDropTarget('assets');
          event.dataTransfer.dropEffect = 'copy';
        }
      }}
      onDrop={(event) => {
        const movingAssetId = getDraggedAssetId(event.dataTransfer);
        if (movingAssetId) {
          event.preventDefault();
          event.stopPropagation();
          setUploadDropTarget(null);
          updateAssetMoveDropFolder(null);
          moveAssetToFolder(movingAssetId, folder.id);
          return;
        }
        if (!event.dataTransfer.files.length) {
          return;
        }
        event.preventDefault();
        event.stopPropagation();
        setUploadDropTarget(null);
        updateAssetMoveDropFolder(null);
        addUploadedFiles(event.dataTransfer.files, {
          folderId: folder.id,
        });
      }}
    >
      <div
        className="image-canvas-editor__asset-folder-header"
        data-asset-folder-header-id={folder.id}
      >
        <EditorIconButton
          label={`${folder.collapsed ? '展开' : '折叠'}${folder.label}`}
          title={folder.collapsed ? '展开' : '折叠'}
          icon={folder.collapsed ? ChevronRight : ChevronDown}
          expanded={!folder.collapsed}
          onClick={() => toggleAssetFolder(folder.id)}
        />
        <Folder className="h-4 w-4" />
        {renamingFolder?.folderId === folder.id ? (
          <PlatformTextField
            aria-label={`重命名文件夹${folder.label}`}
            value={renamingFolder.value}
            autoFocus
            size="xs"
            density="compact"
            className="image-canvas-editor__folder-rename-input"
            onChange={(event) =>
              setRenamingFolder({
                folderId: folder.id,
                value: event.target.value,
              })
            }
            onKeyDown={(event) => {
              if (event.key === 'Enter') {
                event.preventDefault();
                commitFolderRename(folder);
              }
              if (event.key === 'Escape') {
                event.preventDefault();
                setRenamingFolder(null);
              }
            }}
          />
        ) : (
          <span>{folder.label}</span>
        )}
        <span>{folder.assets.length}</span>
        {renamingFolder?.folderId === folder.id ? (
          <>
            <EditorIconButton
              label={`保存文件夹${folder.label}名称`}
              title="保存"
              icon={Check}
              onClick={() => commitFolderRename(folder)}
            />
            <EditorIconButton
              label={`取消重命名文件夹${folder.label}`}
              title="取消"
              icon={X}
              onClick={() => setRenamingFolder(null)}
            />
          </>
        ) : (
          <EditorIconButton
            label={`重命名文件夹${folder.label}`}
            title="重命名"
            icon={PencilLine}
            onClick={() => startRenamingFolder(folder)}
          />
        )}
        {!folder.systemDefault ? (
          <EditorIconButton
            label={`删除文件夹${folder.label}`}
            title="删除"
            icon={Trash2}
            onClick={() => deleteAssetFolder(folder)}
          />
        ) : null}
        <EditorIconButton
          label={`上传到${folder.label}`}
          title="上传"
          icon={ImagePlus}
          onClick={() => {
            setActiveUploadFolderId(folder.id);
            requestUpload('asset');
          }}
        />
      </div>
      <div
        className="image-canvas-editor__asset-folder-list"
        hidden={folder.collapsed}
      >
        {folder.assets.map((asset) => (
          <ImageCanvasAssetRowView
            key={asset.id}
            asset={asset}
            assetPointerDragRef={assetPointerDragRef}
            suppressAssetClickRef={suppressAssetClickRef}
            isAssetSelectionMode={isAssetSelectionMode}
            selectedAssetIds={selectedAssetIds}
            renamingAsset={renamingAsset}
            setRenamingAsset={setRenamingAsset}
            setUploadDropTarget={setUploadDropTarget}
            setAssetPointerDrag={setAssetPointerDrag}
            setSelectedAssetIds={setSelectedAssetIds}
            updateAssetMoveDropFolder={updateAssetMoveDropFolder}
            addUploadedFiles={addUploadedFiles}
            moveAssetToFolder={moveAssetToFolder}
            startRenamingAsset={startRenamingAsset}
            commitAssetRename={commitAssetRename}
            deleteUploadedAsset={deleteUploadedAsset}
            toggleAssetSelected={toggleAssetSelected}
            addAssetLayer={addAssetLayer}
          />
        ))}
      </div>
    </section>
  );
}
