// ============================================================
// useDirectoryScan — 目录扫描 Hook
//
// 根据 selectedProject / selectedEpisode / selectedShot / currentStage
// 智能选择扫描策略：
//   - Assets 阶段 → scanAssetFiles（深度递归扫描 assets/）
//   - 非 Assets 阶段 → scanStageFiles（扫描 shots/{ep}/{shot}/{stage}/）
//
// 防抖 300ms，窗口聚焦时自动重扫。
// ============================================================

import { useEffect, useRef, useCallback } from 'react';
import { logger } from '@/shared/utils/bus';
import { useCanvasStore } from '../stores/useCanvasStore';

export function useDirectoryScan() {
    // 选择性订阅
    const workspaceRoot = useCanvasStore((s) => s.workspaceRoot);
    const selectedProject = useCanvasStore((s) => s.selectedProject);
    const selectedEpisode = useCanvasStore((s) => s.selectedEpisode);
    const selectedShot = useCanvasStore((s) => s.selectedShot);
    const currentStage = useCanvasStore((s) => s.currentStage);
    const assetTypeFilter = useCanvasStore((s) => s.assetTypeFilter);
    const keywordQuery = useCanvasStore((s) => s.keywordQuery);
    const tagQuery = useCanvasStore((s) => s.tagQuery);

    const clearItems = useCanvasStore((s) => s.clearItems);
    const appendItems = useCanvasStore((s) => s.appendItems);
    const setIsScanning = useCanvasStore((s) => s.setIsScanning);
    const setScanProgress = useCanvasStore((s) => s.setScanProgress);
    const getDataSource = useCanvasStore((s) => s.getDataSource);
    const getProjectPath = useCanvasStore((s) => s.getProjectPath);

    // 扫描 abort 控制器 ref
    const abortRef = useRef<AbortController | null>(null);
    // 防抖 timer
    const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
    // 当前 epoch
    const epochRef = useRef(0);

    const doScan = useCallback(async () => {
        const projectPath = getProjectPath();
        if (!projectPath) {
            console.log('[useDirectoryScan] ⏸️ 跳过扫描：projectPath 为空（未选择项目）');
            clearItems();
            return;
        }

        // 取消之前的扫描
        abortRef.current?.abort();
        const controller = new AbortController();
        abortRef.current = controller;

        const epoch = ++epochRef.current;

        const isAssets = currentStage === 'Assets';

        console.log(`[useDirectoryScan] 🔍 开始扫描 (epoch=${epoch})`, {
            projectPath,
            stage: currentStage,
            isAssets,
            selectedEpisode: selectedEpisode || '(未选)',
            selectedShot: selectedShot || '(未选)',
        });

        if (!isAssets && (!selectedEpisode || !selectedShot)) {
            console.log('[useDirectoryScan] ⏸️ 跳过扫描：非 Assets 阶段需先选择集数和镜头');
            clearItems();
            return;
        }

        const t0 = performance.now();
        setIsScanning(true);
        setScanProgress({ found: 0, currentPath: '' });

        try {
            const dataSource = getDataSource();
            let entries: Array<{ path: string; fileName: string; ext: string; fileSize: number; modifiedAt: string }>;

            if (isAssets) {
                // Assets 阶段：深度递归扫描
                entries = await dataSource.scanAssetFiles({
                    projectPath,
                    assetTypeFilter,
                });
            } else {
                // 非 Assets 阶段：扫描指定镜头的阶段目录
                entries = await dataSource.scanStageFiles({
                    projectPath,
                    episode: selectedEpisode!,
                    shot: selectedShot!,
                    stage: currentStage,
                });
            }

            // Epoch 检查
            if (epoch !== epochRef.current) {
                console.log(`[useDirectoryScan] ⚠️ epoch 过期 (${epoch} → ${epochRef.current})，丢弃结果`);
                return;
            }
            if (controller.signal.aborted) {
                console.log('[useDirectoryScan] ⚠️ 扫描已被 abort，丢弃结果');
                return;
            }

            const elapsed = (performance.now() - t0).toFixed(0);
            console.log(`[useDirectoryScan] ✅ 扫描完成 (epoch=${epoch}, 耗时=${elapsed}ms)`, {
                totalEntries: entries.length,
            });

            clearItems();
            appendItems(entries);
            setScanProgress(null);
        } catch (err) {
            if (controller.signal.aborted || epoch !== epochRef.current) return;
            logger.warn('canvas', '目录扫描失败', err instanceof Error ? err : new Error(String(err)));
        } finally {
            if (epoch === epochRef.current) {
                setIsScanning(false);
            }
        }
    }, [
        selectedProject,
        selectedEpisode,
        selectedShot,
        currentStage,
        assetTypeFilter,
        clearItems,
        appendItems,
        setIsScanning,
        setScanProgress,
        getDataSource,
        getProjectPath,
    ]);

    // 防抖触发扫描
    useEffect(() => {
        if (debounceRef.current) {
            clearTimeout(debounceRef.current);
        }
        debounceRef.current = setTimeout(() => {
            void doScan();
        }, 100);

        return () => {
            if (debounceRef.current) {
                clearTimeout(debounceRef.current);
            }
        };
    }, [doScan, workspaceRoot, keywordQuery, tagQuery]);

    // 窗口聚焦时重新扫描
    useEffect(() => {
        const handleFocus = () => {
            setTimeout(() => {
                void doScan();
            }, 500);
        };
        window.addEventListener('focus', handleFocus);
        return () => window.removeEventListener('focus', handleFocus);
    }, [doScan]);

    return { rescan: doScan };
}
