from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.orm import Session
from utils.utils import get_db
from . import handler
from .schema import (
    LoancalculationCreate,
    LoancalculationUpdate,
    LoancalculationResponse,
    LoancalculationWithScheduleResponse,
    PaginatedLoancalculationResponse,
)

router = APIRouter(prefix="/loan-calculations", tags=["Loan Calculations"])


@router.post(
    "/",
    response_model=LoancalculationResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Loan Calculation With Schedule",
    description="Creates a new loan calculation and generates the complete amortization schedule. Validates input parameters, calculates monthly payment using standard amortization formula, computes total amount paid and total interest paid, and generates all schedule entries showing payment breakdown for each period. Returns the created loan calculation with computed results.",
)
def create_loan_calculation_route(
    data: LoancalculationCreate,
    db: Session = Depends(get_db),
):
    return handler.create_loan_calculation_with_schedule(db, data)


@router.get(
    "/{calculation_id}",
    response_model=LoancalculationResponse,
    summary="Get Loan Calculation Summary",
    description="Retrieves a loan calculation summary by ID. Returns the calculation input parameters and computed results including monthly payment, total amount paid, and total interest paid. Returns 404 if the calculation ID does not exist.",
)
def get_loan_calculation_route(
    calculation_id: str,
    db: Session = Depends(get_db),
):
    return handler.get_loan_calculation(db, calculation_id)


@router.get(
    "/{calculation_id}/details",
    response_model=LoancalculationWithScheduleResponse,
    summary="Get Loan Calculation With Schedule",
    description="Retrieves a loan calculation with the complete amortization schedule. Returns the calculation summary plus all schedule entries showing payment number, payment date (if set), payment amount, principal portion, interest portion, remaining balance, and cumulative totals for each payment period over the loan lifetime. Returns 404 if the calculation ID does not exist.",
)
def get_loan_calculation_with_schedule_route(
    calculation_id: str,
    db: Session = Depends(get_db),
):
    return handler.get_loan_calculation_with_schedule(db, calculation_id)


@router.get(
    "/",
    response_model=PaginatedLoancalculationResponse,
    summary="List Loan Calculations",
    description="Returns a paginated list of all loan calculations ordered by creation date descending. Supports pagination via limit and offset query parameters.",
)
def list_loan_calculations_route(
    limit: int = Query(20, ge=1),
    offset: int = Query(0, ge=0),
    db: Session = Depends(get_db),
):
    return handler.list_loan_calculations(db, limit, offset)


@router.patch(
    "/{calculation_id}",
    response_model=LoancalculationResponse,
    summary="Update Loan Calculation",
    description="Updates one or more fields of an existing loan calculation. Only provided fields are updated; unset fields remain unchanged. Returns 404 if the calculation ID does not exist, 400 if no fields are provided.",
)
def update_loan_calculation_route(
    calculation_id: str,
    data: LoancalculationUpdate,
    db: Session = Depends(get_db),
):
    return handler.update_loan_calculation(db, calculation_id, data)


@router.delete(
    "/{calculation_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Loan Calculation",
    description="Deletes a loan calculation and cascade deletes all associated amortization schedule entries. Returns 404 if the calculation ID does not exist.",
)
def delete_loan_calculation_route(
    calculation_id: str,
    db: Session = Depends(get_db),
):
    return handler.delete_loan_calculation(db, calculation_id)