"""
Process control API endpoints.
"""

import logging
from typing import Optional, Dict, Any

from fastapi import APIRouter, HTTPException, Query
from pydantic import BaseModel

from ...recipe.recipe_controller import recipe_controller
from ....shared.models.recipe import RecipePhase


logger = logging.getLogger(__name__)

router = APIRouter()


class ProcessStartRequest(BaseModel):
    """Request model for starting a process."""
    recipe_id: int
    user_id: Optional[str] = None


class ProcessStatusResponse(BaseModel):
    """Response model for process status."""
    session_id: Optional[str]
    recipe_id: Optional[int]
    recipe_name: Optional[str]
    status: Optional[str]
    current_phase: Optional[str]
    started_at: Optional[str]
    duration_seconds: Optional[int]
    started_by: Optional[str]
    current_temperature: Optional[float]
    target_temperature: Optional[float]
    temperature_error: Optional[float]
    error_count: int = 0
    warning_count: int = 0
    is_running: bool = False


class ProcessActionResponse(BaseModel):
    """Response model for process actions."""
    success: bool
    message: str
    session_id: Optional[str] = None


@router.post("/start", response_model=ProcessActionResponse)
async def start_process(request: ProcessStartRequest):
    """Start a new tempering process."""
    try:
        logger.info(f"Starting process for recipe {request.recipe_id} by user {request.user_id}")
        
        session_id = await recipe_controller.start_recipe(
            recipe_id=request.recipe_id,
            user_id=request.user_id
        )
        
        return ProcessActionResponse(
            success=True,
            message="Process started successfully",
            session_id=session_id
        )
        
    except Exception as e:
        logger.error(f"Failed to start process: {e}")
        raise HTTPException(
            status_code=400,
            detail=f"Failed to start process: {str(e)}"
        )


@router.post("/stop", response_model=ProcessActionResponse)
async def stop_process(
    user_id: Optional[str] = None,
    reason: str = "Manual stop"
):
    """Stop the currently running process."""
    try:
        logger.info(f"Stopping process by user {user_id}, reason: {reason}")
        
        success = await recipe_controller.stop_recipe(
            user_id=user_id,
            reason=reason
        )
        
        return ProcessActionResponse(
            success=success,
            message="Process stopped successfully" if success else "No process was running"
        )
        
    except Exception as e:
        logger.error(f"Failed to stop process: {e}")
        raise HTTPException(
            status_code=500,
            detail=f"Failed to stop process: {str(e)}"
        )


@router.post("/pause", response_model=ProcessActionResponse)
async def pause_process(user_id: Optional[str] = None):
    """Pause the currently running process."""
    try:
        logger.info(f"Pausing process by user {user_id}")
        
        success = await recipe_controller.pause_recipe(user_id=user_id)
        
        return ProcessActionResponse(
            success=success,
            message="Process paused successfully" if success else "No process is running to pause"
        )
        
    except Exception as e:
        logger.error(f"Failed to pause process: {e}")
        raise HTTPException(
            status_code=500,
            detail=f"Failed to pause process: {str(e)}"
        )


@router.post("/resume", response_model=ProcessActionResponse)
async def resume_process(user_id: Optional[str] = None):
    """Resume a paused process."""
    try:
        logger.info(f"Resuming process by user {user_id}")
        
        success = await recipe_controller.resume_recipe(user_id=user_id)
        
        return ProcessActionResponse(
            success=success,
            message="Process resumed successfully" if success else "No paused process to resume"
        )
        
    except Exception as e:
        logger.error(f"Failed to resume process: {e}")
        raise HTTPException(
            status_code=500,
            detail=f"Failed to resume process: {str(e)}"
        )


@router.post("/emergency-stop", response_model=ProcessActionResponse)
async def emergency_stop(user_id: Optional[str] = None):
    """Execute emergency stop of the current process."""
    try:
        logger.critical(f"Emergency stop initiated by user {user_id}")
        
        success = await recipe_controller.emergency_stop(user_id=user_id)
        
        return ProcessActionResponse(
            success=success,
            message="Emergency stop executed" if success else "Emergency stop failed"
        )
        
    except Exception as e:
        logger.critical(f"Emergency stop failed: {e}")
        raise HTTPException(
            status_code=500,
            detail=f"Emergency stop failed: {str(e)}"
        )


@router.get("/status", response_model=Optional[ProcessStatusResponse])
async def get_process_status():
    """Get current process status."""
    try:
        status = await recipe_controller.get_process_status()
        
        if not status:
            return None
        
        session_info = status.get("session", {})
        state_machine_info = status.get("state_machine", {})
        
        return ProcessStatusResponse(
            session_id=session_info.get("session_id"),
            recipe_id=state_machine_info.get("recipe_id"),
            recipe_name=session_info.get("recipe_name"),
            status=session_info.get("status"),
            current_phase=state_machine_info.get("current_phase"),
            started_at=session_info.get("started_at"),
            duration_seconds=session_info.get("duration_seconds"),
            started_by=session_info.get("started_by"),
            current_temperature=state_machine_info.get("current_temperature"),
            target_temperature=state_machine_info.get("target_temperature"),
            temperature_error=state_machine_info.get("temperature_error"),
            error_count=state_machine_info.get("error_count", 0),
            warning_count=state_machine_info.get("warning_count", 0),
            is_running=state_machine_info.get("is_running", False)
        )
        
    except Exception as e:
        logger.error(f"Failed to get process status: {e}")
        raise HTTPException(
            status_code=500,
            detail="Failed to retrieve process status"
        )


@router.get("/phases", response_model=Dict[str, str])
async def get_process_phases():
    """Get available process phases."""
    return {phase.value: phase.name for phase in RecipePhase}


@router.get("/active-sessions")
async def get_active_sessions():
    """Get list of active process sessions."""
    try:
        sessions = await recipe_controller.get_active_sessions()
        return {"active_sessions": sessions}
        
    except Exception as e:
        logger.error(f"Failed to get active sessions: {e}")
        raise HTTPException(
            status_code=500,
            detail="Failed to retrieve active sessions"
        )


@router.get("/history")
async def get_process_history(
    limit: int = Query(50, ge=1, le=100, description="Maximum number of sessions to return"),
    skip: int = Query(0, ge=0, description="Number of sessions to skip")
):
    """Get process execution history."""
    try:
        # This would query the database for process session history
        # For now, return empty list as placeholder
        return {
            "sessions": [],
            "total": 0,
            "page": (skip // limit) + 1,
            "per_page": limit
        }
        
    except Exception as e:
        logger.error(f"Failed to get process history: {e}")
        raise HTTPException(
            status_code=500,
            detail="Failed to retrieve process history"
        )