from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.orm import Session
from typing import Optional, List
from utils.utils import get_db
from . import handler
from .schema import PaymentCreate, PaymentUpdate, PaymentResponse, PaymentInitiateRequest, PaymentInitiateResponse, PaymentWebhookRequest, PaymentWebhookResponse, PaymentStatus, PaymentMethod

router = APIRouter(prefix="/payments", tags=["Payments"])

@router.post(
    "/initiate",
    response_model=PaymentInitiateResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Initiate Payment for Reservation",
    description="Initiates payment processing for an active reservation. Creates a booking record and payment record with pending status. Returns payment gateway reference for external payment processing. Validates that reservation is active and not expired. Returns 404 if reservation not found, 400 if reservation expired or not active, 409 if booking already exists for reservation.",
)
def initiate_payment_route(data: PaymentInitiateRequest, db: Session = Depends(get_db)):
    return handler.initiate_payment(db, data)

@router.post(
    "/webhook",
    response_model=PaymentWebhookResponse,
    summary="Process Payment Gateway Webhook",
    description="Processes payment gateway webhook callback to update payment status. On success, confirms booking, updates seat statuses to booked, generates ticket with QR code, and updates reservation status to confirmed. On failure, marks payment and booking as failed. Returns success status and relevant IDs.",
)
def payment_webhook_route(data: PaymentWebhookRequest, db: Session = Depends(get_db)):
    return handler.process_payment_webhook(db, data)

@router.get(
    "/{id}",
    response_model=PaymentResponse,
    summary="Get Payment by ID",
    description="Retrieves a single payment record by its unique identifier. Returns 404 if payment not found.",
)
def get_payment_route(id: str, db: Session = Depends(get_db)):
    return handler.get_payment(db, id)

@router.get(
    "/",
    response_model=List[PaymentResponse],
    summary="List Payments",
    description="Returns a paginated list of payment records. Supports optional filtering by user ID, booking ID, payment status, and payment method. Results are ordered by creation date descending.",
)
def list_payments_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    user_id: Optional[str] = Query(None),
    booking_id: Optional[str] = Query(None),
    payment_status: Optional[PaymentStatus] = Query(None),
    payment_method: Optional[PaymentMethod] = Query(None),
    db: Session = Depends(get_db),
):
    return handler.list_payments(db, limit, offset, user_id, booking_id, payment_status.value if payment_status else None, payment_method.value if payment_method else None)

@router.post(
    "/",
    response_model=PaymentResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Payment Record",
    description="Creates a new payment record manually. Validates that booking and user exist. Returns 404 if booking or user not found, 400 if amount is not positive.",
)
def create_payment_route(data: PaymentCreate, db: Session = Depends(get_db)):
    return handler.create_payment(db, data)

@router.put(
    "/{id}",
    response_model=PaymentResponse,
    summary="Update Payment Record",
    description="Updates an existing payment record. Validates that referenced booking and user exist if those fields are updated. Returns 404 if payment, booking, or user not found, 400 if amount is not positive.",
)
def update_payment_route(id: str, data: PaymentUpdate, db: Session = Depends(get_db)):
    return handler.update_payment(db, id, data)

@router.delete(
    "/{id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Payment Record",
    description="Deletes a payment record by ID. Returns 404 if payment not found, 500 if deletion fails.",
)
def delete_payment_route(id: str, db: Session = Depends(get_db)):
    return handler.delete_payment(db, id)