"""Cloud credit wallet. Consumption may drive the balance negative."""
from __future__ import annotations

from dataclasses import dataclass
from uuid import UUID

from src.domain.cloud_credits.repository import CloudCreditLedgerRepository

USAGE_SOURCE = "cloud_usage_snapshot"
PURCHASE_SOURCE = "stripe_checkout"


@dataclass(frozen=True)
class CloudUsageSettlement:
    reference: str
    millicredits: int
    already_settled: bool = False


class CloudCreditWallet:
    def __init__(self, ledger: CloudCreditLedgerRepository) -> None:
        self._ledger = ledger

    async def balance_millicredits(self, workspace_id: UUID) -> int:
        return await self._ledger.sum_balance(workspace_id)

    async def credit_purchase(
        self,
        *,
        workspace_id: UUID,
        millicredits: int,
        purchase_id: UUID,
        source_id: str,
        description: str,
    ) -> None:
        await self._ledger.acquire_lock(workspace_id)
        existing = await self._ledger.list_by_source(workspace_id, PURCHASE_SOURCE, source_id)
        if existing:
            return
        await self._ledger.add_entry(
            workspace_id=workspace_id,
            entry_type="purchase",
            millicredits_delta=millicredits,
            source_type=PURCHASE_SOURCE,
            source_id=source_id,
            purchase_id=purchase_id,
            description=description,
        )

    async def settle_usage(
        self,
        *,
        workspace_id: UUID,
        snapshot_date: str,
        millicredits: int,
        metrics: dict,
    ) -> CloudUsageSettlement:
        """Idempotent daily deduction. Zero usage is recorded for audit."""
        reference = f"snapshot:{snapshot_date}"
        await self._ledger.acquire_lock(workspace_id)
        existing = await self._ledger.list_by_source(workspace_id, USAGE_SOURCE, reference)
        if existing:
            charged = sum(-e.millicredits_delta for e in existing if e.millicredits_delta < 0)
            return CloudUsageSettlement(reference, charged, already_settled=True)
        await self._ledger.add_entry(
            workspace_id=workspace_id,
            entry_type="consumption",
            millicredits_delta=-abs(millicredits),
            source_type=USAGE_SOURCE,
            source_id=reference,
            description=f"Cloud usage for {snapshot_date}",
            metadata={"metrics": metrics, "snapshot_date": snapshot_date},
            allow_zero=True,
        )
        return CloudUsageSettlement(reference, millicredits)
