/**
 * DeskDropZone — 工作台区域的拖放包装容器
 */

import { useCallback, useEffect, useState } from 'react';
import {
  deskCurrentDir,
  deskUploadFiles,
  deskUploadBrowserFilesToSubdir,
  deskUploadFilesToSubdir,
  deskCreateFile,
  deskMoveTreeFiles,
} from '../../stores/desk-actions';
import {
  clearAppFileDragPayload,
  readAppFileDragPayload,
} from '../../utils/app-file-drag';
import { isWebRuntime } from '../../utils/platform-runtime';
import type { CtxMenuState } from './desk-types';
import type { InlineCreateKind } from './DeskTree';
import s from './Desk.module.css';

export function DeskDropZone({
  children,
  onShowMenu,
  onStartCreate,
  framed = true,
  rightWorkspaceLayout = false,
}: {
  children: React.ReactNode;
  onShowMenu: (state: CtxMenuState) => void;
  onStartCreate: (parentSubdir: string, kind: InlineCreateKind) => Promise<void>;
  framed?: boolean;
  rightWorkspaceLayout?: boolean;
}) {
  const [dragging, setDragging] = useState(false);

  useEffect(() => {
    if (!dragging) return undefined;
    const clear = () => setDragging(false);
    window.addEventListener('dragend', clear);
    window.addEventListener('drop', clear);
    window.addEventListener('blur', clear);
    return () => {
      window.removeEventListener('dragend', clear);
      window.removeEventListener('drop', clear);
      window.removeEventListener('blur', clear);
    };
  }, [dragging]);

  const handleDragOver = useCallback((e: React.DragEvent) => {
    const payload = readAppFileDragPayload(e.dataTransfer);
    if (payload?.source === 'workspace' && (e.target as HTMLElement).closest('[data-desk-item]')) {
      e.preventDefault();
      e.stopPropagation();
      e.dataTransfer.dropEffect = 'none';
      setDragging(false);
      return;
    }
    e.preventDefault();
    e.stopPropagation();
    setDragging(true);
  }, []);

  const handleDragLeave = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    const section = e.currentTarget;
    if (!section.contains(e.relatedTarget as Node)) {
      setDragging(false);
    }
  }, []);

  const handleContextMenu = useCallback((e: React.MouseEvent) => {
    if ((e.target as HTMLElement).closest('[data-desk-item]')) return;
    if ((e.target as HTMLElement).closest('[data-desk-editor]')) return;
    e.preventDefault();
    e.stopPropagation();
    const tFn = window.t ?? ((p: string) => p);
    onShowMenu({
      position: { x: e.clientX, y: e.clientY },
      items: [
        { label: tFn('desk.ctx.newMdFile'), action: () => { void onStartCreate('', 'markdown'); } },
        { label: tFn('desk.ctx.newFolder'), action: () => { void onStartCreate('', 'folder'); } },
        ...(!isWebRuntime() ? [
          { label: tFn('desk.ctx.openInFinder'), action: () => { const p = deskCurrentDir(); if (p) window.platform?.showInFinder?.(p); } },
        ] : []),
      ],
    });
  }, [onShowMenu, onStartCreate]);

  const handleDrop = useCallback(async (e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setDragging(false);

    // 如果 drop 目标在技能面板内，让技能面板自己处理，这里不复制文件
    if ((e.target as HTMLElement).closest('[data-desk-cwd-panel]')) return;

    const payload = readAppFileDragPayload(e.dataTransfer);
    if (payload?.source === 'workspace') {
      clearAppFileDragPayload(payload.dragId);
      if ((e.target as HTMLElement).closest('[data-desk-item]')) return;
      const items = payload.files
        .filter(item => item.sourceSubdir !== undefined)
        .filter(item => (item.sourceSubdir || '').replace(/^\/+|\/+$/g, '') !== '')
        .map(item => ({
          sourceSubdir: (item.sourceSubdir || '').replace(/^\/+|\/+$/g, ''),
          name: item.name,
          isDirectory: item.isDirectory,
        }));
      if (items.length > 0) await deskMoveTreeFiles(items, '');
      return;
    }
    if (payload?.source === 'session-file') {
      clearAppFileDragPayload(payload.dragId);
      const paths = payload.files.map(file => file.path).filter(Boolean);
      if (paths.length > 0) await deskUploadFilesToSubdir(paths, '');
      return;
    }

    const files = e.dataTransfer.files;
    const text = e.dataTransfer.getData('text/plain');

    if (files && files.length > 0) {
      if (isWebRuntime()) {
        await deskUploadBrowserFilesToSubdir(Array.from(files), '');
        return;
      }
      const paths: string[] = [];
      for (const f of Array.from(files)) {
        const p = window.platform?.getFilePath?.(f);
        if (p) paths.push(p);
      }
      if (paths.length > 0) {
        await deskUploadFiles(paths);
      }
    } else if (text) {
      await deskCreateFile(text);
    }
  }, []);

  const className = [
    framed ? 'jian-card' : '',
    s.section,
    rightWorkspaceLayout ? s.rightWorkspaceSection : '',
    dragging ? s.dragOver : '',
  ].filter(Boolean).join(' ');

  return (
    <div
      className={className}
      onDragOver={handleDragOver}
      onDragLeave={handleDragLeave}
      onDrop={handleDrop}
      onContextMenu={handleContextMenu}
    >
      {children}
    </div>
  );
}
