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 OfferCreate, OfferUpdate, OfferResponse

router = APIRouter(prefix="/offers", tags=["Offers"])

@router.post(
    "/",
    response_model=OfferResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Offer",
    description="Creates a new offer for a listing. Validates that the offer amount is at least 50% of asking price and does not exceed the listing price. Returns 400 if listing does not accept offers or is not active. Returns 404 if buyer or listing not found."
)
def create_offer_route(data: OfferCreate, db: Session = Depends(get_db)):
    return handler.create_offer(db, data)

@router.get(
    "/{offer_id}",
    response_model=OfferResponse,
    summary="Get Offer",
    description="Returns a single offer by ID. Returns 404 if offer not found."
)
def get_offer_route(offer_id: str, db: Session = Depends(get_db)):
    return handler.get_offer(db, offer_id)

@router.get(
    "/",
    response_model=List[OfferResponse],
    summary="List Offers",
    description="Returns a paginated list of offers. Supports optional filters for listing_id, buyer_id, and status."
)
def list_offers_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    listing_id: Optional[str] = None,
    buyer_id: Optional[str] = None,
    status: Optional[str] = None,
    db: Session = Depends(get_db)
):
    return handler.list_offers(db, limit, offset, listing_id, buyer_id, status)

@router.put(
    "/{offer_id}",
    response_model=OfferResponse,
    summary="Update Offer",
    description="Updates an existing offer. Returns 404 if offer, buyer, or listing not found."
)
def update_offer_route(offer_id: str, data: OfferUpdate, db: Session = Depends(get_db)):
    return handler.update_offer(db, offer_id, data)

@router.delete(
    "/{offer_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Offer",
    description="Deletes an offer by ID. Returns 404 if offer not found."
)
def delete_offer_route(offer_id: str, db: Session = Depends(get_db)):
    return handler.delete_offer(db, offer_id)

@router.post(
    "/{offer_id}/accept",
    response_model=OfferResponse,
    summary="Accept Offer",
    description="Accepts a pending offer and reserves the listing. Returns 400 if offer is not pending, has expired, or listing is not active. Returns 404 if offer or listing not found."
)
def accept_offer_route(offer_id: str, db: Session = Depends(get_db)):
    return handler.accept_offer(db, offer_id)

@router.post(
    "/{offer_id}/reject",
    response_model=OfferResponse,
    summary="Reject Offer",
    description="Rejects a pending offer with optional response message. Returns 400 if offer is not pending. Returns 404 if offer not found."
)
def reject_offer_route(
    offer_id: str,
    response_message: Optional[str] = None,
    db: Session = Depends(get_db)
):
    return handler.reject_offer(db, offer_id, response_message)

@router.post(
    "/{offer_id}/counter",
    response_model=OfferResponse,
    summary="Counter Offer",
    description="Rejects the current offer and creates a new counter offer with a different amount. Returns 400 if offer is not pending, counter amount is invalid, or exceeds asking price. Returns 404 if offer or listing not found."
)
def counter_offer_route(
    offer_id: str,
    counter_amount: float = Query(..., gt=0),
    response_message: Optional[str] = None,
    db: Session = Depends(get_db)
):
    return handler.counter_offer(db, offer_id, counter_amount, response_message)

@router.post(
    "/{offer_id}/cancel",
    response_model=OfferResponse,
    summary="Cancel Offer",
    description="Cancels a pending offer. Returns 400 if offer is not pending. Returns 404 if offer not found."
)
def cancel_offer_route(offer_id: str, db: Session = Depends(get_db)):
    return handler.cancel_offer(db, offer_id)