"""
Pydantic schemas for Quote models.

Request and response schemas for the MSP Quote Wizard including
public and admin-facing operations.
"""

from datetime import datetime
from decimal import Decimal
from typing import Optional
from uuid import UUID

from pydantic import BaseModel, Field, EmailStr, field_validator

from api.models.quote import (
    QuoteStatus,
    ServiceCategory,
    BillingFrequency,
    NotificationType,
)


# ============================================================================
# Quote Item Schemas
# ============================================================================

class QuoteItemBase(BaseModel):
    """Base schema with shared QuoteItem fields."""

    category: ServiceCategory = Field(..., description="Service category")
    product_code: str = Field(..., description="Product code identifier", min_length=1, max_length=50)
    product_name: str = Field(..., description="Name of the product/service", min_length=1, max_length=255)
    description: Optional[str] = Field(None, description="Detailed description of the product/service")
    quantity: int = Field(1, description="Number of units", ge=1)
    unit_price: Decimal = Field(..., description="Price per unit", ge=0)
    setup_price: Decimal = Field(Decimal("0.00"), description="One-time setup price", ge=0)
    billing_frequency: BillingFrequency = Field(
        BillingFrequency.MONTHLY,
        description="Billing frequency"
    )
    tier: Optional[str] = Field(None, description="Pricing tier", max_length=50)
    is_recommended: bool = Field(False, description="Whether this item is recommended")


class QuoteItemCreate(QuoteItemBase):
    """Schema for creating a new QuoteItem."""
    pass


class QuoteItemUpdate(BaseModel):
    """Schema for updating an existing QuoteItem. All fields optional."""

    category: Optional[ServiceCategory] = None
    product_code: Optional[str] = Field(None, min_length=1, max_length=50)
    product_name: Optional[str] = Field(None, min_length=1, max_length=255)
    description: Optional[str] = None
    quantity: Optional[int] = Field(None, ge=1)
    unit_price: Optional[Decimal] = Field(None, ge=0)
    setup_price: Optional[Decimal] = Field(None, ge=0)
    billing_frequency: Optional[BillingFrequency] = None
    tier: Optional[str] = Field(None, max_length=50)
    is_recommended: Optional[bool] = None


class QuoteItemResponse(QuoteItemBase):
    """Schema for QuoteItem responses with ID and computed fields."""

    id: UUID = Field(..., description="Unique identifier for the quote item")
    quote_id: UUID = Field(..., description="Reference to the parent quote")
    line_total: Decimal = Field(..., description="Calculated line total (unit_price * quantity)")
    monthly_amount: Decimal = Field(..., description="Calculated monthly amount")
    created_at: datetime = Field(..., description="Timestamp when item was created")

    model_config = {"from_attributes": True}


# ============================================================================
# Quote Schemas
# ============================================================================

class QuoteBase(BaseModel):
    """Base schema with shared Quote fields."""

    company_name: Optional[str] = Field(None, description="Prospect company name", max_length=255)
    contact_name: Optional[str] = Field(None, description="Primary contact name", max_length=255)
    contact_email: Optional[EmailStr] = Field(None, description="Contact email address")
    contact_phone: Optional[str] = Field(None, description="Contact phone number", max_length=50)
    employee_count: Optional[int] = Field(None, description="Number of employees/users", ge=1)


class QuoteCreate(BaseModel):
    """Schema for creating a new Quote draft."""

    employee_count: Optional[int] = Field(None, description="Number of employees/users", ge=1)
    # Items can optionally be provided at creation
    items: Optional[list[QuoteItemCreate]] = Field(None, description="Initial quote items")


class QuoteUpdate(BaseModel):
    """Schema for updating a Quote during wizard flow."""

    company_name: Optional[str] = Field(None, max_length=255)
    contact_name: Optional[str] = Field(None, max_length=255)
    contact_email: Optional[EmailStr] = None
    contact_phone: Optional[str] = Field(None, max_length=50)
    employee_count: Optional[int] = Field(None, ge=1)
    # Items to add/update
    items: Optional[list[QuoteItemCreate]] = Field(None, description="Items to set (replaces existing)")


class QuoteSubmit(BaseModel):
    """Schema for final quote submission with required contact info."""

    company_name: str = Field(..., description="Company name (required for submission)", min_length=1, max_length=255)
    contact_name: str = Field(..., description="Contact name (required for submission)", min_length=1, max_length=255)
    contact_email: EmailStr = Field(..., description="Email address (required for submission)")
    contact_phone: Optional[str] = Field(None, description="Phone number", max_length=50)
    notes: Optional[str] = Field(None, description="Additional notes from the prospect", max_length=2000)

    @field_validator("company_name", "contact_name")
    @classmethod
    def strip_whitespace(cls, v: str) -> str:
        """Strip whitespace from string fields."""
        return v.strip() if v else v


class QuoteResponse(QuoteBase):
    """Schema for public Quote responses with items."""

    id: UUID = Field(..., description="Unique identifier for the quote")
    access_token: str = Field(..., description="Access token for public URL")
    status: QuoteStatus = Field(..., description="Current quote status")
    monthly_total: Decimal = Field(..., description="Calculated monthly recurring total")
    setup_total: Decimal = Field(..., description="Calculated one-time setup total")
    expires_at: Optional[datetime] = Field(None, description="Quote expiration date")
    submitted_at: Optional[datetime] = Field(None, description="When quote was submitted")
    created_at: datetime = Field(..., description="Timestamp when quote was created")
    updated_at: datetime = Field(..., description="Timestamp when quote was last updated")
    items: list[QuoteItemResponse] = Field(default_factory=list, description="Quote line items")

    model_config = {"from_attributes": True}


class QuoteCreatedResponse(BaseModel):
    """Schema for quote creation response with access URL info."""

    id: UUID = Field(..., description="Unique identifier for the quote")
    access_token: str = Field(..., description="Access token for public URL")
    status: QuoteStatus = Field(..., description="Current quote status")
    message: str = Field(..., description="Success message")

    model_config = {"from_attributes": True}


# ============================================================================
# Quote Activity Schemas
# ============================================================================

class QuoteActivityResponse(BaseModel):
    """Schema for QuoteActivity responses."""

    id: UUID = Field(..., description="Unique identifier for the activity")
    quote_id: UUID = Field(..., description="Reference to the parent quote")
    action: str = Field(..., description="Action performed")
    step_name: Optional[str] = Field(None, description="Wizard step name")
    details: Optional[str] = Field(None, description="Additional details")
    ip_address: Optional[str] = Field(None, description="IP address of the actor")
    created_at: datetime = Field(..., description="Timestamp of the action")

    model_config = {"from_attributes": True}


# ============================================================================
# Quote Notification Schemas
# ============================================================================

class QuoteNotificationResponse(BaseModel):
    """Schema for QuoteNotification responses."""

    id: UUID = Field(..., description="Unique identifier for the notification")
    quote_id: UUID = Field(..., description="Reference to the parent quote")
    notification_type: NotificationType = Field(..., description="Type of notification")
    recipient: str = Field(..., description="Notification recipient")
    subject: Optional[str] = Field(None, description="Notification subject")
    status: str = Field(..., description="Delivery status")
    attempts: int = Field(0, description="Number of delivery attempts")
    last_attempt_at: Optional[datetime] = Field(None, description="Last delivery attempt timestamp")
    sent_at: Optional[datetime] = Field(None, description="When notification was sent")
    error_message: Optional[str] = Field(None, description="Error message if failed")
    created_at: datetime = Field(..., description="Timestamp when created")

    model_config = {"from_attributes": True}


# ============================================================================
# Admin Schemas
# ============================================================================

class QuoteAdminUpdate(BaseModel):
    """Schema for admin updates to a quote."""

    status: Optional[QuoteStatus] = Field(None, description="New status")
    expires_at: Optional[datetime] = Field(None, description="Quote expiration date")


class QuoteAdminResponse(QuoteResponse):
    """Schema for admin Quote responses with additional fields."""

    ip_address: Optional[str] = Field(None, description="IP address of the requester")
    user_agent: Optional[str] = Field(None, description="Browser user agent")
    activities: list[QuoteActivityResponse] = Field(
        default_factory=list,
        description="Activity log for this quote"
    )
    notifications: list[QuoteNotificationResponse] = Field(
        default_factory=list,
        description="Notifications sent for this quote"
    )

    model_config = {"from_attributes": True}


# ============================================================================
# List and Stats Schemas
# ============================================================================

class QuoteListItem(BaseModel):
    """Schema for quote list items (summary view)."""

    id: UUID = Field(..., description="Unique identifier")
    access_token: str = Field(..., description="Access token")
    status: QuoteStatus = Field(..., description="Current status")
    company_name: Optional[str] = Field(None, description="Company name")
    contact_name: Optional[str] = Field(None, description="Contact name")
    contact_email: Optional[str] = Field(None, description="Contact email")
    employee_count: Optional[int] = Field(None, description="Employee count")
    monthly_total: Decimal = Field(..., description="Monthly total")
    setup_total: Decimal = Field(..., description="Setup total")
    item_count: int = Field(..., description="Number of line items")
    submitted_at: Optional[datetime] = Field(None, description="Submission timestamp")
    created_at: datetime = Field(..., description="Creation timestamp")

    model_config = {"from_attributes": True}


class QuoteListResponse(BaseModel):
    """Schema for paginated quote list responses."""

    total: int = Field(..., description="Total number of quotes matching filters")
    skip: int = Field(..., description="Number of records skipped")
    limit: int = Field(..., description="Maximum number of records returned")
    quotes: list[QuoteListItem] = Field(..., description="List of quotes")


class QuoteStatsResponse(BaseModel):
    """Schema for admin dashboard statistics."""

    total_quotes: int = Field(..., description="Total number of quotes")
    quotes_by_status: dict[str, int] = Field(..., description="Quote count by status")
    total_monthly_value: Decimal = Field(..., description="Total monthly value of all submitted quotes")
    total_setup_value: Decimal = Field(..., description="Total setup value of all submitted quotes")
    quotes_this_month: int = Field(..., description="Quotes created this month")
    quotes_submitted_this_month: int = Field(..., description="Quotes submitted this month")
    average_monthly_value: Decimal = Field(..., description="Average monthly value per submitted quote")
    conversion_rate: Decimal = Field(..., description="Percentage of drafts that get submitted")
