"""
Queue management endpoints for processing AI feedback jobs.
"""

import asyncio
from typing import Any

from fastapi import APIRouter, HTTPException

from app.core.logging import get_logger
from app.repositories.queue_repository import QueueRepository
from app.schemas.queue import QueueStatus
from app.services.progress_tracker import ProgressTracker

logger = get_logger("queue_endpoints")

router = APIRouter()

_PROCESS_TASK: asyncio.Task | None = None


@router.get("/status", response_model=QueueStatus)
async def get_queue_status() -> QueueStatus:
    """Get queue status and statistics."""
    try:
        logger.info("Queue status requested")
        queue_repo = QueueRepository()
        stats = await queue_repo.get_queue_stats()
        average_processing_time = await queue_repo.get_average_processing_time()
        # Get actual pending jobs (status="0" AND data_process="1")
        actual_pending = await queue_repo.get_pending_jobs(limit=1000)
        actual_pending_count = len(actual_pending)

        return QueueStatus(
            total_jobs=sum(stats.values()),
            pending_jobs=actual_pending_count,  # Only jobs ready for processing
            processing_jobs=stats.get("1", 0),
            failed_jobs=stats.get("2", 0),
            completed_jobs=stats.get("3", 0),
            average_processing_time=average_processing_time,
        )
    except Exception as e:
        logger.error(f"Failed to get queue status: {e}")
        raise HTTPException(
            status_code=500, detail=f"Failed to get queue status: {e!s}"
        ) from e


@router.post("/timeout-check")
async def check_timeout_jobs(
    timeout_hours: int = 5, step_timeout_minutes: int = 30
) -> dict[str, Any]:
    """Check for jobs that have been processing for too long and handle them."""
    try:
        logger.info(
            f"Timeout check requested (timeout: {timeout_hours}h, step timeout: {step_timeout_minutes}m)"
        )
        from app.services.queue_processor import QueueProcessor

        processor = QueueProcessor()

        # Check for traditional timeout jobs (overall processing time)
        timeout_result = await processor.check_timeout_jobs(timeout_hours)

        # Also check for stuck jobs (step-level timeout)
        stuck_jobs = await ProgressTracker.get_stuck_jobs(step_timeout_minutes)

        # Auto-reset stuck jobs if they're really stuck
        auto_reset_count = 0
        for stuck_job in stuck_jobs:
            job_id = stuck_job["job_id"]
            time_since_step = stuck_job.get("time_since_step_minutes", 0)

            # Auto-reset if stuck for more than double the timeout
            if time_since_step and time_since_step > (step_timeout_minutes * 2):
                success = await ProgressTracker.reset_stuck_job(
                    job_id,
                    f"Auto-reset: stuck in step for {time_since_step:.1f} minutes",
                )
                if success:
                    auto_reset_count += 1
                    logger.info(
                        f"Auto-reset stuck job {job_id} after {time_since_step:.1f} minutes"
                    )

        combined_result = {
            **timeout_result,
            "stuck_jobs_found": len(stuck_jobs),
            "stuck_jobs_auto_reset": auto_reset_count,
            "stuck_jobs": stuck_jobs,
            "step_timeout_minutes": step_timeout_minutes,
        }

        logger.info("Timeout check completed")
        return {"message": "Timeout check completed", "result": combined_result}
    except Exception as e:
        logger.error(f"Failed to check timeout jobs: {e}")
        raise HTTPException(
            status_code=500, detail=f"Failed to check timeout jobs: {e!s}"
        ) from e


@router.post("/process")
async def process_queue() -> dict[str, Any]:
    """Start queue processing in the background and return immediately."""
    global _PROCESS_TASK
    try:
        logger.info("Queue processing requested")
        # If a processing task is already running, don't start another
        if _PROCESS_TASK is not None and not _PROCESS_TASK.done():
            logger.info("Queue processing already running; request ignored")
            return {"message": "Queue processing already running"}

        from app.services.queue_processor import QueueProcessor

        processor = QueueProcessor()
        _PROCESS_TASK = asyncio.create_task(processor.process_queue())

        logger.info("Queue processing task started")
        return {"message": "Queue processing started"}
    except Exception as e:
        logger.error(f"Failed to process queue: {e}")
        raise HTTPException(
            status_code=500, detail=f"Failed to process queue: {e!s}"
        ) from e


@router.post("/test-analysis")
async def test_video_analysis(video_path: str) -> dict[str, Any]:
    """Test the comprehensive video analysis pipeline."""
    try:
        logger.info(f"Test video analysis requested for path: {video_path}")
        from app.services.video_analysis import (
            VideoAnalysisService,
        )

        analyzer = VideoAnalysisService()
        result = await analyzer.analyze_video(
            video_path=video_path,
            user_id=1,
            interview_id=1,
            question_id=1,
            interview_type="1",
        )

        logger.info("Test video analysis completed")
        return {"message": "Video analysis test completed", "result": result}
    except Exception as e:
        logger.error(f"Failed to test video analysis: {e}")
        raise HTTPException(
            status_code=500, detail=f"Failed to test video analysis: {e!s}"
        ) from e


@router.post("/cleanup")
async def cleanup_database() -> dict[str, Any]:
    """Clean up invalid data in the database."""
    try:
        logger.info("Database cleanup requested")
        from app.repositories.queue_repository import QueueRepository

        repo = QueueRepository()
        result = await repo.cleanup_invalid_data()

        logger.info("Database cleanup completed")
        return result
    except Exception as e:
        logger.error(f"Failed to cleanup database: {e}")
        raise HTTPException(
            status_code=500, detail=f"Failed to cleanup database: {e!s}"
        ) from e


@router.get("/schema")
async def get_database_schema() -> dict[str, Any]:
    """Get database schema information for debugging."""
    try:
        logger.info("Database schema info requested")
        from app.repositories.queue_repository import QueueRepository

        repo = QueueRepository()
        result = await repo.get_database_schema_info()

        logger.info("Database schema info retrieved")
        return result
    except Exception as e:
        logger.error(f"Failed to get database schema: {e}")
        raise HTTPException(
            status_code=500, detail=f"Failed to get database schema: {e!s}"
        ) from e


@router.get("/progress/{job_id}")
async def get_job_progress(job_id: int) -> dict[str, Any]:
    """Get progress information for a specific job."""
    try:
        logger.info(f"Job progress requested for job {job_id}")
        progress = await ProgressTracker.get_job_progress(job_id)

        if not progress:
            raise HTTPException(status_code=404, detail=f"Job {job_id} not found")

        return progress
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to get job progress for {job_id}: {e}")
        raise HTTPException(
            status_code=500, detail=f"Failed to get job progress: {e!s}"
        ) from e


@router.get("/stuck-jobs")
async def get_stuck_jobs(timeout_minutes: int = 30) -> dict[str, Any]:
    """Get list of jobs that appear to be stuck."""
    try:
        logger.info(f"Stuck jobs check requested (timeout: {timeout_minutes} minutes)")
        stuck_jobs = await ProgressTracker.get_stuck_jobs(timeout_minutes)

        return {
            "stuck_jobs": stuck_jobs,
            "count": len(stuck_jobs),
            "timeout_minutes": timeout_minutes,
        }
    except Exception as e:
        logger.error(f"Failed to get stuck jobs: {e}")
        raise HTTPException(
            status_code=500, detail=f"Failed to get stuck jobs: {e!s}"
        ) from e


@router.post("/reset-stuck-job/{job_id}")
async def reset_stuck_job(job_id: int, reason: str = "Manual reset") -> dict[str, Any]:
    """Reset a stuck job back to pending status."""
    try:
        logger.info(f"Resetting stuck job {job_id}: {reason}")
        success = await ProgressTracker.reset_stuck_job(job_id, reason)

        if not success:
            raise HTTPException(
                status_code=404, detail=f"Job {job_id} not found or could not be reset"
            )

        return {
            "status": "success",
            "job_id": job_id,
            "message": f"Job {job_id} has been reset to pending status",
            "reason": reason,
        }
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to reset stuck job {job_id}: {e}")
        raise HTTPException(
            status_code=500, detail=f"Failed to reset stuck job: {e!s}"
        ) from e


@router.get("/processing-jobs")
async def get_processing_jobs() -> dict[str, Any]:
    """Get all currently processing jobs with their progress."""
    try:
        logger.info("Processing jobs list requested")
        from app.models.queue import AIFeedbackQueue

        # Get all processing jobs
        processing_jobs = await AIFeedbackQueue.filter(status="1").all()

        jobs_info = []
        for job in processing_jobs:
            job_info = {
                "job_id": job.id,
                "video_name": job.video_name,
                "user_id": job.user_id,
                "interview_id": job.interview_id,
                "question_id": job.question_id,
                "current_step": job.current_step,
                "progress_percentage": job.progress_percentage,
                "process_start_time": job.process_start_time.isoformat()
                if job.process_start_time
                else None,
                "step_start_time": job.step_start_time.isoformat()
                if job.step_start_time
                else None,
                "last_heartbeat": job.last_heartbeat.isoformat()
                if job.last_heartbeat
                else None,
            }
            jobs_info.append(job_info)

        return {
            "processing_jobs": jobs_info,
            "count": len(jobs_info),
        }
    except Exception as e:
        logger.error(f"Failed to get processing jobs: {e}")
        raise HTTPException(
            status_code=500, detail=f"Failed to get processing jobs: {e!s}"
        ) from e
