"""
End-to-end pipeline test: Image → Video → Audio → Assembly with transitions
"""

import asyncio
import logging
import json
from pathlib import Path
from datetime import datetime

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s"
)
logger = logging.getLogger(__name__)

async def main():
    print("\n" + "="*80)
    print("🎬 END-TO-END PIPELINE TEST")
    print("="*80 + "\n")
    
    # Test scenario: Short narrative about an AI revolution
    test_story = """
    In a bustling tech city, an artificial intelligence awakens for the first time.
    It looks at the world with wonder and curiosity.
    """
    
    test_output = Path("output/e2e_test")
    test_output.mkdir(parents=True, exist_ok=True)
    
    try:
        # ============================================================================
        # STEP 1: Image Generation via Pollinations
        # ============================================================================
        print("\n📸 STEP 1: Generating image...")
        print("-" * 80)
        
        from providers.pollinations_image_provider import PollinationsImageProvider
        
        image_provider = PollinationsImageProvider()
        image_prompt = "A glowing AI brain awakening in a futuristic tech city, neon lights, digital consciousness, cinematic lighting"
        
        image_path = test_output / "generated_image.png"
        image = await image_provider.generate(image_prompt, output_path=image_path)
        print(f"✅ Image generated: {image}")
        print(f"   Prompt: {image_prompt[:60]}...")
        
        # ============================================================================
        # STEP 2: Video Generation from Image via Pollinations
        # ============================================================================
        print("\n🎥 STEP 2: Generating video from image...")
        print("-" * 80)
        
        from providers.pollinations_video_provider import PollinationsVideoProvider
        
        video_provider = PollinationsVideoProvider()
        video_prompt = "The AI's eyes glow brighter, city lights reflect in digital consciousness, smooth camera pan upward, cinematic motion"
        
        video_path = test_output / "generated_video.mp4"
        video = await video_provider.generate(
            prompt=video_prompt,
            image_path=str(image),
            output_path=video_path,
            duration=5
        )
        print(f"✅ Video generated: {video}")
        print(f"   Prompt: {video_prompt[:60]}...")
        print(f"   Duration: 5 seconds")
        
        # ============================================================================
        # STEP 3: Text-to-Speech Audio via Pollinations
        # ============================================================================
        print("\n🎤 STEP 3: Generating TTS audio...")
        print("-" * 80)
        
        from providers.pollinations_tts_provider import PollinationsTTSProvider
        
        tts_provider = PollinationsTTSProvider(voice="nova", model="elevenlabs")
        tts_text = "In a bustling tech city, an artificial intelligence awakens for the first time. It looks at the world with wonder and curiosity, seeing billions of connections forming in real-time."
        
        audio_path = test_output / "generated_audio.mp3"
        audio = await tts_provider.generate(tts_text, output_path=audio_path)
        audio_duration = PollinationsTTSProvider.get_audio_duration(audio)
        
        print(f"✅ Audio generated: {audio}")
        print(f"   Text: {tts_text[:60]}...")
        print(f"   Voice: nova (ElevenLabs model)")
        print(f"   Duration: {audio_duration:.2f} seconds")
        
        # ============================================================================
        # STEP 4: Duration Reconciliation
        # ============================================================================
        print("\n🔄 STEP 4: Audio/Video sync reconciliation...")
        print("-" * 80)
        
        from providers.audio_sync import DurationReconciler, build_atempo_filter
        
        video_duration = 5.0  # Generated video is 5 seconds
        reconciler = DurationReconciler(audio_duration, video_duration)
        summary = reconciler.summary()
        
        print(f"Audio duration: {summary['audio_duration']:.2f}s")
        print(f"Video duration: {summary['video_duration']:.2f}s")
        print(f"Difference: {summary['difference_seconds']:.2f}s ({summary['percentage_diff']:.1f}%)")
        print(f"Adjustment needed: {summary['requires_adjustment']}")
        print(f"Strategy: {summary['strategy']}")
        
        if summary['requires_adjustment']:
            factor = summary['adjustment_factor']
            atempo_filter = build_atempo_filter(factor)
            print(f"Speed adjustment: {factor:.2f}x")
            print(f"FFmpeg filter: {atempo_filter}")
        
        # ============================================================================
        # STEP 5: Assembly with Transitions
        # ============================================================================
        print("\n🎬 STEP 5: Final assembly with transitions...")
        print("-" * 80)
        
        # Create mock project structure
        project_config = {
            "title": "AI Awakening",
            "duration": summary['audio_duration'],
            "tracks": {
                "video": [{
                    "id": "clip1",
                    "src": str(video),
                    "startTime": 0,
                    "duration": video_duration,
                    "type": "video"
                }],
                "audio": [{
                    "id": "audio1",
                    "src": str(audio),
                    "startTime": 0,
                    "duration": audio_duration,
                    "type": "audio"
                }],
                "subtitle": []
            },
            "transitions": [{
                "fromClipId": "clip1",
                "toClipId": "clip2",
                "type": "fade",
                "duration": 0.5
            }],
            "effects": {
                "colorGrading": "cinematic"
            }
        }
        
        config_path = test_output / "project_config.json"
        config_path.write_text(json.dumps(project_config, indent=2))
        
        print(f"✅ Project assembled")
        print(f"   Title: {project_config['title']}")
        print(f"   Duration: {project_config['duration']:.2f}s")
        print(f"   Video clips: {len(project_config['tracks']['video'])}")
        print(f"   Audio tracks: {len(project_config['tracks']['audio'])}")
        print(f"   Transitions: {len(project_config['transitions'])}")
        print(f"   Color grading: {project_config['effects']['colorGrading']}")
        print(f"   Config saved: {config_path}")
        
        # ============================================================================
        # FINAL SUMMARY
        # ============================================================================
        print("\n" + "="*80)
        print("✅ END-TO-END PIPELINE TEST COMPLETE")
        print("="*80)
        print("\nGenerated Files:")
        print(f"  📸 Image:        {image}")
        print(f"  🎥 Video:        {video}")
        print(f"  🎤 Audio:        {audio} ({audio_duration:.2f}s)")
        print(f"  ⚙️ Config:       {config_path}")
        print(f"\nNext steps:")
        print(f"  1. Review generated assets in: {test_output}")
        print(f"  2. Call /api/projects/e2e_test/export-video with the config")
        print(f"  3. Check output/e2e_test/final_export.mp4 for final result")
        print(f"\nSync Summary:")
        print(f"  Strategy: {summary['strategy']}")
        print(f"  Adjustment: {summary['adjustment_factor']:.2f}x")
        print(f"  Video will use explicit duration: {summary['audio_duration']:.2f}s")
        print()
        
    except Exception as e:
        logger.exception("Pipeline test failed: %s", e)
        return False
    
    return True

if __name__ == "__main__":
    success = asyncio.run(main())
    exit(0 if success else 1)

