"""Checkout session business logic."""

from typing import Optional

from sqlalchemy.orm import Session

from ..models import CheckoutSession, Event, Partner
from ..repositories import checkout_sessions as session_repo
from ..repositories import events as event_repo
from ..schemas import CheckoutSessionCreate, PayoutUpdateIn


def create_session(
    db: Session, partner: Partner, payload: CheckoutSessionCreate
) -> CheckoutSession:
    session = CheckoutSession(
        partner_id=partner.id,
        external_order_id=payload.external_order_id,
        amount=payload.amount,
        currency=payload.currency.upper(),
        success_url=payload.success_url,
        cancel_url=payload.cancel_url,
        customer_email=payload.customer_email,
        customer_name=payload.customer_name,
        customer_country=payload.customer_country,
        service_type=payload.service_type,
        channel=payload.channel,
        consent_analytics=bool(payload.consent_analytics),
        consent_marketing=bool(payload.consent_marketing),
        status="pending",
    )
    session_repo.create_session(db, session)
    event_repo.create_event(
        db,
        Event(
            session_id=session.id,
            type="created",
            payload={
                "status": "pending",
                "consent_analytics": session.consent_analytics,
                "consent_marketing": session.consent_marketing,
            },
        ),
    )
    session_repo.commit(db)
    session_repo.refresh(db, session)
    return session


def get_session_for_partner(
    db: Session, session_id: str, partner: Partner
) -> Optional[CheckoutSession]:
    session = session_repo.get_session(db, session_id)
    if not session or session.partner_id != partner.id:
        return None
    return session


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


def update_payout(
    db: Session, session: CheckoutSession, payload: PayoutUpdateIn
) -> CheckoutSession:
    session_repo.update_payout(
        session,
        payload.payout_status,
        payload.payout_method,
        payload.payout_batch_id,
        payload.payout_paid_at,
    )
    event_repo.create_event(
        db,
        Event(
            session_id=session.id,
            type="payout_updated",
            payload={
                "payout_status": payload.payout_status,
                "payout_method": payload.payout_method,
                "payout_batch_id": payload.payout_batch_id,
                "payout_paid_at": (
                    payload.payout_paid_at.isoformat() if payload.payout_paid_at else None
                ),
            },
        ),
    )
    session_repo.commit(db)
    session_repo.refresh(db, session)
    return session


def mark_paid(
    db: Session,
    session: CheckoutSession,
    status: str,
    provider_event_id: str,
    payload: dict,
) -> None:
    session_repo.update_status(db, session, status)
    event_repo.create_event(
        db,
        Event(
            session_id=session.id,
            type="webhook_received",
            provider_event_id=provider_event_id,
            payload=payload,
        ),
    )
    session_repo.commit(db)
