"""Analysis job endpoints."""
from fastapi import APIRouter, Depends, HTTPException, BackgroundTasks
from sqlalchemy.orm import Session
from pydantic import BaseModel
from typing import Dict, Optional
from uuid import uuid4
import asyncio

from ...models.database import get_db
from ...models import crud
from ...core.analyzer import AudioAnalyzer
from ...utils.logging import get_logger
from ...utils.validators import validate_directory_path

router = APIRouter()
logger = get_logger(__name__)

# In-memory job storage (in production, use Redis)
jobs: Dict[str, dict] = {}


class AnalyzeFolderRequest(BaseModel):
    """Request to analyze a folder."""
    path: str
    recursive: bool = True


class JobStatus(BaseModel):
    """Analysis job status."""
    job_id: str
    status: str  # pending, running, completed, failed
    progress: int
    total: int
    current_file: Optional[str] = None
    errors: list = []


def analyze_folder_task(job_id: str, path: str, recursive: bool, db_url: str):
    """Background task to analyze folder.

    Args:
        job_id: Job UUID
        path: Directory path
        recursive: Scan recursively
        db_url: Database URL for new session
    """
    from ...models.database import SessionLocal

    try:
        logger.info(f"Starting analysis job {job_id} for {path}")

        # Update job status
        jobs[job_id]["status"] = "running"

        # Create analyzer
        analyzer = AudioAnalyzer()

        # Progress callback
        def progress_callback(current: int, total: int, filename: str):
            jobs[job_id]["progress"] = current
            jobs[job_id]["total"] = total
            jobs[job_id]["current_file"] = filename

        # Analyze folder
        results = analyzer.analyze_folder(
            path=path,
            recursive=recursive,
            progress_callback=progress_callback,
        )

        # Save to database
        db = SessionLocal()
        try:
            saved_count = 0
            for analysis in results:
                try:
                    crud.upsert_track(db, analysis)
                    saved_count += 1
                except Exception as e:
                    logger.error(f"Failed to save track {analysis.filename}: {e}")
                    jobs[job_id]["errors"].append({
                        "file": analysis.filename,
                        "error": str(e)
                    })

            logger.info(f"Job {job_id} completed: {saved_count}/{len(results)} tracks saved")

            # Update job status
            jobs[job_id]["status"] = "completed"
            jobs[job_id]["progress"] = len(results)
            jobs[job_id]["total"] = len(results)
            jobs[job_id]["current_file"] = None
            jobs[job_id]["saved_count"] = saved_count

        finally:
            db.close()

    except Exception as e:
        logger.error(f"Job {job_id} failed: {e}")
        jobs[job_id]["status"] = "failed"
        jobs[job_id]["errors"].append({
            "error": str(e)
        })


@router.post("/folder")
async def analyze_folder(
    request: AnalyzeFolderRequest,
    background_tasks: BackgroundTasks,
    db: Session = Depends(get_db),
):
    """Start folder analysis job.

    Args:
        request: Folder analysis request
        background_tasks: FastAPI background tasks
        db: Database session

    Returns:
        Job ID for status tracking

    Raises:
        HTTPException: 400 if path is invalid
    """
    # Validate path
    validated_path = validate_directory_path(request.path)

    if not validated_path:
        raise HTTPException(
            status_code=400,
            detail=f"Invalid or inaccessible directory: {request.path}"
        )

    # Create job
    job_id = str(uuid4())

    jobs[job_id] = {
        "job_id": job_id,
        "status": "pending",
        "progress": 0,
        "total": 0,
        "current_file": None,
        "errors": [],
        "path": validated_path,
        "recursive": request.recursive,
    }

    # Get database URL for background task
    from ...utils.config import settings

    # Start background task
    background_tasks.add_task(
        analyze_folder_task,
        job_id,
        validated_path,
        request.recursive,
        settings.DATABASE_URL,
    )

    logger.info(f"Created analysis job {job_id} for {validated_path}")

    return {
        "job_id": job_id,
        "message": "Analysis job started",
        "path": validated_path,
        "recursive": request.recursive,
    }


@router.get("/status/{job_id}")
async def get_job_status(job_id: str):
    """Get analysis job status.

    Args:
        job_id: Job UUID

    Returns:
        Job status

    Raises:
        HTTPException: 404 if job not found
    """
    if job_id not in jobs:
        raise HTTPException(status_code=404, detail="Job not found")

    job_data = jobs[job_id]

    return {
        "job_id": job_data["job_id"],
        "status": job_data["status"],
        "progress": job_data["progress"],
        "total": job_data["total"],
        "current_file": job_data.get("current_file"),
        "errors": job_data.get("errors", []),
        "saved_count": job_data.get("saved_count"),
    }


@router.delete("/job/{job_id}")
async def delete_job(job_id: str):
    """Delete job from memory.

    Args:
        job_id: Job UUID

    Returns:
        Success message

    Raises:
        HTTPException: 404 if job not found
    """
    if job_id not in jobs:
        raise HTTPException(status_code=404, detail="Job not found")

    del jobs[job_id]

    return {"message": "Job deleted", "job_id": job_id}
