# app/modules/tenancy/schemas/merchant.py
"""
Pydantic schemas for Merchant model.

These schemas are used for API request/response validation and serialization.
"""

from datetime import datetime
from typing import Any

from pydantic import BaseModel, ConfigDict, EmailStr, Field, field_validator

from app.modules.tenancy.schemas.store import StoreSummary


class MerchantBase(BaseModel):
    """Base schema for merchant with common fields."""

    name: str = Field(..., min_length=2, max_length=200, description="Merchant name")
    description: str | None = Field(None, description="Merchant description")
    contact_email: EmailStr = Field(..., description="Business contact email")
    contact_phone: str | None = Field(None, description="Business phone number")
    website: str | None = Field(None, description="Merchant website URL")
    business_address: str | None = Field(None, description="Physical business address")
    tax_number: str | None = Field(None, description="Tax/VAT registration number")

    @field_validator("contact_email")
    @classmethod
    def normalize_email(cls, v):
        """Normalize email to lowercase."""
        return v.lower() if v else v


class MerchantCreate(MerchantBase):
    """
    Schema for creating a new merchant.

    Requires owner_email to create the associated owner user account.
    """

    owner_email: EmailStr = Field(
        ..., description="Email for the merchant owner account"
    )

    @field_validator("owner_email")
    @classmethod
    def normalize_owner_email(cls, v):
        """Normalize owner email to lowercase."""
        return v.lower() if v else v

    model_config = ConfigDict(from_attributes=True)


class MerchantUpdate(BaseModel):
    """
    Schema for updating merchant information.

    All fields are optional to support partial updates.
    """

    name: str | None = Field(None, min_length=2, max_length=200)
    description: str | None = None
    contact_email: EmailStr | None = None
    contact_phone: str | None = None
    website: str | None = None
    business_address: str | None = None
    tax_number: str | None = None

    # Status (Admin only)
    is_active: bool | None = None
    is_verified: bool | None = None

    @field_validator("contact_email")
    @classmethod
    def normalize_email(cls, v):
        """Normalize email to lowercase."""
        return v.lower() if v else v

    model_config = ConfigDict(from_attributes=True)


class MerchantResponse(BaseModel):
    """Standard schema for merchant response data."""

    model_config = ConfigDict(from_attributes=True)

    id: int
    name: str
    description: str | None

    # Owner information
    owner_user_id: int
    owner_email: str | None = Field(None, description="Owner's email address")

    # Contact Information
    contact_email: str
    contact_phone: str | None
    website: str | None

    # Business Information
    business_address: str | None
    tax_number: str | None

    # Status Flags
    is_active: bool
    is_verified: bool

    # Timestamps
    created_at: str
    updated_at: str

    # Store statistics
    store_count: int = Field(0, description="Number of stores under this merchant")


class MerchantDetailResponse(MerchantResponse):
    """
    Detailed merchant response including store count and owner details.

    Used for merchant detail pages and admin views.
    """

    # Owner details (from related User)
    owner_username: str | None = Field(None, description="Owner's username")

    # Store statistics
    active_store_count: int = Field(
        0, description="Number of active stores under this merchant"
    )

    # Stores list (optional, for detail view)
    stores: list | None = Field(None, description="List of stores under this merchant")


class MerchantListResponse(BaseModel):
    """Schema for paginated merchant list."""

    merchants: list[MerchantResponse]
    total: int
    skip: int
    limit: int


class MerchantCreateResponse(BaseModel):
    """
    Response after creating a merchant with owner account.

    Includes temporary password for the owner (shown only once).
    """

    merchant: MerchantResponse
    owner_user_id: int
    owner_username: str
    owner_email: str
    temporary_password: str = Field(
        ..., description="Temporary password for owner (SHOWN ONLY ONCE)"
    )
    login_url: str | None = Field(None, description="URL for merchant owner to login")


class MerchantSummary(BaseModel):
    """Lightweight merchant summary for dropdowns and quick references."""

    model_config = ConfigDict(from_attributes=True)

    id: int
    name: str
    is_active: bool
    is_verified: bool
    store_count: int = 0


class MerchantTransferOwnership(BaseModel):
    """
    Schema for transferring merchant ownership to another user.

    This is a critical operation that requires:
    - Confirmation flag
    - Reason for audit trail (optional)
    """

    new_owner_user_id: int = Field(
        ..., description="ID of the user who will become the new owner", gt=0
    )

    confirm_transfer: bool = Field(
        ..., description="Must be true to confirm ownership transfer"
    )

    transfer_reason: str | None = Field(
        None,
        max_length=500,
        description="Reason for ownership transfer (for audit logs)",
    )

    @field_validator("confirm_transfer")
    @classmethod
    def validate_confirmation(cls, v):
        """Ensure confirmation is explicitly true."""
        if not v:
            raise ValueError("Ownership transfer requires explicit confirmation")
        return v


class MerchantTransferOwnershipResponse(BaseModel):
    """Response after successful ownership transfer."""

    message: str
    merchant_id: int
    merchant_name: str

    old_owner: dict[str, Any] = Field(
        ..., description="Information about the previous owner"
    )
    new_owner: dict[str, Any] = Field(
        ..., description="Information about the new owner"
    )

    transferred_at: datetime
    transfer_reason: str | None


# ============================================================================
# Merchant Portal Schemas (for merchant-facing routes)
# ============================================================================


class MerchantPortalProfileResponse(BaseModel):
    """Merchant profile as seen by the merchant owner."""

    model_config = ConfigDict(from_attributes=True)

    id: int
    name: str
    description: str | None
    contact_email: str
    contact_phone: str | None
    website: str | None
    business_address: str | None
    tax_number: str | None
    is_verified: bool


class MerchantPortalProfileUpdate(BaseModel):
    """Merchant profile update from the merchant portal.
    Excludes admin-only fields (is_active, is_verified)."""

    name: str | None = Field(None, min_length=2, max_length=200)
    description: str | None = None
    contact_email: EmailStr | None = None
    contact_phone: str | None = None
    website: str | None = None
    business_address: str | None = None
    tax_number: str | None = None


class MerchantPortalStoreListResponse(BaseModel):
    """Paginated store list for the merchant portal."""

    stores: list[StoreSummary]
    total: int
    skip: int
    limit: int
    can_create_store: bool = True


class MerchantStoreCreate(BaseModel):
    """Store creation from the merchant portal.
    Subset of admin StoreCreate — excludes admin-only fields."""

    name: str = Field(..., min_length=2, max_length=255, description="Store name")
    store_code: str = Field(
        ..., min_length=2, max_length=50, description="Unique store code"
    )
    subdomain: str = Field(
        ..., min_length=2, max_length=100, description="Store subdomain"
    )
    description: str | None = Field(None, description="Store description")
    platform_ids: list[int] = Field(
        default_factory=list, description="Platform IDs to assign store to"
    )

    @field_validator("subdomain")
    @classmethod
    def validate_subdomain(cls, v):
        """Validate subdomain format."""
        import re

        v = v.lower().strip()
        if not re.match(r"^[a-z0-9][a-z0-9-]*[a-z0-9]$", v) and len(v) > 1:
            raise ValueError(
                "Subdomain must contain only lowercase letters, numbers, and hyphens"
            )
        return v

    @field_validator("store_code")
    @classmethod
    def normalize_store_code(cls, v):
        """Normalize store code to uppercase."""
        return v.upper().strip()


class MerchantStoreDetailResponse(BaseModel):
    """Store detail for the merchant portal."""

    id: int
    store_code: str
    subdomain: str
    name: str
    description: str | None = None
    is_active: bool
    is_verified: bool
    contact_email: str | None = None
    contact_phone: str | None = None
    website: str | None = None
    business_address: str | None = None
    tax_number: str | None = None
    default_language: str | None = None
    created_at: str | None = None
    platforms: list[dict] = Field(default_factory=list)

    model_config = {"from_attributes": True}


class MerchantStoreUpdate(BaseModel):
    """Store update from the merchant portal.
    Only merchant-allowed fields."""

    name: str | None = Field(None, min_length=2, max_length=255)
    description: str | None = None
    contact_email: EmailStr | None = None
    contact_phone: str | None = None
    website: str | None = None
    business_address: str | None = None
    tax_number: str | None = None
