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

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

def list_all(db: Session, limit: int = 20, offset: int = 0, **filters) -> List[Offer]:
    query = db.query(Offer)
    
    if "listing_id" in filters and filters["listing_id"]:
        query = query.filter(Offer.listing_id == filters["listing_id"])
    
    if "buyer_id" in filters and filters["buyer_id"]:
        query = query.filter(Offer.buyer_id == filters["buyer_id"])
    
    if "status" in filters and filters["status"]:
        query = query.filter(Offer.status == filters["status"])
    
    return query.order_by(Offer.created_at.desc()).limit(limit).offset(offset).all()

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

def update(db: Session, entity_id: str, data: dict) -> Optional[Offer]:
    offer = db.query(Offer).filter(Offer.id == entity_id).first()
    if not offer:
        return None
    for key, value in data.items():
        setattr(offer, key, value)
    db.flush()
    return offer

def delete(db: Session, entity_id: str) -> bool:
    offer = db.query(Offer).filter(Offer.id == entity_id).first()
    if not offer:
        return False
    db.delete(offer)
    db.flush()
    return True

def get_with_details(db: Session, entity_id: str) -> Optional[Offer]:
    return (
        db.query(Offer)
        .options(
            joinedload(Offer.listing),
            joinedload(Offer.buyer)
        )
        .filter(Offer.id == entity_id)
        .first()
    )