import { generateImage } from './lib/image-generator';
import { generateVideo } from './lib/video-generator';
import { logger } from './lib/logger';
import { Scene } from './types';
import scenes from './scenes/space.json';
import dotenv from 'dotenv';

dotenv.config();

const COMFY_BASE_URL = process.env.COMFY_BASE_URL;
const COMFY_OUTPUT_DIR = process.env.COMFY_OUTPUT_DIR;

interface ProcessedScene {
    scene: Scene;
    generatedImagePath: string;
}

async function prepareImageForScene(scene: Scene): Promise<ProcessedScene | null> {
    if (!COMFY_BASE_URL || !COMFY_OUTPUT_DIR) {
        logger.error('COMFY_BASE_URL and COMFY_OUTPUT_DIR must be set in the environment variables.');
        return null;
    }

    try {
        const startTime = Date.now();
        logger.info(`--- Preparing image for scene: ${scene.idea} ---`);

        const timestamp = new Date().getTime();
        const imageFileName = `${scene.idea.replace(/\s/g, '_')}_${timestamp}.png`;
        const generatedImagePath = await generateImage(
            scene.image_prompt,
            imageFileName,
            COMFY_BASE_URL,
            COMFY_OUTPUT_DIR,
            'flux',
            { width: 1280, height: 720 }
        );
        logger.debug(`Generated new image from prompt, saved to: ${generatedImagePath}`);

        const endTime = Date.now();
        const durationInSeconds = (endTime - startTime) / 1000;
        logger.info(`--- Finished preparing image for scene: ${scene.idea} in ${durationInSeconds.toFixed(2)} seconds ---`);
        return { scene, generatedImagePath };
    } catch (error) {
        logger.error(`Failed to prepare image for scene "${scene.idea}":`, error);
        return null;
    }
}

async function generateVideoForScene(processedScene: ProcessedScene) {
    if (!COMFY_BASE_URL || !COMFY_OUTPUT_DIR) {
        logger.error('COMFY_BASE_URL and COMFY_OUTPUT_DIR must be set in the environment variables.');
        return;
    }

    const { scene, generatedImagePath } = processedScene;
    try {
        const startTime = Date.now();
        logger.info(`--- Generating video for scene: ${scene.idea} ---`);
        const timestamp = new Date().getTime();
        const videoFileName = `${scene.idea.replace(/\s/g, '_')}_${timestamp}.mp4`;
        await generateVideo(
            scene.video_prompt,
            generatedImagePath,
            videoFileName,
            COMFY_BASE_URL,
            COMFY_OUTPUT_DIR,
            { width: 1280, height: 720 }
        );
        const endTime = Date.now();
        const durationInSeconds = (endTime - startTime) / 1000;
        logger.info(`--- Finished generating video for scene: ${scene.idea} in ${durationInSeconds.toFixed(2)} seconds ---`);
    } catch (error) {
        logger.error(`Failed to generate video for scene "${scene.idea}":`, error);
    }
}


(async () => {
    const allScenes: Scene[] = scenes;

    while (true) {
        const preparedImages: ProcessedScene[] = [];
        logger.info('--- Starting image preparation phase ---');
        for (const scene of allScenes) {
            const result = await prepareImageForScene(scene);
            if (result) {
                preparedImages.push(result);
            }
        }
        logger.info('--- Finished image preparation phase ---');

        logger.info('--- Starting video generation phase ---');
        for (const processedScene of preparedImages) {
            await generateVideoForScene(processedScene);
        }
        logger.info('--- Finished video generation phase ---');
    }
})();
