from pydantic import BaseModel, Field, HttpUrl, field_validator
from typing import Optional, Literal
from datetime import date


class PlanOverview(BaseModel):
    plan_name: str = Field(..., description="Name of the subscription plan, e.g., 'Pro Plan'")
    plan_id: str = Field(..., description="Internal identifier for the plan, e.g., 'plan_ABC123'")
    plan_description: Optional[str] = Field(None, description="Optional description of the plan")
    start_date: date = Field(..., description="Start date of the subscription period")
    end_date: date = Field(..., description="End date of the subscription period")
    is_active: bool = Field(..., description="Flag indicating if the plan is currently active")


class UsageLimits(BaseModel):
    max_users: int = Field(..., description="Maximum number of users allowed")
    max_devices: int = Field(..., description="Maximum number of devices allowed")
    max_geofences: int = Field(..., description="Maximum number of geofences allowed")
    max_tasks_per_day: int = Field(..., description="Maximum number of tasks allowed per day")


class RenewalPreferences(BaseModel):
    auto_renewal: bool = Field(..., description="Whether the subscription auto-renews")
    renewal_cycle: Literal['monthly', 'yearly', 'quarterly'] = Field(..., description="Cycle of renewal")
    reminder_days: int = Field(..., description="Days before expiry to send renewal reminder")


class InvoiceInfo(BaseModel):
    last_invoice_id: Optional[str] = Field(None, description="ID of the last invoice")
    last_invoice_date: Optional[date] = Field(None, description="Date of the last invoice")
    next_invoice_date: Optional[date] = Field(None, description="Expected date for next invoice")
    download_invoice_url: Optional[HttpUrl] = Field(None, description="URL to download the last invoice")

    @field_validator("last_invoice_date", "next_invoice_date", mode="before")
    def validate_optional_date(cls, v):
        return v or None

    @field_validator("download_invoice_url", mode="before")
    def validate_optional_url(cls, v):
        return v or None


class PaymentMode(BaseModel):
    payment_mode: str = Field(..., description="Mode of payment")
    stripe_customer_id: Optional[str] = Field(None)
    bank_account_name: Optional[str] = Field(None)
    bank_iban: Optional[str] = Field(None)
    bank_name: Optional[str] = Field(None)

    @field_validator("payment_mode")
    def validate_payment_mode(cls, value):
        if value == "bank":
            return "bank_transfer"
        if value not in ("stripe", "bank_transfer"):
            raise ValueError("payment_mode must be 'stripe' or 'bank_transfer'")
        return value


class SubscriptionSettings(BaseModel):
    plan_overview: PlanOverview = Field(..., description="Details about the subscription plan")
    usage_limits: UsageLimits = Field(..., description="Limits related to resource usage")
    renewal_preferences: RenewalPreferences = Field(..., description="Settings for auto-renewal")
    invoice_info: InvoiceInfo = Field(..., description="Invoice-related information")
    payment: PaymentMode = Field(..., description="Payment method details")
