import { NodeExecutionStrategy, ExecutionContext } from '../types';
import { editImageWithText, generateCharacterPrompt, generateLyrics } from '../../canvasService';
import { AppNodeData } from '../../../types/node';

export class ImageEditorStrategy implements NodeExecutionStrategy {
    async execute(context: ExecutionContext): Promise<void> {
        const { 
            nodeId, node, inputs, prompt, 
            updateNodeData, addHistoryItem,
            getImageModelDefault
        } = context;

        if (node.type !== 'appNode') return;
        const nodeData = node.data as AppNodeData;

        const inputImages: string[] = [];
        inputs.forEach(n => { 
            if (n.type === 'appNode') {
                const data = n.data as AppNodeData;
                if (data.image) inputImages.push(data.image);
                if (data.images && Array.isArray(data.images)) inputImages.push(...data.images);
            }
        });
        
        const img = nodeData.image || inputImages[0];
        if (!img) throw new Error("未找到图片输入");

        const res = await editImageWithText(img, prompt || '', nodeData.model || getImageModelDefault());
        updateNodeData(nodeId, { image: res, status: 'SUCCESS' });
        
        addHistoryItem({
            id: `gen-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
            type: 'image',
            src: res,
            title: nodeData.title || 'Edited Image',
            timestamp: Date.now(),
            model: nodeData.model
        });
    }
}

export class PromptGeneratorStrategy implements NodeExecutionStrategy {
    async execute(context: ExecutionContext): Promise<void> {
        const { 
            nodeId, node, prompt, updateNodeData, upstreamTexts
        } = context;

        if (node.type !== 'appNode') return;
        const nodeData = node.data as AppNodeData;

        const combinedUpstream = upstreamTexts.join('\n');
        const userInput = nodeData.userPrompt || nodeData.prompt || '';
        
        const isStoryboardContext = combinedUpstream.includes('[Storyboard Shot Description]');
        
        let template = nodeData.template;
        const targetType = nodeData.targetType || 'image';
        
        if (!template && isStoryboardContext) {
             template = targetType === 'video' ? 'storyboard_video_integrated' : 'storyboard_integrated';
        }
        
        const optimized = await generateCharacterPrompt(
            userInput, 
            combinedUpstream,
            {
                targetType,
                template
            }
        );
        updateNodeData(nodeId, { prompt: optimized, status: 'SUCCESS' });
    }
}

export class LyricsStrategy implements NodeExecutionStrategy {
    async execute(context: ExecutionContext): Promise<void> {
        const { nodeId, node, prompt, updateNodeData, projectId } = context;
        if (node.type !== 'appNode') return;

        const nodeData = node.data as AppNodeData;
        const result = await generateLyrics(prompt || nodeData.prompt || '', {
            model: nodeData.model,
            mode: 'write_full_song',
            projectId,
            onTaskId: (taskId) => updateNodeData(nodeId, { taskId }),
        });

        const nextTitle = result.songTitle?.trim() ? result.songTitle : (nodeData.title || '歌词生成');
        updateNodeData(nodeId, {
            title: nextTitle,
            lyrics: result.lyrics,
            status: 'SUCCESS',
            taskId: undefined,
        });
    }
}

export class GenericSuccessStrategy implements NodeExecutionStrategy {
    async execute(context: ExecutionContext): Promise<void> {
        const { nodeId, updateNodeData } = context;
        setTimeout(() => {
            updateNodeData(nodeId, { status: 'SUCCESS' });
        }, 500);
    }
}
