import React from 'react';
import { useShallow } from 'zustand/react/shallow';
import { AppNodeData } from '../types/node';
import { useAssetSaver } from './useAssetSaver';
import { useProjectStore } from '@lib/store/project';
import { GenerationRecord, AssetType } from '@/types';
import { useCanvasEvents } from './useCanvasEvents';
import { useCanvasContext } from '../CanvasContext';
import { getStorageDownloadUrl } from '@/lib/api/urls';

export const useNodeActions = (
    id: string,
    data: AppNodeData,
    update: (data: Partial<AppNodeData>) => void
) => {
    const { saveAsset } = useAssetSaver();
    const { activeCanvasId, activeCanvasType } = useCanvasContext();
    const { updateStoryboard, storyboards, selectedStoryboardId } = useProjectStore(
        useShallow((s) => ({
            updateStoryboard: s.updateStoryboard,
            storyboards: s.storyboards,
            selectedStoryboardId: s.selectedStoryboardId,
        }))
    );
    
    const { 
        setExpandedMedia, 
        setCropRequest, 
        setMediaContextMenu,
        setHandleClick 
    } = useCanvasEvents();

    const handleDownload = async () => {
        const src = data.image || data.videoUri || data.audioUri;
        if (!src) return;

        const triggerDownloadFromUrl = (url: string) => {
            const a = document.createElement('a');
            a.href = url;
            a.download = `canvas-${Date.now()}`;
            a.rel = 'noopener noreferrer';
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
        };

        // 统一走后端下载接口，由后端设置 Content-Disposition=attachment，避免浏览器直接在当前页打开
        try {
            // 推断一个文件名：优先用节点标题，其次从 URL path 中取最后一段
            let filename = data.title || 'canvas';
            try {
                const parsed = new URL(src, window.location.origin);
                const candidate = parsed.pathname.split('/').filter(Boolean).pop();
                if (candidate) {
                    filename = candidate;
                }
            } catch {
                // src 可能是相对路径或非标准 URL，忽略解析错误
            }

            const apiUrl = getStorageDownloadUrl(src);
            triggerDownloadFromUrl(apiUrl);
        } catch (e) {
            console.warn('Failed to trigger download via storage download API, falling back to direct src', e);
            triggerDownloadFromUrl(src);
        }
    };

    const handleExpand = () => {
        setExpandedMedia({
            type: data.videoUri ? 'video' : 'image',
            src: data.videoUri || data.image || '',
            nodeId: id
        });
    };

    const handleMediaContextMenu = (e: React.MouseEvent, type: 'image' | 'video', src: string) => {
        e.preventDefault();
        e.stopPropagation();
        setMediaContextMenu({
            nodeId: id,
            type,
            src,
            x: e.clientX,
            y: e.clientY
        });
    };

    const handleCropRequest = (src: string) => {
        setCropRequest({
            nodeId: id,
            src
        });
    };
    
    const handleHandleClick = (e: React.MouseEvent, type: 'source') => {
        e.stopPropagation();
        setHandleClick({
            nodeId: id,
            handleType: type,
            x: e.clientX,
            y: e.clientY
        });
    };

    const handleSaveToAssets = (targetType: AssetType = 'scene') => {
        const src = data.image || data.videoUri || data.audioUri;
        if (!src) return;
        
        const isVideo = !!data.videoUri;
        const isAudio = !!data.audioUri;
        
        saveAsset(
            isAudio ? 'audio' : (isVideo ? 'video' : 'image'),
            src,
            data.title || `Asset ${Date.now()}`,
            {
                prompt: data.prompt,
                model: data.model,
                params: {
                    aspectRatio: data.aspectRatio,
                    ...(isVideo && data.duration ? { duration: parseInt(data.duration) || 0 } : {}),
                }
            }
        );
    };

    const handleSaveToStoryboard = (targetId?: string) => {
        const idToUse = targetId || selectedStoryboardId;
        if (!idToUse) return;
        
        const src = data.image || data.videoUri;
        if (!src) return;
        
        const isVideo = !!data.videoUri;
        const storyboard = storyboards.find(s => s.id === idToUse);
        if (!storyboard) return;

        const generationRecord: GenerationRecord = {
            id: crypto.randomUUID(),
            timestamp: Date.now(),
            status: 'success',
            model: data.model || 'unknown',
            prompt: data.prompt || '',
            resultUrl: src,
            type: isVideo ? 'video' : 'image',
            params: {
                aspectRatio: data.aspectRatio,
                ...(isVideo && data.duration ? { duration: parseInt(data.duration) || 0 } : {}),
            }
        } as GenerationRecord;

        if (isVideo) {
             updateStoryboard(idToUse, { 
                 videoUrls: [...(storyboard.videoUrls || []), src],
                 generations: [...(storyboard.generations || []), generationRecord]
             });
        } else {
             updateStoryboard(idToUse, { 
                 imageUrls: [...(storyboard.imageUrls || []), src],
                 generations: [...(storyboard.generations || []), generationRecord]
             });
        }
    };

    const handleSmartSave = () => {
        // 1. Storyboard Context
        const currentStoryboardId = selectedStoryboardId || (activeCanvasType === 'storyboard' ? activeCanvasId : null);
        
        if (currentStoryboardId) {
            handleSaveToStoryboard(currentStoryboardId);
            return;
        } 
        
        // 2. Asset Context (Check if we are in an asset canvas)
        // Check 1: Explicit Node Context (inherited from creation)
        if (data.assetInfo?.id) {
            const src = data.image || data.videoUri || data.audioUri;
            if (!src) return;
            
            const isVideo = !!data.videoUri;
            const isAudio = !!data.audioUri;
            
            saveAsset(
                isAudio ? 'audio' : (isVideo ? 'video' : 'image'),
                src,
                data.title || data.assetInfo.name,
                {
                    prompt: data.prompt,
                    model: data.model,
                    params: {
                        aspectRatio: data.aspectRatio,
                        ...(isVideo && data.duration ? { duration: parseInt(data.duration) || 0 } : {}),
                    }
                },
                { assetId: data.assetInfo.id }
            );
            return;
        }

        // Check 2: Global Canvas Context (Fallback if node context is missing)
        if (activeCanvasType === 'asset' && activeCanvasId) {
             const src = data.image || data.videoUri || data.audioUri;
             if (!src) return;
             
             const isVideo = !!data.videoUri;
             const isAudio = !!data.audioUri;
             
             saveAsset(
                 isAudio ? 'audio' : (isVideo ? 'video' : 'image'),
                 src,
                 data.title || `Asset ${Date.now()}`,
                 {
                     prompt: data.prompt,
                     model: data.model,
                     params: {
                         aspectRatio: data.aspectRatio,
                         ...(isVideo && data.duration ? { duration: parseInt(data.duration) || 0 } : {}),
                     }
                 },
                 { assetId: activeCanvasId } // Explicitly pass the active asset ID
             );
             return;
        }

        // 3. Fallback: Create New Asset (Default behavior)
        handleSaveToAssets('scene');
    };

    return {
        handleDownload,
        handleExpand,
        handleMediaContextMenu,
        handleCropRequest,
        handleSaveToAssets,
        handleSaveToStoryboard,
        handleSmartSave,
        handleHandleClick
    };
};
