from datetime import datetime
from typing import Optional, TypedDict, Dict, Any

from pydantic import BaseModel, Field

from .base import NotchPayPaginatedResponse, NotchPayResponse
from .channels import NotchPayChannels
from .payments import NotchPayPayment

__all__ = [
    "NotchPayCustomer",
    "NotchPayCustomerCreate",
    "NotchPayCustomerUpdate",
    "NotchPayCustomerResponse",
    "NotchPayPaymentMethod",
    "NotchPayPaymentMethodsResponse",
    "NotchPayCustomerPaymentsResponse",
]


class NotchPayCustomer(BaseModel):
    """Model representing a NotchPay customer.

    Attributes:
        id: Unique customer identifier (e.g., "cus.test_123456789").
        name: Customer name.
        email: Customer email address.
        phone: Customer phone number.
        company_name: Company name.
        tax_number: Tax identification number.
        metadata: Custom metadata.
        created_at: Customer creation date.
        updated_at: Last update date.
    """

    id: str = Field(..., description="Unique customer identifier")
    name: Optional[str] = Field(None, description="Customer name")
    email: Optional[str] = Field(None, description="Customer email address")
    phone: Optional[str] = Field(None, description="Customer phone number")
    company_name: Optional[str] = Field(None, description="Company name")
    tax_number: Optional[str] = Field(
        None, description="Tax identification number")
    metadata: Optional[Dict[str, Any]] = Field(
        None, description="Custom metadata")
    created_at: datetime = Field(..., description="Creation date")
    updated_at: datetime = Field(..., description="Update date")


class NotchPayCustomerCreate(TypedDict, total=False):
    """Model for creating a customer.

    Attributes:
        name: Customer name.
        email: Customer email (required if phone is not provided).
        phone: Customer phone (required if email is not provided).
        company_name: Company name.
        tax_number: Tax identification number.
        metadata: Custom metadata.
    """

    name: Optional[str]
    """Customer name."""

    email: Optional[str]
    """Customer email."""

    phone: Optional[str]
    """Customer phone number."""

    company_name: Optional[str]
    """Company name."""

    tax_number: Optional[str]
    """Tax identification number."""

    metadata: Optional[Dict[str, Any]]
    """Custom metadata."""


class NotchPayCustomerUpdate(NotchPayCustomerCreate, total=False):
    """Model for updating a customer."""
    pass


class NotchPayCustomerResponse(NotchPayResponse):
    """Customer detail response."""

    customer: NotchPayCustomer = Field(..., description="Customer details")


class NotchPayCustomerPaymentsResponse(NotchPayPaginatedResponse):
    """Customer payments list response."""

    payments: list[NotchPayPayment] = Field(..., description="List of payments")


class NotchPayPaymentMethod(BaseModel):
    """Model representing a customer's payment method.

    Attributes:
        id: Unique payment method identifier.
        type: Payment method type.
        channel: Payment channel.
        email: Associated email address.
        name: Associated name.
        country: Country code.
        account_number: Account number.
        issuer: Payment method issuer.
        issuer_code: Issuer code.
        phone: Associated phone number.
        created_at: Creation date.
    """

    id: str = Field(..., description="Unique identifier")
    type: Optional[str] = Field(None, description="Payment method type")
    channel: NotchPayChannels = Field(..., description="Payment channel")
    email: Optional[str] = Field(None, description="Associated email")
    name: Optional[str] = Field(None, description="Associated name")
    country: Optional[str] = Field(None, description="Country code")
    account_number: Optional[str] = Field(None, description="Account number")
    issuer: Optional[str] = Field(None, description="Issuer")
    issuer_code: Optional[str] = Field(None, description="Issuer code")
    phone: Optional[str] = Field(None, description="Phone number")
    created_at: Optional[datetime] = Field(None, description="Creation date")


class NotchPayPaymentMethodsResponse(NotchPayResponse):
    """Customer payment methods list response."""

    items: list[NotchPayPaymentMethod] = Field(
        ..., description="List of payment methods")
