"""Payments customers domain — sync and async mixins."""

from __future__ import annotations

from typing import Any

from ...exceptions import api_error_handler, async_api_error_handler
from ..._api.generated.payments.payments__api__payments.models import (
    CustomerBalance,
    CustomerCreateRequest,
    CustomerDetail,
    PaginatedCustomerListList,
    PaginatedCustomerTransactionList,
    PatchedCustomerUpdateRequest,
)


class _CustomersMixin:
    """Sync customer methods."""

    _api: Any

    @api_error_handler
    def list_customers(
        self,
        project_slug: str,
        *,
        page: int = 1,
        page_size: int = 20,
        search: str | None = None,
        ordering: str | None = None,
    ) -> PaginatedCustomerListList:
        """List customers for a project."""
        return self._api.projects_customers_list(
            project_slug,
            ordering=ordering,
            page=page,
            page_size=page_size,
            search=search,
        )

    @api_error_handler
    def create_customer(
        self,
        project_slug: str,
        *,
        display_name: str,
        external_id: str | None = None,
        email: str | None = None,
        metadata: dict[str, Any] | None = None,
    ) -> CustomerDetail:
        """Create a new customer for a project."""
        request = CustomerCreateRequest(
            display_name=display_name,
            external_id=external_id,
            email=email,
            metadata=metadata,
        )
        return self._api.projects_customers_create(project_slug, request)

    @api_error_handler
    def get_customer(self, customer_id: str, project_slug: str) -> CustomerDetail:
        """Get customer details."""
        return self._api.projects_customers_retrieve(customer_id, project_slug)

    @api_error_handler
    def update_customer(
        self,
        customer_id: str,
        project_slug: str,
        *,
        display_name: str | None = None,
        external_id: str | None = None,
        email: str | None = None,
        metadata: dict[str, Any] | None = None,
    ) -> CustomerDetail:
        """Partially update a customer."""
        request = PatchedCustomerUpdateRequest(
            display_name=display_name,
            email=email,
            metadata=metadata,
        )
        return self._api.projects_customers_partial_update(customer_id, project_slug, request)

    @api_error_handler
    def customer_balance(self, customer_id: str, project_slug: str) -> CustomerBalance:
        """Get customer balance."""
        return self._api.projects_customers_balance_retrieve(customer_id, project_slug)

    @api_error_handler
    def customer_transactions(
        self,
        customer_id: str,
        project_slug: str,
        *,
        page: int = 1,
        page_size: int = 20,
    ) -> PaginatedCustomerTransactionList:
        """List transactions for a customer."""
        return self._api.projects_customers_transactions_list(
            customer_id,
            project_slug,
            page=page,
            page_size=page_size,
        )


class _AsyncCustomersMixin:
    """Async customer methods."""

    _api: Any

    @async_api_error_handler
    async def list_customers(
        self,
        project_slug: str,
        *,
        page: int = 1,
        page_size: int = 20,
        search: str | None = None,
        ordering: str | None = None,
    ) -> PaginatedCustomerListList:
        """List customers for a project."""
        return await self._api.projects_customers_list(
            project_slug,
            ordering=ordering,
            page=page,
            page_size=page_size,
            search=search,
        )

    @async_api_error_handler
    async def create_customer(
        self,
        project_slug: str,
        *,
        display_name: str,
        external_id: str | None = None,
        email: str | None = None,
        metadata: dict[str, Any] | None = None,
    ) -> CustomerDetail:
        """Create a new customer for a project."""
        request = CustomerCreateRequest(
            display_name=display_name,
            external_id=external_id,
            email=email,
            metadata=metadata,
        )
        return await self._api.projects_customers_create(project_slug, request)

    @async_api_error_handler
    async def get_customer(self, customer_id: str, project_slug: str) -> CustomerDetail:
        """Get customer details."""
        return await self._api.projects_customers_retrieve(customer_id, project_slug)

    @async_api_error_handler
    async def update_customer(
        self,
        customer_id: str,
        project_slug: str,
        *,
        display_name: str | None = None,
        external_id: str | None = None,
        email: str | None = None,
        metadata: dict[str, Any] | None = None,
    ) -> CustomerDetail:
        """Partially update a customer."""
        request = PatchedCustomerUpdateRequest(
            display_name=display_name,
            email=email,
            metadata=metadata,
        )
        return await self._api.projects_customers_partial_update(customer_id, project_slug, request)

    @async_api_error_handler
    async def customer_balance(self, customer_id: str, project_slug: str) -> CustomerBalance:
        """Get customer balance."""
        return await self._api.projects_customers_balance_retrieve(customer_id, project_slug)

    @async_api_error_handler
    async def customer_transactions(
        self,
        customer_id: str,
        project_slug: str,
        *,
        page: int = 1,
        page_size: int = 20,
    ) -> PaginatedCustomerTransactionList:
        """List transactions for a customer."""
        return await self._api.projects_customers_transactions_list(
            customer_id,
            project_slug,
            page=page,
            page_size=page_size,
        )
