"""Audio Service API - FastAPI endpoints for audio generation."""
from fastapi import FastAPI, HTTPException, BackgroundTasks, status
from pydantic import BaseModel, Field
from typing import Optional, List
from pathlib import Path
from datetime import datetime
import uuid
import sys

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

from shared.config import settings
from shared.logging_config import setup_logging
from services.audio.audio_models.music_generator import get_music_generator
from services.audio.processing.audio_processor import AudioProcessor

logger = setup_logging("audio.api")

app = FastAPI(
    title="Audio Generation Service",
    description="Music and voice generation API",
    version="1.0.0"
)

# In-memory job tracking (use Redis in production)
jobs = {}


class MusicGenerationRequest(BaseModel):
    """Music generation request."""
    prompt: str = Field(..., description="Text description of the music")
    duration: int = Field(30, ge=5, le=300, description="Duration in seconds")
    style: Optional[str] = Field(None, description="Music style/genre")
    temperature: float = Field(1.0, ge=0.1, le=2.0, description="Creativity level")


class JobResponse(BaseModel):
    """Job response."""
    job_id: str
    status: str
    message: Optional[str] = None


class JobStatusResponse(BaseModel):
    """Job status response."""
    job_id: str
    status: str  # pending, processing, completed, failed
    progress: int  # 0-100
    result: Optional[dict] = None
    error: Optional[str] = None
    created_at: datetime
    completed_at: Optional[datetime] = None


def generate_music_task(job_id: str, request: MusicGenerationRequest):
    """Background task for music generation.
    
    Args:
        job_id: Job ID
        request: Generation request
    """
    try:
        jobs[job_id]["status"] = "processing"
        jobs[job_id]["progress"] = 10
        
        # Get music generator
        generator = get_music_generator()
        
        # Enhance prompt with style if provided
        full_prompt = request.prompt
        if request.style:
            full_prompt = f"{request.style} music: {request.prompt}"
        
        jobs[job_id]["progress"] = 30
        
        # Generate music
        logger.info(f"[{job_id}] Generating music: {full_prompt}")
        audio = generator.generate(
            prompts=[full_prompt],
            duration=request.duration,
            temperature=request.temperature
        )
        
        jobs[job_id]["progress"] = 70
        
        # Save audio
        output_dir = Path(settings.media_root) / "audio"
        output_dir.mkdir(parents=True, exist_ok=True)
        output_path = output_dir / f"{job_id}"
        
        audio_file = generator.save_audio(audio, str(output_path), format="wav")
        
        jobs[job_id]["progress"] = 90
        
        # Normalize audio
        processor = AudioProcessor()
        normalized_path = output_dir / f"{job_id}_normalized.wav"
        processor.normalize_audio(audio_file, str(normalized_path))
        
        # Analyze
        metadata = processor.analyze_audio(str(normalized_path))
        
        jobs[job_id]["status"] = "completed"
        jobs[job_id]["progress"] = 100
        jobs[job_id]["result"] = {
            "audio_file": str(normalized_path),
            "metadata": metadata
        }
        jobs[job_id]["completed_at"] = datetime.utcnow()
        
        logger.info(f"[{job_id}] Generation completed successfully")
        
    except Exception as e:
        logger.error(f"[{job_id}] Generation failed: {e}")
        jobs[job_id]["status"] = "failed"
        jobs[job_id]["error"] = str(e)


@app.get("/health")
async def health_check():
    """Health check endpoint."""
    return {
        "status": "healthy",
        "service": "audio",
        "timestamp": datetime.utcnow()
    }


@app.post("/generate/music", response_model=JobResponse, status_code=status.HTTP_202_ACCEPTED)
async def generate_music(
    request: MusicGenerationRequest,
    background_tasks: BackgroundTasks
):
    """Generate music from text prompt.
    
    Args:
        request: Generation request
        background_tasks: Background task manager
        
    Returns:
        Job ID for tracking
    """
    job_id = str(uuid.uuid4())
    
    # Create job entry
    jobs[job_id] = {
        "status": "pending",
        "progress": 0,
        "result": None,
        "error": None,
        "created_at": datetime.utcnow(),
        "completed_at": None
    }
    
    # Start background task
    background_tasks.add_task(generate_music_task, job_id, request)
    
    logger.info(f"Created music generation job: {job_id}")
    
    return JobResponse(
        job_id=job_id,
        status="pending",
        message="Music generation started"
    )


@app.get ("/jobs/{job_id}", response_model=JobStatusResponse)
async def get_job_status(job_id: str):
    """Get job status.
    
    Args:
        job_id: Job ID
        
    Returns:
        Job status
        
    Raises:
        HTTPException: If job not found
    """
    if job_id not in jobs:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Job not found"
        )
    
    job_data = jobs[job_id]
    
    return JobStatusResponse(
        job_id=job_id,
        status=job_data["status"],
        progress=job_data["progress"],
        result=job_data["result"],
        error=job_data["error"],
        created_at=job_data["created_at"],
        completed_at=job_data.get("completed_at")
    )


if __name__ == "__main__":
    import uvicorn
    
    uvicorn.run(
        "audio_api:app",
        host="0.0.0.0",
        port=8002,
        reload=True
    )
