"""Manual adapter — operator-initiated mints (comps, support replacements).

There is no webhook to verify and no payload to parse: the operator
hands us the buyer details directly via the CLI, and we construct a
:class:`SaleEvent` from them. ``source='manual'`` separates these
rows from storefront-driven mints in the DB.
"""

from __future__ import annotations

from decimal import Decimal
from typing import Any, Optional

from app.adapters.base import RefundEvent, SaleEvent


class ManualAdapter:
    source_name = "manual"

    def verify_webhook(self, *, body: bytes, headers: dict[str, str]) -> bool:
        return False  # manual flows never come through webhooks

    def parse_sale(self, payload: dict[str, Any]) -> Optional[SaleEvent]:
        return self.build_sale(**payload)

    def parse_refund(self, payload: dict[str, Any]) -> Optional[RefundEvent]:
        return None

    def build_sale(
        self,
        *,
        name: str,
        email: str,
        tier: str,
        years: int = 1,
        promotion: Optional[str] = None,
        amount_paid: Optional[Decimal] = None,
        currency: Optional[str] = "USD",
        notes: Optional[str] = None,
    ) -> SaleEvent:
        return SaleEvent(
            source=self.source_name,
            source_order_id=None,
            buyer_name=name,
            buyer_email=email,
            tier=tier,
            years=years,
            promotion=promotion,
            amount_paid=amount_paid,
            currency=currency,
            notes=notes,
        )
