from datetime import date

from fastapi import APIRouter, Depends, Query
from sqlalchemy.orm import Session

from app.api.deps import get_current_user
from app.core.exceptions import NotFoundError
from app.db.session import get_db
from app.models.policy_document import PolicyDocument
from app.schemas.common import PaginatedResponse
from app.schemas.policy import MarkRenewedRequest, PolicyCreate, PolicyResponse, PolicyUpdate
from app.schemas.user_context import CurrentUser
from app.services.policy_service import PolicyService
from app.utils.pdf_response import pdf_file_response

router = APIRouter()


@router.get("/body-types")
def list_body_types(current_user: CurrentUser = Depends(get_current_user)):
    from app.utils.body_types import BODY_TYPE_CHOICES

    return BODY_TYPE_CHOICES


@router.get("/vehicle-types")
def list_vehicle_types(current_user: CurrentUser = Depends(get_current_user)):
    from app.utils.vehicle_types import VEHICLE_TYPE_CHOICES

    return VEHICLE_TYPE_CHOICES


@router.get("", response_model=PaginatedResponse[PolicyResponse])
def list_policies(
    page: int = Query(1, ge=1),
    page_size: int = Query(20, ge=1, le=100),
    search: str | None = None,
    status: str | None = None,
    company_id: int | None = None,
    payment_status: str | None = None,
    expiry_preset: str | None = None,
    expiry_from: date | None = None,
    expiry_to: date | None = None,
    vehicle_type: str | None = None,
    sort_by: str = Query("expiry_date"),
    sort_order: str = Query("asc"),
    current_user: CurrentUser = Depends(get_current_user),
    db: Session = Depends(get_db),
):
    items, total = PolicyService(db).list_policies(
        current_user.agency_id,
        current_user=current_user,
        page=page,
        page_size=page_size,
        search=search,
        status=status,
        company_id=company_id,
        payment_status=payment_status,
        expiry_preset=expiry_preset,
        expiry_from=expiry_from,
        expiry_to=expiry_to,
        vehicle_type=vehicle_type,
        sort_by=sort_by,
        sort_order=sort_order,
    )
    return PaginatedResponse(total=total, page=page, page_size=page_size, items=items)


@router.post("", response_model=PolicyResponse)
def create_policy(
    payload: PolicyCreate,
    current_user: CurrentUser = Depends(get_current_user),
    db: Session = Depends(get_db),
):
    return PolicyService(db).create_policy(current_user.agency_id, payload, user_id=current_user.id, current_user=current_user)


@router.get("/{policy_id}", response_model=PolicyResponse)
def get_policy(
    policy_id: int,
    current_user: CurrentUser = Depends(get_current_user),
    db: Session = Depends(get_db),
):
    return PolicyService(db).get_policy(current_user.agency_id, policy_id, current_user=current_user)


@router.put("/{policy_id}", response_model=PolicyResponse)
def update_policy(
    policy_id: int,
    payload: PolicyUpdate,
    current_user: CurrentUser = Depends(get_current_user),
    db: Session = Depends(get_db),
):
    return PolicyService(db).update_policy(current_user.agency_id, policy_id, payload, user_id=current_user.id, current_user=current_user)


@router.delete("/{policy_id}")
def delete_policy(
    policy_id: int,
    current_user: CurrentUser = Depends(get_current_user),
    db: Session = Depends(get_db),
):
    PolicyService(db).delete_policy(current_user.agency_id, policy_id, current_user=current_user)
    return {"message": "Policy deleted"}


@router.post("/{policy_id}/mark-renewed", response_model=PolicyResponse)
def mark_renewed(
    policy_id: int,
    payload: MarkRenewedRequest,
    current_user: CurrentUser = Depends(get_current_user),
    db: Session = Depends(get_db),
):
    return PolicyService(db).mark_renewed(
        current_user.agency_id, policy_id, payload.new_policy_id, user_id=current_user.id, current_user=current_user
    )


@router.get("/{policy_id}/pdf")
def download_policy_pdf(
    policy_id: int,
    current_user: CurrentUser = Depends(get_current_user),
    db: Session = Depends(get_db),
):
    PolicyService(db).get_policy(current_user.agency_id, policy_id)
    document = (
        db.query(PolicyDocument)
        .filter(PolicyDocument.policy_id == policy_id)
        .order_by(PolicyDocument.version.desc())
        .first()
    )
    if not document:
        raise NotFoundError("No PDF document found for this policy")
    return pdf_file_response(document.storage_path, document.original_filename)
