from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.orm import Session

from core.database import get_core_db
from core.security import get_current_user

from . import service
from .dto import (
    ShipmentCloseInput,
    ShipmentCreate,
    ShipmentDocumentCreate,
    ShipmentDocumentResponse,
    ShipmentDocumentUpdate,
    ShipmentEventCreate,
    ShipmentEventDecisionInput,
    ShipmentEventResponse,
    ShipmentEventUpdate,
    ShipmentRescheduleInput,
    ShipmentResponse,
    ShipmentUpdate,
)

router = APIRouter()


def _user_id(current_user: dict) -> str | None:
    return current_user.get("sub") or current_user.get("id")


@router.get("/shipments", response_model=list[ShipmentResponse])
def list_shipments(
    company_id: int = Query(..., description="Company ID"),
    search: str | None = Query(None),
    shipment_status: str | None = Query(None, alias="status"),
    account_id: int | None = Query(None),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    tenant_id = current_user["tenant_id"]
    return service.get_shipments(db, tenant_id, company_id, search, shipment_status, account_id)


@router.get("/shipments/{shipment_id}", response_model=ShipmentResponse)
def get_shipment(
    shipment_id: int,
    company_id: int = Query(..., description="Company ID"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    return service.get_shipment(db, shipment_id, current_user["tenant_id"], company_id)


@router.post("/shipments", response_model=ShipmentResponse, status_code=status.HTTP_201_CREATED)
def create_shipment(
    payload: ShipmentCreate,
    company_id: int = Query(..., description="Company ID"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    tenant_id = current_user["tenant_id"]
    return service.create_shipment(db, payload, tenant_id, company_id, _user_id(current_user))


@router.post("/shipments/from-quote", response_model=ShipmentResponse, status_code=status.HTTP_201_CREATED)
def create_shipment_from_quote(
    quote_id: int = Query(..., description="Cotización aceptada a liberar"),
    company_id: int = Query(..., description="Company ID"),
    operation_type: str | None = Query(None, description="Confirma la dirección: importacion | exportacion"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    tenant_id = current_user["tenant_id"]
    return service.create_shipment_from_quote(
        db, quote_id, tenant_id, company_id, _user_id(current_user), operation_type=operation_type
    )


@router.post("/shipments/{shipment_id}/reschedule", response_model=ShipmentResponse)
def reschedule_shipment(
    shipment_id: int,
    payload: ShipmentRescheduleInput,
    company_id: int = Query(..., description="Company ID"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    """Reprograma la salida cuando no se alcanza el Cut Off (R-E-06)."""
    tenant_id = current_user["tenant_id"]
    return service.reschedule_departure(db, shipment_id, payload, tenant_id, company_id, _user_id(current_user))


@router.post("/shipments/{shipment_id}/close", response_model=ShipmentResponse)
def close_shipment(
    shipment_id: int,
    payload: ShipmentCloseInput,
    company_id: int = Query(..., description="Company ID"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    """Cierre operativo del embarque con costos finales (R-E-22, dispara facturación R-F-01)."""
    tenant_id = current_user["tenant_id"]
    return service.close_shipment(db, shipment_id, payload, tenant_id, company_id, _user_id(current_user))


@router.patch("/shipments/{shipment_id}", response_model=ShipmentResponse)
def update_shipment(
    shipment_id: int,
    payload: ShipmentUpdate,
    company_id: int = Query(..., description="Company ID"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    tenant_id = current_user["tenant_id"]
    return service.update_shipment(db, shipment_id, payload, tenant_id, company_id, _user_id(current_user))


@router.delete("/shipments/{shipment_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_shipment(
    shipment_id: int,
    company_id: int = Query(..., description="Company ID"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    service.delete_shipment(db, shipment_id, current_user["tenant_id"], company_id)


# ----- Documentos del embarque -----

@router.get("/shipments/{shipment_id}/documents", response_model=list[ShipmentDocumentResponse])
def list_shipment_documents(
    shipment_id: int,
    company_id: int = Query(..., description="Company ID"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    service.get_shipment(db, shipment_id, current_user["tenant_id"], company_id)
    return service.get_shipment_documents(db, current_user["tenant_id"], company_id, shipment_id)


@router.post("/shipment-documents", response_model=ShipmentDocumentResponse, status_code=status.HTTP_201_CREATED)
def create_shipment_document(
    payload: ShipmentDocumentCreate,
    company_id: int = Query(..., description="Company ID"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    return service.create_shipment_document(db, payload, current_user["tenant_id"], company_id)


@router.patch("/shipment-documents/{doc_id}", response_model=ShipmentDocumentResponse)
def update_shipment_document(
    doc_id: int,
    payload: ShipmentDocumentUpdate,
    company_id: int = Query(..., description="Company ID"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    return service.update_shipment_document(db, doc_id, payload, current_user["tenant_id"], company_id)


@router.delete("/shipment-documents/{doc_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_shipment_document(
    doc_id: int,
    company_id: int = Query(..., description="Company ID"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    service.delete_shipment_document(db, doc_id, current_user["tenant_id"], company_id)


# ----- Bitácora / hitos -----

@router.get("/shipments/{shipment_id}/events", response_model=list[ShipmentEventResponse])
def list_shipment_events(
    shipment_id: int,
    company_id: int = Query(..., description="Company ID"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    service.get_shipment(db, shipment_id, current_user["tenant_id"], company_id)
    return service.get_shipment_events(db, current_user["tenant_id"], company_id, shipment_id)


@router.post("/shipments/{shipment_id}/events/seed", response_model=list[ShipmentEventResponse])
def seed_shipment_events(
    shipment_id: int,
    company_id: int = Query(..., description="Company ID"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    return service.seed_default_milestones(db, shipment_id, current_user["tenant_id"], company_id)


@router.post("/shipment-events", response_model=ShipmentEventResponse, status_code=status.HTTP_201_CREATED)
def create_shipment_event(
    payload: ShipmentEventCreate,
    company_id: int = Query(..., description="Company ID"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    return service.create_shipment_event(db, payload, current_user["tenant_id"], company_id)


@router.patch("/shipment-events/{event_id}", response_model=ShipmentEventResponse)
def update_shipment_event(
    event_id: int,
    payload: ShipmentEventUpdate,
    company_id: int = Query(..., description="Company ID"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    return service.update_shipment_event(db, event_id, payload, current_user["tenant_id"], company_id)


@router.patch("/shipment-events/{event_id}/complete", response_model=ShipmentEventResponse)
def complete_shipment_event(
    event_id: int,
    company_id: int = Query(..., description="Company ID"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    return service.complete_shipment_event(db, event_id, current_user["tenant_id"], company_id)


@router.patch("/shipment-events/{event_id}/decision", response_model=ShipmentEventResponse)
def decide_shipment_event(
    event_id: int,
    payload: ShipmentEventDecisionInput,
    company_id: int = Query(..., description="Company ID"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    """Resuelve un punto de decisión: autorizado o rechazado (abre corrección). R-E-13/R-I-06."""
    return service.decide_shipment_event(db, event_id, payload, current_user["tenant_id"], company_id)


@router.delete("/shipment-events/{event_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_shipment_event(
    event_id: int,
    company_id: int = Query(..., description="Company ID"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    service.delete_shipment_event(db, event_id, current_user["tenant_id"], company_id)
