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_arrival import arrival as crud_arrival
from app.schemas.arrival import Arrival, ArrivalCreate, ArrivalUpdate, ArrivalStatus, ArrivalStatusUpdate
from app.models.ppr import User
from app.core.utils import get_client_ip

router = APIRouter()


@router.get("/", response_model=List[Arrival])
async def get_arrivals(
    request: Request,
    skip: int = 0,
    limit: int = 100,
    status: Optional[ArrivalStatus] = 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 arrival records with optional filtering"""
    arrivals = crud_arrival.get_multi(
        db, skip=skip, limit=limit, status=status, 
        date_from=date_from, date_to=date_to
    )
    return arrivals


@router.post("/", response_model=Arrival)
async def create_arrival(
    request: Request,
    arrival_in: ArrivalCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_operator_user)
):
    """Create a new arrival record"""
    arrival = crud_arrival.create(db, obj_in=arrival_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": "arrival_booked_in",
            "data": {
                "id": arrival.id,
                "registration": arrival.registration,
                "in_from": arrival.in_from,
                "status": arrival.status.value
            }
        })
    
    return arrival


@router.get("/{arrival_id}", response_model=Arrival)
async def get_arrival(
    arrival_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_read_user)
):
    """Get a specific arrival record"""
    arrival = crud_arrival.get(db, arrival_id=arrival_id)
    if not arrival:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Arrival record not found"
        )
    return arrival


@router.put("/{arrival_id}", response_model=Arrival)
async def update_arrival(
    request: Request,
    arrival_id: int,
    arrival_in: ArrivalUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_operator_user)
):
    """Update an arrival record"""
    db_arrival = crud_arrival.get(db, arrival_id=arrival_id)
    if not db_arrival:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Arrival record not found"
        )
    
    # Get user IP from request
    user_ip = request.client.host if request.client else None
    
    arrival = crud_arrival.update(
        db, 
        db_obj=db_arrival, 
        obj_in=arrival_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": "arrival_updated",
            "data": {
                "id": arrival.id,
                "registration": arrival.registration,
                "status": arrival.status.value
            }
        })
    
    return arrival


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


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