"""Checkout session data access helpers."""

from datetime import datetime
from typing import Optional

from sqlalchemy import case, func
from sqlalchemy.orm import Session

from ..models import CheckoutSession


def get_session(db: Session, session_id: str) -> Optional[CheckoutSession]:
    return db.get(CheckoutSession, session_id)


def create_session(db: Session, session: CheckoutSession) -> CheckoutSession:
    db.add(session)
    db.flush()
    return session


def commit(db: Session) -> None:
    db.commit()


def refresh(db: Session, session: CheckoutSession) -> CheckoutSession:
    db.refresh(session)
    return session


def update_status(db: Session, session: CheckoutSession, status: str) -> CheckoutSession:
    session.status = status
    session.updated_at = datetime.utcnow()
    return session


def update_payout(
    session: CheckoutSession,
    payout_status: str,
    payout_method: Optional[str],
    payout_batch_id: Optional[str],
    payout_paid_at: Optional[datetime],
) -> CheckoutSession:
    session.payout_status = payout_status
    session.payout_method = payout_method
    session.payout_batch_id = payout_batch_id
    session.payout_paid_at = payout_paid_at
    return session


def list_sessions_filtered(
    db: Session,
    partner_id: str,
    q: Optional[str],
    status: Optional[str],
    payout_status: Optional[str],
    date_from: Optional[datetime],
    date_to: Optional[datetime],
):
    query = db.query(CheckoutSession).filter(CheckoutSession.partner_id == partner_id)
    if q:
        like = f"%{q}%"
        query = query.filter(
            (CheckoutSession.external_order_id.ilike(like))
            | (CheckoutSession.customer_email.ilike(like))
        )
    if status:
        query = query.filter(CheckoutSession.status == status)
    if payout_status:
        query = query.filter(CheckoutSession.payout_status == payout_status)
    if date_from:
        query = query.filter(CheckoutSession.created_at >= date_from)
    if date_to:
        query = query.filter(CheckoutSession.created_at <= date_to)
    return query


def get_totals(db: Session, partner_id: str):
    return (
        db.query(
            func.coalesce(func.sum(CheckoutSession.amount), 0),
            func.coalesce(
                func.sum(
                    case(
                        (CheckoutSession.payout_status != "paid", CheckoutSession.amount),
                        else_=0,
                    )
                ),
                0,
            ),
        )
        .filter(CheckoutSession.partner_id == partner_id)
        .first()
    )
