import {
  Check,
  CheckSquare,
  Folder,
  Square,
  Trash2,
  X,
} from 'lucide-react';
import type {
  Dispatch,
  PointerEvent as ReactPointerEvent,
  RefObject,
  SetStateAction,
} from 'react';

import { PlatformActionButton } from '../common/PlatformActionButton';
import { PlatformBatchActionToolbar } from '../common/PlatformBatchActionToolbar';
import { PlatformTextField } from '../common/PlatformTextField';
import { EditorIconButton } from './ImageCanvasEditorPrimitives';
import { ImageCanvasAssetFolderSectionView } from './ImageCanvasAssetFolderSectionView';
import type {
  AssetMarqueeState,
  AssetPointerDragState,
  EditorAsset,
  EditorAssetFolder,
  UploadTarget,
} from './ImageCanvasEditorTypes';

export type GroupedEditorAssetFolder = EditorAssetFolder & {
  assets: EditorAsset[];
};

export type UploadFilesOptions = {
  folderId?: string;
  canvasPoint?: { x: number; y: number };
  addToCanvas?: boolean;
};

export type ImageCanvasAssetLibraryPanelViewProps = {
  assetListRef: RefObject<HTMLDivElement | null>;
  assetPointerDragRef: { current: AssetPointerDragState | null };
  suppressAssetClickRef: { current: boolean };
  groupedAssets: GroupedEditorAssetFolder[];
  assetFolders: EditorAssetFolder[];
  isAssetSelectionMode: boolean;
  selectedAssetIds: Set<string>;
  assetMoveDropFolderId: string | null;
  pinnedAssetMoveFolderId: string | null;
  creatingFolder: boolean;
  newFolderName: string;
  renamingFolder: { folderId: string; value: string } | null;
  renamingAsset: { assetId: string; value: string } | null;
  allSelectableAssetsSelected: boolean;
  assetMarquee: AssetMarqueeState | null;
  setCreatingFolder: Dispatch<SetStateAction<boolean>>;
  setNewFolderName: Dispatch<SetStateAction<string>>;
  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>>>;
  onAssetMarqueePointerDown: (
    event: ReactPointerEvent<HTMLDivElement>,
  ) => void;
  onAssetMarqueePointerMove: (
    event: ReactPointerEvent<HTMLDivElement>,
  ) => void;
  onAssetMarqueePointerUp: (
    event: ReactPointerEvent<HTMLDivElement>,
  ) => void;
  updateAssetMoveDropFolder: (folderId: string | null) => void;
  addUploadedFiles: (files: FileList | File[], options?: UploadFilesOptions) => void;
  requestUpload: (target: UploadTarget) => void;
  moveAssetToFolder: (assetId: string, folderId: string) => void;
  commitNewAssetFolder: () => void | Promise<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;
  toggleAllAssetsSelected: () => void;
  deleteSelectedAssets: () => void;
  closeAssetSelectionMode: () => void;
};

export function ImageCanvasAssetLibraryPanelView({
  assetListRef,
  assetPointerDragRef,
  suppressAssetClickRef,
  groupedAssets,
  assetFolders,
  isAssetSelectionMode,
  selectedAssetIds,
  assetMoveDropFolderId,
  pinnedAssetMoveFolderId,
  creatingFolder,
  newFolderName,
  renamingFolder,
  renamingAsset,
  allSelectableAssetsSelected,
  assetMarquee,
  setCreatingFolder,
  setNewFolderName,
  setRenamingFolder,
  setRenamingAsset,
  setActiveUploadFolderId,
  setUploadDropTarget,
  setAssetPointerDrag,
  setSelectedAssetIds,
  onAssetMarqueePointerDown,
  onAssetMarqueePointerMove,
  onAssetMarqueePointerUp,
  updateAssetMoveDropFolder,
  addUploadedFiles,
  requestUpload,
  moveAssetToFolder,
  commitNewAssetFolder,
  toggleAssetFolder,
  startRenamingFolder,
  commitFolderRename,
  deleteAssetFolder,
  startRenamingAsset,
  commitAssetRename,
  deleteUploadedAsset,
  toggleAssetSelected,
  addAssetLayer,
  toggleAllAssetsSelected,
  deleteSelectedAssets,
  closeAssetSelectionMode,
}: ImageCanvasAssetLibraryPanelViewProps) {
  return (
    <div
      ref={assetListRef}
      className="image-canvas-editor__asset-list"
      onPointerDown={onAssetMarqueePointerDown}
      onPointerMove={onAssetMarqueePointerMove}
      onPointerUp={onAssetMarqueePointerUp}
      onPointerCancel={onAssetMarqueePointerUp}
    >
      {pinnedAssetMoveFolderId ? (
        <div
          className="image-canvas-editor__asset-folder-sticky-target"
          aria-hidden="true"
        >
          <Folder className="h-4 w-4" />
          <span>
            {assetFolders.find((folder) => folder.id === pinnedAssetMoveFolderId)
              ?.label ?? '目标文件夹'}
          </span>
        </div>
      ) : null}
      {creatingFolder ? (
        <form
          className="image-canvas-editor__folder-create"
          onSubmit={(event) => {
            event.preventDefault();
            void commitNewAssetFolder();
          }}
        >
          <PlatformTextField
            aria-label="素材文件夹名称"
            value={newFolderName}
            autoFocus
            size="xs"
            density="compact"
            className="image-canvas-editor__folder-create-input"
            onChange={(event) => setNewFolderName(event.target.value)}
            onKeyDown={(event) => {
              if (event.key === 'Escape') {
                event.preventDefault();
                setCreatingFolder(false);
                setNewFolderName('');
              }
            }}
          />
          <EditorIconButton type="submit" label="保存素材文件夹" icon={Check} />
          <EditorIconButton
            label="取消新建素材文件夹"
            icon={X}
            onClick={() => {
              setCreatingFolder(false);
              setNewFolderName('');
            }}
          />
        </form>
      ) : null}
      {groupedAssets.map((folder) => (
        <ImageCanvasAssetFolderSectionView
          key={folder.id}
          folder={folder}
          assetPointerDragRef={assetPointerDragRef}
          suppressAssetClickRef={suppressAssetClickRef}
          isAssetSelectionMode={isAssetSelectionMode}
          selectedAssetIds={selectedAssetIds}
          assetMoveDropFolderId={assetMoveDropFolderId}
          renamingFolder={renamingFolder}
          renamingAsset={renamingAsset}
          setRenamingFolder={setRenamingFolder}
          setRenamingAsset={setRenamingAsset}
          setActiveUploadFolderId={setActiveUploadFolderId}
          setUploadDropTarget={setUploadDropTarget}
          setAssetPointerDrag={setAssetPointerDrag}
          setSelectedAssetIds={setSelectedAssetIds}
          updateAssetMoveDropFolder={updateAssetMoveDropFolder}
          addUploadedFiles={addUploadedFiles}
          requestUpload={requestUpload}
          moveAssetToFolder={moveAssetToFolder}
          toggleAssetFolder={toggleAssetFolder}
          startRenamingFolder={startRenamingFolder}
          commitFolderRename={commitFolderRename}
          deleteAssetFolder={deleteAssetFolder}
          startRenamingAsset={startRenamingAsset}
          commitAssetRename={commitAssetRename}
          deleteUploadedAsset={deleteUploadedAsset}
          toggleAssetSelected={toggleAssetSelected}
          addAssetLayer={addAssetLayer}
        />
      ))}
      {isAssetSelectionMode ? (
        <PlatformBatchActionToolbar
          className="image-canvas-editor__asset-batch-toolbar"
          label="素材批量操作"
        >
          <PlatformActionButton
            tone="secondary"
            size="sm"
            onClick={toggleAllAssetsSelected}
          >
            {allSelectableAssetsSelected ? (
              <CheckSquare className="h-4 w-4" />
            ) : (
              <Square className="h-4 w-4" />
            )}
            {selectedAssetIds.size > 0
              ? `${allSelectableAssetsSelected ? '取消全选' : '全选'} · 已选 ${selectedAssetIds.size}`
              : '全选'}
          </PlatformActionButton>
          <PlatformActionButton
            tone="warning"
            size="sm"
            disabled={selectedAssetIds.size === 0}
            onClick={deleteSelectedAssets}
          >
            <Trash2 className="h-4 w-4" />
            删除
          </PlatformActionButton>
          <PlatformActionButton
            tone="secondary"
            size="sm"
            onClick={closeAssetSelectionMode}
          >
            取消
          </PlatformActionButton>
        </PlatformBatchActionToolbar>
      ) : null}
      {assetMarquee ? (
        <div
          className="image-canvas-editor__asset-marquee"
          aria-hidden="true"
          style={{
            left: Math.min(assetMarquee.startX, assetMarquee.currentX),
            top: Math.min(assetMarquee.startY, assetMarquee.currentY),
            width: Math.abs(assetMarquee.currentX - assetMarquee.startX),
            height: Math.abs(assetMarquee.currentY - assetMarquee.startY),
          }}
        />
      ) : null}
    </div>
  );
}
