"""Mock video provider for testing and development."""
import asyncio
import uuid
from pathlib import Path
from typing import Optional, Dict, Any
import sys

sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent))

from services.video.providers.base_provider import VideoProvider
from shared.config import settings
from shared.logging_config import setup_logging

logger = setup_logging("video.mock")


class MockVideoProvider(VideoProvider):
    """Mock video provider that simulates video generation."""
    
    def __init__(self):
        """Initialize mock provider."""
        super().__init__("mock")
        self.jobs = {}
    
    async def generate(
        self,
        prompt: str,
        duration: int,
        resolution: str = "1080p",
        fps: int = 30,
        style: Optional[str] = None,
        **kwargs
    ) -> Dict[str, Any]:
        """Simulate video generation.
        
        Args:
            prompt: Text description
            duration: Duration in seconds
            resolution: Video resolution
            fps: Frames per second
            style: Visual style
            **kwargs: Additional parameters
            
        Returns:
            Job information
        """
        job_id = str(uuid.uuid4())
        width, height = self.get_resolution_dimensions(resolution)
        
        logger.info(f"[{job_id}] Mock generating video: {prompt[:50]}...")
        logger.info(f"[{job_id}] Duration: {duration}s, Resolution: {width}x{height}, FPS: {fps}")
        
        # Create job entry
        self.jobs[job_id] = {
            "status": "processing",
            "progress": 0,
            "prompt": prompt,
            "duration": duration,
            "resolution": resolution,
            "fps": fps,
            "style": style,
            "error": None
        }
        
        # Simulate async generation
        asyncio.create_task(self._simulate_generation(job_id, duration))
        
        return {
            "job_id": job_id,
            "status": "processing",
            "message": f"Mock video generation started for {duration}s {resolution} video"
        }
    
    async def generate_with_audio(
        self,
        prompt: str,
        audio_file: str,
        resolution: str = "1080p",
        fps: int = 30,
        style: Optional[str] = None,
        **kwargs
    ) -> Dict[str, Any]:
        """Simulate video generation with audio sync.
        
        Args:
            prompt: Text description
            audio_file: Path to audio file
            resolution: Video resolution
            fps: Frames per second
            style: Visual style
            **kwargs: Additional parameters
            
        Returns:
            Job information
        """
        job_id = str(uuid.uuid4())
        width, height = self.get_resolution_dimensions(resolution)
        
        logger.info(f"[{job_id}] Mock generating video with audio: {audio_file}")
        logger.info(f"[{job_id}] Prompt: {prompt[:50]}...")
        
        # Estimate duration from audio (mock - would use actual audio analysis)
        duration = kwargs.get('duration', 30)
        
        self.jobs[job_id] = {
            "status": "processing",
            "progress": 0,
            "prompt": prompt,
            "audio_file": audio_file,
            "duration": duration,
            "resolution": resolution,
            "fps": fps,
            "style": style,
            "error": None
        }
        
        asyncio.create_task(self._simulate_generation(job_id, duration, with_audio=True))
        
        return {
            "job_id": job_id,
            "status": "processing",
            "message": f"Mock video generation with audio started"
        }
    
    async def check_status(self, job_id: str) -> Dict[str, Any]:
        """Check job status.
        
        Args:
            job_id: Job identifier
            
        Returns:
            Status information
        """
        if job_id not in self.jobs:
            return {
                "status": "not_found",
                "error": "Job not found"
            }
        
        job = self.jobs[job_id]
        
        result = {
            "job_id": job_id,
            "status": job["status"],
            "progress": job["progress"]
        }
        
        if job["status"] == "completed":
            result["video_file"] = job.get("video_file")
            result["metadata"] = {
                "duration": job["duration"],
                "resolution": job["resolution"],
                "fps": job["fps"],
                "file_size": job.get("file_size", 0)
            }
        elif job["status"] == "failed":
            result["error"] = job["error"]
        
        return result
    
    async def _simulate_generation(self, job_id: str, duration: int, with_audio: bool = False):
        """Simulate video generation process.
        
        Args:
            job_id: Job identifier
            duration: Video duration
            with_audio: Whether audio is included
        """
        try:
            # Simulate generation steps
            steps = [
                ("Analyzing prompt", 10),
                ("Generating frames", 40),
                ("Rendering video", 30),
                ("Encoding", 15),
                ("Finalizing", 5)
            ]
            
            if with_audio:
                steps.insert(2, ("Synchronizing with audio", 20))
            
            total_weight = sum(weight for _, weight in steps)
            current_progress = 0
            
            for step_name, weight in steps:
                logger.info(f"[{job_id}] {step_name}...")
                
                # Simulate work
                await asyncio.sleep(1)  # Simulate time
                
                current_progress += int((weight / total_weight) * 100)
                self.jobs[job_id]["progress"] = min(current_progress, 95)
            
            # Create mock video file path
            output_dir = Path(settings.media_root) / "video"
            output_dir.mkdir(parents=True, exist_ok=True)
            
            video_file = output_dir / f"{job_id}.mp4"
            
            # Create empty file as placeholder
            video_file.touch()
            
            # Update job as completed
            self.jobs[job_id].update({
                "status": "completed",
                "progress": 100,
                "video_file": str(video_file),
                "file_size": 1024 * 1024 * 5  # Mock 5MB file
            })
            
            logger.info(f"[{job_id}] Mock generation completed: {video_file}")
            
        except Exception as e:
            logger.error(f"[{job_id}] Mock generation failed: {e}")
            self.jobs[job_id].update({
                "status": "failed",
                "error": str(e)
            })


# Singleton instance
_mock_provider = None


def get_mock_provider() -> MockVideoProvider:
    """Get singleton mock provider instance.
    
    Returns:
        MockVideoProvider instance
    """
    global _mock_provider
    if _mock_provider is None:
        _mock_provider = MockVideoProvider()
    return _mock_provider
