# -*- coding: utf-8 -*-
"""크레딧 충전/차감 (원장 기록). castad credit_service 패턴 축약."""
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from .models import CreditTransaction, User


class InsufficientCreditError(Exception):
    pass


async def _record(session, user_uuid, amount, balance_after, type_, reason):
    tx = CreditTransaction(
        user_uuid=user_uuid, amount=amount, balance_after=balance_after, type=type_, reason=reason,
    )
    session.add(tx)
    return tx


async def charge(session: AsyncSession, user_uuid: str, amount: int, type_: str = "charge", reason: str | None = None):
    user = (await session.execute(select(User).where(User.user_uuid == user_uuid).with_for_update())).scalar_one_or_none()
    if user is None:
        raise ValueError("user not found")
    user.credits += amount
    await session.flush()
    return await _record(session, user_uuid, amount, user.credits, type_, reason)


async def deduct(session: AsyncSession, user_uuid: str, amount: int, type_: str = "consume", reason: str | None = None):
    user = (await session.execute(select(User).where(User.user_uuid == user_uuid).with_for_update())).scalar_one_or_none()
    if user is None:
        raise ValueError("user not found")
    if user.credits < amount:
        raise InsufficientCreditError()
    user.credits -= amount
    await session.flush()
    return await _record(session, user_uuid, -amount, user.credits, type_, reason)
