"""Pydantic schemas for the Checkouts module."""
from datetime import datetime
from typing import Any, Dict, List, Optional
from pydantic import BaseModel, EmailStr, Field


# ─── Line Items ──────────────────────────────────────────────────────────────

class CheckoutLineItemSchema(BaseModel):
    id: Optional[int] = None
    product_id: Optional[int] = None
    title: Optional[str] = None
    description: Optional[str] = None
    quantity: float = 1.0
    unit_price: float = 0.0
    discount_amount: float = 0.0
    tax: Optional[float] = 0.0
    tax_amount: Optional[float] = 0.0


# ─── Link ────────────────────────────────────────────────────────────────────

class CheckoutLinkSchema(BaseModel):
    id: int
    token: str
    status: str
    click_count: int
    created_at: datetime

    class Config:
        from_attributes = True


# ─── Create / Update ──────────────────────────────────────────────────────────

class CreateCheckoutRequest(BaseModel):
    title: str
    description: Optional[str] = None
    checkout_type: str = "MERCHANT_DEFINED"
    # Merchant Defined
    amount: Optional[float] = None
    currency: str = "USD"
    # Payer Defined
    min_amount: Optional[float] = None
    max_amount: Optional[float] = None
    suggested_amounts: Optional[List[float]] = None
    default_amount: Optional[float] = None
    # Tip
    tip_enabled: bool = False
    tip_type: Optional[str] = None
    tip_percentages: Optional[List[int]] = None
    tip_allow_custom: bool = False
    # Payment config
    payment_frequency: str = "SINGLE"
    authorization_type: Optional[str] = None
    authorization_method: Optional[str] = None  # "CHECKBOX" | "SIGNATURE" | "SMS"
    require_billing_address: bool = False
    require_cvv: bool = False
    split_config: Optional[dict] = None
    recurring_config: Optional[dict] = None
    # Verification
    require_payer_verification: bool = False
    payer_verification_type: Optional[str] = None
    # Link
    expires_at: Optional[datetime] = None
    allow_link_regeneration: bool = True
    # Post-payment
    redirect_url: Optional[str] = None
    thank_you_message: Optional[str] = None
    # Status — mutually exclusive with is_draft; is_draft takes precedence if provided
    status: str = "DRAFT"
    is_draft: Optional[bool] = None
    # Tax
    tax_percent: Optional[float] = Field(default=0.0)
    tax_type: Optional[str] = Field(default="notax", pattern="^(tax_exclusive|tax_inclusive|notax)$")
    # Line items
    line_items: Optional[List[CheckoutLineItemSchema]] = []
    # Additional settings (cost adjustment, discount, late fee, attachment)
    adjustment_config: Optional[dict] = None


class UpdateCheckoutRequest(CreateCheckoutRequest):
    regenerate_link: bool = False


# ─── Responses ────────────────────────────────────────────────────────────────

class CheckoutResponse(BaseModel):
    id: int
    checkout_literal: Optional[str]
    title: str
    description: Optional[str]
    checkout_type: str
    status: str
    amount: Optional[float]
    currency: str
    min_amount: Optional[float]
    max_amount: Optional[float]
    suggested_amounts: Optional[list]
    default_amount: Optional[float]
    tip_enabled: bool
    tip_type: Optional[str]
    tip_percentages: Optional[list]
    tip_allow_custom: bool
    tax_percent: Optional[float]
    tax_type: Optional[str]
    payment_frequency: str
    authorization_type: Optional[str]
    authorization_method: Optional[str]
    require_billing_address: bool
    require_cvv: bool
    split_config: Optional[dict]
    recurring_config: Optional[dict]
    require_payer_verification: bool
    payer_verification_type: Optional[str]
    expires_at: Optional[datetime]
    allow_link_regeneration: bool
    redirect_url: Optional[str]
    thank_you_message: Optional[str]
    active_link: Optional[CheckoutLinkSchema]
    line_items: List[CheckoutLineItemSchema]
    adjustment_config: Optional[dict] = None
    created_at: datetime
    updated_at: Optional[datetime]

    class Config:
        from_attributes = True


class CheckoutListItemSchema(BaseModel):
    id: int
    checkout_literal: Optional[str]
    title: str
    checkout_type: str
    status: str
    amount: Optional[float]
    max_amount: Optional[float]
    currency: str
    active_link_token: Optional[str]
    click_count: int = 0
    created_at: datetime

    class Config:
        from_attributes = True


class CheckoutSummaryResponse(BaseModel):
    draft_count: int = 0
    active_count: int = 0
    inactive_count: int = 0
    expired_count: int = 0
    active_total_collected: float = 0.0
    total_link_views: int = 0


# ─── Share ────────────────────────────────────────────────────────────────────

class ShareCheckoutRequest(BaseModel):
    customer_ids: Optional[List[int]] = []
    free_form_emails: Optional[List[str]] = []
    free_form_phones: Optional[List[str]] = []
    channels: List[str]
    message_override: Optional[str] = None


# ─── Bulk Actions ─────────────────────────────────────────────────────────────

class BulkActionRequest(BaseModel):
    checkout_literals: List[str]
    action: str  # "activate" | "deactivate" | "delete"


# ─── Analytics ────────────────────────────────────────────────────────────────

class CheckoutAnalyticsResponse(BaseModel):
    period: str
    total_collected: float = 0.0
    total_authorized: float = 0.0
    transaction_count: int = 0
    unique_payers: int = 0
    link_views: int = 0
    conversion_rate: float = 0.0
    average_transaction_amount: float = 0.0
    tip_total: float = 0.0
    new_customers_created: int = 0
    returning_payers: int = 0
    daily_series: List[Dict[str, Any]] = []


# ─── Settings ─────────────────────────────────────────────────────────────────

class CheckoutSettingsResponse(BaseModel):
    default_tip_enabled: bool = False
    default_tip_percentages: Optional[list] = None
    default_thank_you_message: Optional[str] = None
    default_redirect_url: Optional[str] = None
    default_require_payer_verification: bool = False
    default_payer_verification_type: Optional[str] = None

    class Config:
        from_attributes = True


class CheckoutSettingsUpdate(BaseModel):
    default_tip_enabled: Optional[bool] = None
    default_tip_percentages: Optional[list] = None
    default_thank_you_message: Optional[str] = None
    default_redirect_url: Optional[str] = None
    default_require_payer_verification: Optional[bool] = None
    default_payer_verification_type: Optional[str] = None


# ─── Public (no auth) ─────────────────────────────────────────────────────────

class MerchantBrandingSchema(BaseModel):
    merchant_name: Optional[str] = None
    logo_url: Optional[str] = None
    primary_color: Optional[str] = None


class PublicCheckoutResponse(BaseModel):
    token: str
    title: str
    description: Optional[str]
    checkout_type: str
    amount: Optional[float]
    currency: str
    min_amount: Optional[float]
    max_amount: Optional[float]
    suggested_amounts: Optional[list]
    default_amount: Optional[float]
    tip_enabled: bool
    tip_type: Optional[str]
    tip_percentages: Optional[list]
    tip_allow_custom: bool = False
    payment_frequency: str
    authorization_type: Optional[str]
    authorization_method: Optional[str]
    require_billing_address: bool = False
    require_cvv: bool = False
    split_config: Optional[dict] = None
    recurring_config: Optional[dict] = None
    require_payer_verification: bool
    payer_verification_type: Optional[str]
    thank_you_message: Optional[str]
    redirect_url: Optional[str] = None
    line_items: List[CheckoutLineItemSchema]
    merchant_branding: MerchantBrandingSchema
    expires_at: Optional[datetime]


class CheckoutEmailCheckRequest(BaseModel):
    email: EmailStr


class CheckoutEmailCheckResponse(BaseModel):
    exists: bool


class CheckoutRegisterRequest(BaseModel):
    first_name: str
    last_name: str
    email: EmailStr
    phone: Optional[str] = None
    business_legal_name: Optional[str] = None
    billing_address: Optional[dict] = None
    # Flat address fields (sent by the checkout registration form)
    address: Optional[str] = None
    city: Optional[str] = None
    state: Optional[str] = None
    zip: Optional[str] = None
    country: Optional[str] = None
    password: str


class CheckoutLoginRequest(BaseModel):
    email: EmailStr
    password: str


class CheckoutSubmitRequest(BaseModel):
    amount: Optional[float] = None
    tip_amount: float = 0.0
    payment_method_token: Optional[str] = None
    hosted_form_token: Optional[str] = None
    billing_info: Optional[dict] = None
    shipping_info: Optional[dict] = None
    authorization_data: Optional[dict] = None
    customer_id: Optional[int] = None


class PayerTokenResponse(BaseModel):
    access_token: str
    token_type: str = "bearer"
    expires_in: int
    customer_id: Optional[int] = None
    user_id: int


class ForgotPasswordRequest(BaseModel):
    email: EmailStr


class ResetPasswordConfirmRequest(BaseModel):
    reset_token: str
    new_password: str


class PayerProfileUpdate(BaseModel):
    first_name: Optional[str] = None
    last_name: Optional[str] = None
    phone: Optional[str] = None


class ChangePasswordRequest(BaseModel):
    current_password: str
    new_password: str
