from typing import Optional

from fastapi import APIRouter, Query, Request

from app.modules.fedex.backend.service import fedex_service
from app.modules.fedex.models.schemas import (
    FedExBookingCreate,
    FedExBookingListResponse,
    FedExBookingResponse,
    FedExBookingSubmitResponse,
    FedExCancelRequest,
    FedExCancelResponse,
    FedExTrackingResponse,
)

router = APIRouter()


def _user_id_from_request(request: Request) -> Optional[int]:
    raw_user_id = getattr(request.state, "user_id", None)
    if raw_user_id is None:
        return None
    try:
        return int(raw_user_id)
    except (TypeError, ValueError):
        return None


@router.get("/fedex/config")
async def fedex_config() -> dict:
    return {
        "enabled": fedex_service.enabled,
        "read_only": fedex_service.read_only,
        "dry_run": fedex_service.dry_run,
    }


@router.post("/fedex/bookings", response_model=FedExBookingResponse)
async def create_booking(payload: FedExBookingCreate, request: Request):
    booking = fedex_service.create_booking_draft(payload, _user_id_from_request(request))
    return booking


@router.get("/fedex/bookings", response_model=FedExBookingListResponse)
async def list_bookings(case_id: Optional[int] = Query(default=None, gt=0)):
    return {"items": fedex_service.list_bookings(case_id=case_id)}


@router.get("/fedex/bookings/{booking_ref}", response_model=FedExBookingResponse)
async def get_booking(booking_ref: str):
    return fedex_service.get_booking(booking_ref)


@router.post("/fedex/bookings/{booking_ref}/submit", response_model=FedExBookingSubmitResponse)
async def submit_booking(booking_ref: str, request: Request):
    return await fedex_service.submit_booking(booking_ref, _user_id_from_request(request))


@router.get("/fedex/bookings/{booking_ref}/tracking", response_model=FedExTrackingResponse)
async def get_tracking(booking_ref: str):
    return await fedex_service.get_tracking(booking_ref)


@router.post("/fedex/bookings/{booking_ref}/cancel", response_model=FedExCancelResponse)
async def cancel_booking(booking_ref: str, payload: FedExCancelRequest, request: Request):
    return await fedex_service.cancel_booking(booking_ref, payload.reason, _user_id_from_request(request))
