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

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

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

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

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

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

def get_with_details(db: Session, dispute_id: str) -> Optional[Dispute]:
    return (
        db.query(Dispute)
        .options(
            joinedload(Dispute.order).subqueryload("order_items"),
            joinedload(Dispute.complainant),
            joinedload(Dispute.respondent),
            joinedload(Dispute.resolved_by)
        )
        .filter(Dispute.id == dispute_id)
        .first()
    )