"""
Create video endpoints: text-to-video and image-to-video generation.
"""

from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form, BackgroundTasks
from sqlalchemy.orm import Session
from typing import Optional, Dict, Any
import uuid

from ...database import get_db
from ...models.content_asset_models import AssetSource, AssetType
from ...services.video_studio import VideoStudioService
from ...services.asset_service import ContentAssetService
from ...utils.auth import get_current_user, require_authenticated_user
from ...utils.logger_utils import get_service_logger
from api.story_writer.task_manager import task_manager
from ..tasks.video_generation import execute_video_generation_task

logger = get_service_logger("video_studio.endpoints.create")

router = APIRouter()


@router.post("/generate")
async def generate_video(
    background_tasks: BackgroundTasks,
    prompt: str = Form(..., description="Text description for video generation"),
    negative_prompt: Optional[str] = Form(None, description="What to avoid in the video"),
    duration: int = Form(5, description="Video duration in seconds", ge=1, le=10),
    resolution: str = Form("720p", description="Video resolution"),
    aspect_ratio: str = Form("16:9", description="Video aspect ratio"),
    motion_preset: str = Form("medium", description="Motion intensity"),
    provider: str = Form("wavespeed", description="AI provider to use"),
    model: str = Form("hunyuan-video-1.5", description="Specific AI model to use"),
    current_user: Dict[str, Any] = Depends(get_current_user),
    db: Session = Depends(get_db),
) -> Dict[str, Any]:
    """
    Generate video from text description using AI models.

    Supports multiple providers and models for optimal quality and cost.
    """
    try:
        user_id = require_authenticated_user(current_user)

        # Initialize services
        video_service = VideoStudioService()
        asset_service = ContentAssetService(db)

        logger.info(f"[VideoStudio] Text-to-video request: user={user_id}, model={model}, duration={duration}s")

        # Generate video
        result = await video_service.generate_text_to_video(
            prompt=prompt,
            negative_prompt=negative_prompt,
            duration=duration,
            resolution=resolution,
            aspect_ratio=aspect_ratio,
            motion_preset=motion_preset,
            provider=provider,
            model=model,
            user_id=user_id,
        )

        if not result.get("success"):
            raise HTTPException(
                status_code=500,
                detail=f"Video generation failed: {result.get('error', 'Unknown error')}"
            )

        # Store in asset library if successful
        video_url = result.get("video_url")
        if video_url:
            asset_metadata = {
                "prompt": prompt,
                "negative_prompt": negative_prompt,
                "duration": duration,
                "resolution": resolution,
                "aspect_ratio": aspect_ratio,
                "motion_preset": motion_preset,
                "provider": provider,
                "model": model,
                "generation_type": "text-to-video",
            }

            asset_service.create_asset(
                user_id=user_id,
                filename=f"video_{uuid.uuid4().hex[:8]}.mp4",
                file_url=video_url,
                asset_type=AssetType.VIDEO,
                source_module=AssetSource.VIDEO_STUDIO,
                asset_metadata=asset_metadata,
                cost=result.get("cost", 0),
                tags=["video_studio", "text-to-video", "ai-generated"]
            )

        logger.info(f"[VideoStudio] Video generated successfully: user={user_id}, url={video_url}")

        return {
            "success": True,
            "video_url": video_url,
            "cost": result.get("cost", 0),
            "estimated_duration": result.get("estimated_duration", duration),
            "model_used": model,
            "provider": provider,
        }

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"[VideoStudio] Text-to-video error: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Video generation failed: {str(e)}")


@router.post("/transform")
async def transform_to_video(
    background_tasks: BackgroundTasks,
    file: UploadFile = File(..., description="Image file to transform"),
    prompt: Optional[str] = Form(None, description="Optional text prompt to guide transformation"),
    duration: int = Form(5, description="Video duration in seconds", ge=1, le=10),
    resolution: str = Form("720p", description="Video resolution"),
    aspect_ratio: str = Form("16:9", description="Video aspect ratio"),
    motion_preset: str = Form("medium", description="Motion intensity"),
    provider: str = Form("wavespeed", description="AI provider to use"),
    model: str = Form("alibaba/wan-2.5", description="Specific AI model to use"),
    current_user: Dict[str, Any] = Depends(get_current_user),
    db: Session = Depends(get_db),
) -> Dict[str, Any]:
    """
    Transform image to video using AI models.

    Supports various motion presets and durations for dynamic video creation.
    """
    try:
        user_id = require_authenticated_user(current_user)

        # Validate file type
        if not file.content_type.startswith('image/'):
            raise HTTPException(status_code=400, detail="File must be an image")

        # Initialize services
        video_service = VideoStudioService()
        asset_service = ContentAssetService(db)

        logger.info(f"[VideoStudio] Image-to-video request: user={user_id}, model={model}, duration={duration}s")

        # Read image file
        image_data = await file.read()

        # Generate video
        result = await video_service.generate_image_to_video(
            image_data=image_data,
            prompt=prompt,
            duration=duration,
            resolution=resolution,
            aspect_ratio=aspect_ratio,
            motion_preset=motion_preset,
            provider=provider,
            model=model,
            user_id=user_id,
        )

        if not result.get("success"):
            raise HTTPException(
                status_code=500,
                detail=f"Video transformation failed: {result.get('error', 'Unknown error')}"
            )

        # Store in asset library if successful
        video_url = result.get("video_url")
        if video_url:
            asset_metadata = {
                "original_image": file.filename,
                "prompt": prompt,
                "duration": duration,
                "resolution": resolution,
                "aspect_ratio": aspect_ratio,
                "motion_preset": motion_preset,
                "provider": provider,
                "model": model,
                "generation_type": "image-to-video",
            }

            asset_service.create_asset(
                user_id=user_id,
                filename=f"video_{uuid.uuid4().hex[:8]}.mp4",
                file_url=video_url,
                asset_type=AssetType.VIDEO,
                source_module=AssetSource.VIDEO_STUDIO,
                asset_metadata=asset_metadata,
                cost=result.get("cost", 0),
                tags=["video_studio", "image-to-video", "ai-generated"]
            )

        logger.info(f"[VideoStudio] Video transformation successful: user={user_id}, url={video_url}")

        return {
            "success": True,
            "video_url": video_url,
            "cost": result.get("cost", 0),
            "estimated_duration": result.get("estimated_duration", duration),
            "model_used": model,
            "provider": provider,
        }

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"[VideoStudio] Image-to-video error: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Video transformation failed: {str(e)}")


@router.post("/generate-async")
async def generate_video_async(
    background_tasks: BackgroundTasks,
    prompt: Optional[str] = Form(None, description="Text description for video generation"),
    image: Optional[UploadFile] = File(None, description="Image file for image-to-video"),
    operation_type: str = Form("text-to-video", description="Operation type: text-to-video or image-to-video"),
    negative_prompt: Optional[str] = Form(None, description="What to avoid in the video"),
    duration: int = Form(5, description="Video duration in seconds", ge=1, le=10),
    resolution: str = Form("720p", description="Video resolution"),
    aspect_ratio: str = Form("16:9", description="Video aspect ratio"),
    motion_preset: str = Form("medium", description="Motion intensity"),
    provider: str = Form("wavespeed", description="AI provider to use"),
    model: str = Form("alibaba/wan-2.5", description="Specific AI model to use"),
    current_user: Dict[str, Any] = Depends(get_current_user),
) -> Dict[str, Any]:
    """
    Generate video asynchronously with polling support.
    
    Returns task_id for polling. Frontend can poll /api/video-studio/task/{task_id}/status
    to get progress updates and final result.
    """
    try:
        user_id = require_authenticated_user(current_user)
        
        # Validate operation type
        if operation_type not in ["text-to-video", "image-to-video"]:
            raise HTTPException(
                status_code=400,
                detail=f"Invalid operation_type: {operation_type}. Must be 'text-to-video' or 'image-to-video'"
            )
        
        # Validate inputs based on operation type
        if operation_type == "text-to-video" and not prompt:
            raise HTTPException(
                status_code=400,
                detail="prompt is required for text-to-video generation"
            )
        
        if operation_type == "image-to-video" and not image:
            raise HTTPException(
                status_code=400,
                detail="image file is required for image-to-video generation"
            )
        
        # Read image data if provided
        image_data = None
        if image:
            image_data = await image.read()
            if len(image_data) == 0:
                raise HTTPException(status_code=400, detail="Image file is empty")
        
        # Create task
        task_id = task_manager.create_task("video_generation")
        
        # Prepare kwargs
        kwargs = {
            "duration": duration,
            "resolution": resolution,
            "model": model,
        }
        if negative_prompt:
            kwargs["negative_prompt"] = negative_prompt
        if aspect_ratio:
            kwargs["aspect_ratio"] = aspect_ratio
        if motion_preset:
            kwargs["motion_preset"] = motion_preset
        
        # Start background task
        background_tasks.add_task(
            execute_video_generation_task,
            task_id=task_id,
            operation_type=operation_type,
            user_id=user_id,
            prompt=prompt,
            image_data=image_data,
            provider=provider,
            **kwargs
        )
        
        logger.info(f"[VideoStudio] Started async video generation: task_id={task_id}, operation={operation_type}, user={user_id}")
        
        return {
            "task_id": task_id,
            "status": "pending",
            "message": f"Video generation started. This may take several minutes. Poll /api/video-studio/task/{task_id}/status for updates."
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"[VideoStudio] Failed to start async video generation: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Failed to start video generation: {str(e)}")
