from typing import List
from fastapi import APIRouter, Depends, HTTPException, status, Request
from sqlalchemy.orm import Session
from app.api.deps import get_db
from app.core.config import settings
from app.schemas.public_book import (
    PublicLocalFlightCreate,
    PublicCircuitCreate,
    PublicDepartureCreate,
    PublicArrivalCreate,
)
from app.schemas.local_flight import LocalFlight as LocalFlightSchema
from app.schemas.circuit import Circuit as CircuitSchema
from app.schemas.departure import Departure as DepartureSchema
from app.schemas.arrival import Arrival as ArrivalSchema
from app.crud.crud_local_flight import local_flight as crud_local_flight
from app.crud.crud_circuit import crud_circuit
from app.crud.crud_departure import departure as crud_departure
from app.crud.crud_arrival import arrival as crud_arrival
from app.models.local_flight import SubmissionSource
from app.models.departure import SubmissionSource as DepartureSubmissionSource
from app.models.arrival import SubmissionSource as ArrivalSubmissionSource

router = APIRouter()


def check_public_booking_enabled():
    """Check if public booking is enabled"""
    if not settings.allow_public_booking:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Public booking is currently disabled"
        )


@router.post("/local-flights", response_model=LocalFlightSchema)
async def public_book_local_flight(
    request: Request,
    flight_in: PublicLocalFlightCreate,
    db: Session = Depends(get_db),
):
    """Book a local flight via public portal"""
    check_public_booking_enabled()
    
    # Create the flight with public submission source
    from app.schemas.local_flight import LocalFlightCreate
    
    flight_create = LocalFlightCreate(
        registration=flight_in.registration,
        type=flight_in.type,
        callsign=flight_in.callsign,
        pob=flight_in.pob,
        flight_type=flight_in.flight_type,
        duration=flight_in.duration,
        etd=flight_in.etd,
        notes=flight_in.notes,
    )
    
    flight = crud_local_flight.create(db, obj_in=flight_create, created_by="PUBLIC_PILOT")
    
    # Update with submission source and pilot email
    db.query(type(flight)).filter(type(flight).id == flight.id).update({
        type(flight).submitted_via: SubmissionSource.PUBLIC,
        type(flight).pilot_email: flight_in.pilot_email,
    })
    db.commit()
    db.refresh(flight)
    
    # Send real-time update via WebSocket if available
    if hasattr(request.app.state, 'connection_manager'):
        await request.app.state.connection_manager.broadcast({
            "type": "local_flight_booked_out",
            "data": {
                "id": flight.id,
                "registration": flight.registration,
                "flight_type": flight.flight_type.value,
                "status": flight.status.value,
                "submitted_via": "PUBLIC"
            }
        })
    
    return flight


@router.post("/circuits", response_model=CircuitSchema)
async def public_record_circuit(
    request: Request,
    circuit_in: PublicCircuitCreate,
    db: Session = Depends(get_db),
):
    """Record a circuit (touch and go) via public portal"""
    check_public_booking_enabled()
    
    from app.schemas.circuit import CircuitCreate
    
    circuit_create = CircuitCreate(
        local_flight_id=circuit_in.local_flight_id,
        circuit_timestamp=circuit_in.circuit_timestamp,
    )
    
    circuit = crud_circuit.create(db, obj_in=circuit_create)
    
    # Send real-time update via WebSocket
    if hasattr(request.app.state, 'connection_manager'):
        await request.app.state.connection_manager.broadcast({
            "type": "circuit_recorded",
            "data": {
                "id": circuit.id,
                "local_flight_id": circuit.local_flight_id,
                "circuit_timestamp": circuit.circuit_timestamp.isoformat(),
                "submitted_via": "PUBLIC"
            }
        })
    
    return circuit


@router.post("/departures", response_model=DepartureSchema)
async def public_book_departure(
    request: Request,
    departure_in: PublicDepartureCreate,
    db: Session = Depends(get_db),
):
    """Book a departure via public portal"""
    check_public_booking_enabled()
    
    from app.schemas.departure import DepartureCreate
    
    departure_create = DepartureCreate(
        registration=departure_in.registration,
        type=departure_in.type,
        callsign=departure_in.callsign,
        pob=departure_in.pob,
        out_to=departure_in.out_to,
        etd=departure_in.etd,
        notes=departure_in.notes,
    )
    
    departure = crud_departure.create(db, obj_in=departure_create, created_by="PUBLIC_PILOT")
    
    # Update with submission source and pilot email
    db.query(type(departure)).filter(type(departure).id == departure.id).update({
        type(departure).submitted_via: DepartureSubmissionSource.PUBLIC,
        type(departure).pilot_email: departure_in.pilot_email,
    })
    db.commit()
    db.refresh(departure)
    
    # 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,
                "status": departure.status.value,
                "submitted_via": "PUBLIC"
            }
        })
    
    return departure


@router.post("/arrivals", response_model=ArrivalSchema)
async def public_book_arrival(
    request: Request,
    arrival_in: PublicArrivalCreate,
    db: Session = Depends(get_db),
):
    """Book an arrival via public portal"""
    check_public_booking_enabled()
    
    from app.schemas.arrival import ArrivalCreate
    
    arrival_create = ArrivalCreate(
        registration=arrival_in.registration,
        type=arrival_in.type,
        callsign=arrival_in.callsign,
        pob=arrival_in.pob,
        in_from=arrival_in.in_from,
        eta=arrival_in.eta,
        notes=arrival_in.notes,
    )
    
    arrival = crud_arrival.create(db, obj_in=arrival_create, created_by="PUBLIC_PILOT")
    
    # Update with submission source and pilot email
    db.query(type(arrival)).filter(type(arrival).id == arrival.id).update({
        type(arrival).submitted_via: ArrivalSubmissionSource.PUBLIC,
        type(arrival).pilot_email: arrival_in.pilot_email,
    })
    db.commit()
    db.refresh(arrival)
    
    # 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,
                "status": arrival.status.value,
                "submitted_via": "PUBLIC"
            }
        })
    
    return arrival
