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


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


def list_all(db: Session, limit: int = 20, offset: int = 0, **filters) -> List[Review]:
    query = db.query(Review)
    
    if "order_id" in filters and filters["order_id"]:
        query = query.filter(Review.order_id == filters["order_id"])
    
    if "reviewer_id" in filters and filters["reviewer_id"]:
        query = query.filter(Review.reviewer_id == filters["reviewer_id"])
    
    if "seller_id" in filters and filters["seller_id"]:
        query = query.filter(Review.seller_id == filters["seller_id"])
    
    if "rating" in filters and filters["rating"] is not None:
        query = query.filter(Review.rating == filters["rating"])
    
    if "is_verified_purchase" in filters and filters["is_verified_purchase"] is not None:
        query = query.filter(Review.is_verified_purchase == filters["is_verified_purchase"])
    
    return query.order_by(Review.created_at.desc()).limit(limit).offset(offset).all()


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


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


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


def get_with_details(db: Session, entity_id: str) -> Optional[Review]:
    return (
        db.query(Review)
        .options(
            joinedload(Review.order),
            joinedload(Review.reviewer).joinedload("user_profile"),
            joinedload(Review.seller).joinedload("seller_profile")
        )
        .filter(Review.id == entity_id)
        .first()
    )