from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, status, Request
from sqlalchemy.orm import Session
from datetime import date
from app.api.deps import get_db, get_current_read_user, get_current_operator_user
from app.crud.crud_departure import departure as crud_departure
from app.schemas.departure import Departure, DepartureCreate, DepartureUpdate, DepartureStatus, DepartureStatusUpdate
from app.models.ppr import User
from app.core.utils import get_client_ip

router = APIRouter()


@router.get("/", response_model=List[Departure])
async def get_departures(
    request: Request,
    skip: int = 0,
    limit: int = 100,
    status: Optional[DepartureStatus] = None,
    date_from: Optional[date] = None,
    date_to: Optional[date] = None,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_read_user)
):
    """Get departure records with optional filtering"""
    departures = crud_departure.get_multi(
        db, skip=skip, limit=limit, status=status, 
        date_from=date_from, date_to=date_to
    )
    return departures


@router.post("/", response_model=Departure)
async def create_departure(
    request: Request,
    departure_in: DepartureCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_operator_user)
):
    """Create a new departure record"""
    departure = crud_departure.create(db, obj_in=departure_in, created_by=current_user.username)
    
    # Send real-time update via WebSocket
    if hasattr(request.app.state, 'connection_manager'):
        await request.app.state.connection_manager.broadcast({
            "type": "departure_booked_out",
            "data": {
                "id": departure.id,
                "registration": departure.registration,
                "out_to": departure.out_to,
                "status": departure.status.value
            }
        })
    
    return departure


@router.get("/{departure_id}", response_model=Departure)
async def get_departure(
    departure_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_read_user)
):
    """Get a specific departure record"""
    departure = crud_departure.get(db, departure_id=departure_id)
    if not departure:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Departure record not found"
        )
    return departure


@router.put("/{departure_id}", response_model=Departure)
async def update_departure(
    request: Request,
    departure_id: int,
    departure_in: DepartureUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_operator_user)
):
    """Update a departure record"""
    db_departure = crud_departure.get(db, departure_id=departure_id)
    if not db_departure:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Departure record not found"
        )
    
    # Get user IP from request
    user_ip = request.client.host if request.client else None
    
    departure = crud_departure.update(
        db, 
        db_obj=db_departure, 
        obj_in=departure_in,
        user=current_user.username,
        user_ip=user_ip
    )
    
    # Send real-time update
    if hasattr(request.app.state, 'connection_manager'):
        await request.app.state.connection_manager.broadcast({
            "type": "departure_updated",
            "data": {
                "id": departure.id,
                "registration": departure.registration,
                "status": departure.status.value
            }
        })
    
    return departure


@router.patch("/{departure_id}/status", response_model=Departure)
async def update_departure_status(
    request: Request,
    departure_id: int,
    status_update: DepartureStatusUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_operator_user)
):
    """Update departure status"""
    client_ip = get_client_ip(request)
    departure = crud_departure.update_status(
        db, 
        departure_id=departure_id, 
        status=status_update.status,
        timestamp=status_update.timestamp,
        user=current_user.username,
        user_ip=client_ip
    )
    if not departure:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Departure record not found"
        )
    
    # Send real-time update
    if hasattr(request.app.state, 'connection_manager'):
        await request.app.state.connection_manager.broadcast({
            "type": "departure_status_update",
            "data": {
                "id": departure.id,
                "registration": departure.registration,
                "status": departure.status.value,
                "departed_dt": departure.departed_dt.isoformat() if departure.departed_dt else None
            }
        })
    
    return departure


@router.delete("/{departure_id}", response_model=Departure)
async def cancel_departure(
    request: Request,
    departure_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_operator_user)
):
    """Cancel a departure record"""
    departure = crud_departure.cancel(db, departure_id=departure_id)
    if not departure:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Departure record not found"
        )
    
    # Send real-time update
    if hasattr(request.app.state, 'connection_manager'):
        await request.app.state.connection_manager.broadcast({
            "type": "departure_cancelled",
            "data": {
                "id": departure.id,
                "registration": departure.registration
            }
        })
    
    return departure
