from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from typing import List
from datetime import datetime, timezone

from ..database import get_db, SelectionOffer as SelectionOfferModel
from ..models.selection_offer import (
    SelectionOffer,
    SelectionOfferCreate,
    SelectionOfferUpdate,
)

router = APIRouter(
    prefix="/selection-offers",
    tags=["selection-offers"],
    responses={404: {"description": "Not found"}},
)


# Get all selection offers
@router.get("/", response_model=List[SelectionOffer])
def get_all_selection_offers(db: Session = Depends(get_db)):
    return db.query(SelectionOfferModel).order_by(SelectionOfferModel.min_amount).all()


# Get active selection offers
@router.get("/active", response_model=List[SelectionOffer])
def get_active_selection_offers(db: Session = Depends(get_db)):
    return (
        db.query(SelectionOfferModel)
        .filter(SelectionOfferModel.is_active == True)
        .order_by(SelectionOfferModel.min_amount)
        .all()
    )


# Get selection offer by ID
@router.get("/{offer_id}", response_model=SelectionOffer)
def get_selection_offer(offer_id: int, db: Session = Depends(get_db)):
    db_offer = (
        db.query(SelectionOfferModel).filter(SelectionOfferModel.id == offer_id).first()
    )
    if not db_offer:
        raise HTTPException(status_code=404, detail="Selection offer not found")
    return db_offer


# Create new selection offer
@router.post("/", response_model=SelectionOffer)
def create_selection_offer(offer: SelectionOfferCreate, db: Session = Depends(get_db)):
    # Check if an offer with this min_amount already exists
    existing_offer = (
        db.query(SelectionOfferModel)
        .filter(SelectionOfferModel.min_amount == offer.min_amount)
        .first()
    )
    if existing_offer:
        raise HTTPException(
            status_code=400,
            detail=f"Selection offer with minimum amount {offer.min_amount} already exists",
        )

    # Create new offer
    db_offer = SelectionOfferModel(
        min_amount=offer.min_amount,
        discount_amount=offer.discount_amount,
        is_active=offer.is_active,
        description=offer.description,
        created_at=datetime.now(timezone.utc),
        updated_at=datetime.now(timezone.utc),
    )
    db.add(db_offer)
    db.commit()
    db.refresh(db_offer)
    return db_offer


# Update selection offer
@router.put("/{offer_id}", response_model=SelectionOffer)
def update_selection_offer(
    offer_id: int, offer_update: SelectionOfferUpdate, db: Session = Depends(get_db)
):
    db_offer = (
        db.query(SelectionOfferModel).filter(SelectionOfferModel.id == offer_id).first()
    )
    if not db_offer:
        raise HTTPException(status_code=404, detail="Selection offer not found")

    # Check if updating min_amount and if it already exists
    if (
        offer_update.min_amount is not None
        and offer_update.min_amount != db_offer.min_amount
    ):
        existing_offer = (
            db.query(SelectionOfferModel)
            .filter(
                SelectionOfferModel.min_amount == offer_update.min_amount,
                SelectionOfferModel.id != offer_id,
            )
            .first()
        )
        if existing_offer:
            raise HTTPException(
                status_code=400,
                detail=f"Selection offer with minimum amount {offer_update.min_amount} already exists",
            )
        db_offer.min_amount = offer_update.min_amount

    # Update other fields if provided
    if offer_update.discount_amount is not None:
        db_offer.discount_amount = offer_update.discount_amount
    if offer_update.is_active is not None:
        db_offer.is_active = offer_update.is_active
    if offer_update.description is not None:
        db_offer.description = offer_update.description

    db_offer.updated_at = datetime.now(timezone.utc)
    db.commit()
    db.refresh(db_offer)
    return db_offer


# Delete selection offer
@router.delete("/{offer_id}")
def delete_selection_offer(offer_id: int, db: Session = Depends(get_db)):
    db_offer = (
        db.query(SelectionOfferModel).filter(SelectionOfferModel.id == offer_id).first()
    )
    if not db_offer:
        raise HTTPException(status_code=404, detail="Selection offer not found")

    db.delete(db_offer)
    db.commit()
    return {"message": "Selection offer deleted successfully"}


# Get applicable discount for an order amount
@router.get("/discount/{order_amount}")
def get_discount_for_order_amount(order_amount: float, db: Session = Depends(get_db)):
    # Find the highest tier that the order amount qualifies for
    applicable_offer = (
        db.query(SelectionOfferModel)
        .filter(
            SelectionOfferModel.min_amount <= order_amount,
            SelectionOfferModel.is_active == True,
        )
        .order_by(SelectionOfferModel.min_amount.desc())
        .first()
    )

    if not applicable_offer:
        return {
            "discount_amount": 0,
            "message": "No applicable selection offer discount",
        }

    return {
        "discount_amount": applicable_offer.discount_amount,
        "offer_id": applicable_offer.id,
        "min_amount": applicable_offer.min_amount,
        "message": f"Selection offer discount of ${applicable_offer.discount_amount} applied",
    }