from sqlalchemy.orm import Session, joinedload
from typing import Optional, List
from .models import Cancellationrequest


def get_by_id(db: Session, entity_id: str) -> Optional[Cancellationrequest]:
    return db.query(Cancellationrequest).filter(Cancellationrequest.id == entity_id).first()


def list_all(db: Session, limit: int = 20, offset: int = 0, **filters) -> List[Cancellationrequest]:
    query = db.query(Cancellationrequest)
    
    if "status" in filters and filters["status"] is not None:
        query = query.filter(Cancellationrequest.status == filters["status"])
    
    if "customer_id" in filters and filters["customer_id"]:
        query = query.filter(Cancellationrequest.customer_id == filters["customer_id"])
    
    if "booking_id" in filters and filters["booking_id"]:
        query = query.filter(Cancellationrequest.booking_id == filters["booking_id"])
    
    return query.order_by(Cancellationrequest.created_at.desc()).limit(limit).offset(offset).all()


def create(db: Session, data: dict) -> Cancellationrequest:
    cancellation_request = Cancellationrequest(**data)
    db.add(cancellation_request)
    db.flush()
    return cancellation_request


def update(db: Session, entity_id: str, data: dict) -> Optional[Cancellationrequest]:
    cancellation_request = get_by_id(db, entity_id)
    if not cancellation_request:
        return None
    
    for key, value in data.items():
        setattr(cancellation_request, key, value)
    
    db.flush()
    return cancellation_request


def delete(db: Session, entity_id: str) -> bool:
    cancellation_request = get_by_id(db, entity_id)
    if not cancellation_request:
        return False
    
    db.delete(cancellation_request)
    db.flush()
    return True


def get_with_details(db: Session, entity_id: str) -> Optional[Cancellationrequest]:
    from booking_management.models import Booking, Tourschedule
    from tour_catalog.models import Tourpackage
    from user_management.models import Customer, User
    
    return (
        db.query(Cancellationrequest)
        .options(
            joinedload(Cancellationrequest.booking)
                .joinedload(Booking.tour_schedule)
                .joinedload(Tourschedule.tour_package),
            joinedload(Cancellationrequest.booking)
                .joinedload(Booking.customer)
                .joinedload(Customer.user),
            joinedload(Cancellationrequest.customer)
                .joinedload(Customer.user),
            joinedload(Cancellationrequest.processor),
        )
        .filter(Cancellationrequest.id == entity_id)
        .first()
    )