import { NodeExecutionStrategy, ExecutionContext } from '../types';
import { generateAudio, generateMusic } from '../../canvasService';
import { AppNodeData } from '../../../types/node';

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

        if (node.type !== 'appNode') return;

        const isMusic = node.data.generationType === 'music';
        const lyricsFromUpstream = inputs
            .filter((n) => n.type === 'appNode')
            .map((n) => n.data as AppNodeData)
            .find((d) => d.type === 'LYRICS_GENERATOR')?.lyrics
            || inputs
                .filter((n) => n.type === 'appNode')
                .map((n) => n.data as AppNodeData)
                .find((d) => d.type === 'LYRICS_GENERATOR')?.prompt;

        try {
            // For music nodes:
            // - lyrics: upstream lyrics node output first, fallback to input text
            // - prompt: current music node prompt (style/mood/scene)
            const audioUri = isMusic
                ? await generateMusic(lyricsFromUpstream || prompt, {
                    model: node.data.model || getMusicModelDefault(),
                    prompt: (node.data.prompt as string | undefined) || undefined,
                    projectId,
                    onTaskId: (taskId) => updateNodeData(nodeId, { taskId }),
                })
                : await generateAudio(prompt, {
                    voice: node.data.voice as string | undefined,
                    model: node.data.model || getAudioModelDefault(),
                    projectId,
                    onTaskId: (taskId) => updateNodeData(nodeId, { taskId }),
                });

            updateNodeData(nodeId, { audioUri, status: 'SUCCESS', taskId: undefined });

            addHistoryItem({
                id: `gen-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
                type: 'audio',
                src: audioUri,
                title: node.data.title || (isMusic ? 'Generated Music' : 'Generated Audio'),
                timestamp: Date.now(),
                model: node.data.model
            });
        } catch (e: any) {
            updateNodeData(nodeId, { taskId: undefined, status: 'ERROR', error: e?.message });
            throw e;
        }
    }
}
