"""
Subscription and User models for the monetization system
"""

from pydantic import BaseModel, EmailStr, Field, field_validator
from typing import Optional, List, Dict, Any
from datetime import datetime, timezone
from enum import Enum
import re


class PlanType(str, Enum):
    FREE = "free"
    STARTER = "starter"
    PRO = "pro"
    BUSINESS = "business"
    ENTERPRISE = "enterprise"


class SubscriptionStatus(str, Enum):
    ACTIVE = "active"
    CANCELED = "canceled"
    PAST_DUE = "past_due"
    TRIALING = "trialing"
    PAUSED = "paused"


import os

# Plan definitions — Pricing reviewed March 2026
# NOTE: Stripe price IDs must be set via env vars in production.
# Create products/prices in Stripe Dashboard: https://dashboard.stripe.com/products
#
# Official LLM ranges (via OpenRouter — September 2026). The model used per
# translation is resolved from the plan's AI tier (admin settings > plan default):
#   Essentielle (Pro plan)    : deepseek/deepseek-v4-flash, z-ai/glm-5.3-flash,
#                               minimax/minimax-m3
#   Premium     (Business)    : anthropic/claude-sonnet-5 (default),
#                               alternatives deepseek/deepseek-v4-pro, z-ai/glm-5.3
# A Pro user must never trigger a Premium model (see translate_routes).
DEFAULT_AI_MODELS_ESSENTIAL = [
    "deepseek/deepseek-v4-flash",
    "z-ai/glm-5.3-flash",
    "minimax/minimax-m3",
]
DEFAULT_AI_MODELS_PREMIUM = [
    "anthropic/claude-sonnet-5",
    "deepseek/deepseek-v4-pro",
    "z-ai/glm-5.3",
]

PLANS = {
    PlanType.FREE: {
        "name": "Free",
        "price_monthly": 0,
        "price_yearly": 0,
        "docs_per_month": 2,
        "max_pages_per_doc": 10,
        "max_file_size_mb": 5,
        "max_chars_per_month": 20_000,
        "providers": ["google"],
        "features": [
            "pricing.plans.free.feat1",
            "pricing.plans.free.feat2",
            "pricing.plans.free.feat3",
            "pricing.plans.free.feat4",
            "pricing.plans.free.feat5",
        ],
        "ai_translation": False,
        "api_access": False,
        "priority_processing": False,
        "watermark": True,
        "stripe_price_id_monthly": None,
        "stripe_price_id_yearly": None,
        "highlight": None,
        "description": "pricing.plans.free.description",
        "badge": None,
    },
    PlanType.STARTER: {
        "name": "Starter",
        "price_monthly": 9.00,
        "price_yearly": 86.40,   # -20 %
        "docs_per_month": 50,
        "max_pages_per_doc": 50,
        "max_file_size_mb": 10,
        "max_chars_per_month": 500_000,
        "providers": ["google"],
        "features": [
            "pricing.plans.starter.feat1",
            "pricing.plans.starter.feat2",
            "pricing.plans.starter.feat3",
            "pricing.plans.starter.feat4",
            "pricing.plans.starter.feat5",
            "pricing.plans.starter.feat6",
        ],
        "ai_translation": False,
        "api_access": False,
        "priority_processing": False,
        "stripe_price_id_monthly": os.getenv("STRIPE_PRICE_STARTER_MONTHLY", ""),
        "stripe_price_id_yearly": os.getenv("STRIPE_PRICE_STARTER_YEARLY", ""),
        "highlight": None,
        "description": "pricing.plans.starter.description",
        "badge": None,
    },
    PlanType.PRO: {
        "name": "Pro",
        "price_monthly": 19.00,
        "price_yearly": 182.40,  # -20 %
        "docs_per_month": 200,
        "max_pages_per_doc": 200,
        "max_file_size_mb": 25,
        "max_chars_per_month": 2_000_000,
        "providers": ["google", "google_cloud", "openrouter"],
        "ai_models_essential": list(DEFAULT_AI_MODELS_ESSENTIAL),
        "features": [
            "pricing.plans.pro.feat1",
            "pricing.plans.pro.feat2",
            "pricing.plans.pro.feat3",
            "pricing.plans.pro.feat4",
            "pricing.plans.pro.feat5",
            "pricing.plans.pro.feat6",
            "pricing.plans.pro.feat7",
            "pricing.plans.pro.feat8",
        ],
        "ai_translation": True,
        "ai_tier": "essential",
        "api_access": False,
        "priority_processing": True,
        "stripe_price_id_monthly": os.getenv("STRIPE_PRICE_PRO_MONTHLY", ""),
        "stripe_price_id_yearly": os.getenv("STRIPE_PRICE_PRO_YEARLY", ""),
        "highlight": "pricing.plans.pro.highlight",
        "description": "pricing.plans.pro.description",
        "badge": "POPULAR",
    },
    PlanType.BUSINESS: {
        "name": "Business",
        "price_monthly": 49.00,
        "price_yearly": 470.40,  # -20 %
        "docs_per_month": 1000,
        "max_pages_per_doc": 500,
        "max_file_size_mb": 50,
        "max_chars_per_month": 10_000_000,
        "providers": ["google", "google_cloud", "openrouter", "openrouter_premium", "openai", "zai"],
        "ai_models_essential": list(DEFAULT_AI_MODELS_ESSENTIAL),
        "ai_models_premium": list(DEFAULT_AI_MODELS_PREMIUM),
        "features": [
            "pricing.plans.business.feat1",
            "pricing.plans.business.feat2",
            "pricing.plans.business.feat3",
            "pricing.plans.business.feat4",
            "pricing.plans.business.feat5",
            "pricing.plans.business.feat6",
            "pricing.plans.business.feat7",
            "pricing.plans.business.feat8",
            "pricing.plans.business.feat9",
            "pricing.plans.business.feat10",
        ],
        "ai_translation": True,
        "ai_tier": "premium",
        "api_access": True,
        "api_calls_per_month": 10_000,
        "priority_processing": True,
        "team_seats": 5,
        "stripe_price_id_monthly": os.getenv("STRIPE_PRICE_BUSINESS_MONTHLY", ""),
        "stripe_price_id_yearly": os.getenv("STRIPE_PRICE_BUSINESS_YEARLY", ""),
        "highlight": None,
        "description": "pricing.plans.business.description",
        "badge": None,
    },
    PlanType.ENTERPRISE: {
        "name": "Enterprise",
        "price_monthly": -1,
        "price_yearly": -1,
        "docs_per_month": -1,
        "max_pages_per_doc": -1,
        "max_file_size_mb": -1,
        "max_chars_per_month": -1,
        "providers": ["google", "google_cloud", "openrouter", "openrouter_premium", "openai", "zai", "custom"],
        "features": [
            "pricing.plans.enterprise.feat1",
            "pricing.plans.enterprise.feat2",
            "pricing.plans.enterprise.feat3",
            "pricing.plans.enterprise.feat4",
            "pricing.plans.enterprise.feat5",
            "pricing.plans.enterprise.feat6",
            "pricing.plans.enterprise.feat7",
            "pricing.plans.enterprise.feat8",
        ],
        "ai_translation": True,
        "ai_tier": "custom",
        "api_access": True,
        "api_calls_per_month": -1,
        "priority_processing": True,
        "team_seats": -1,
        "stripe_price_id_monthly": None,
        "stripe_price_id_yearly": None,
        "highlight": None,
        "description": "pricing.plans.enterprise.description",
        "badge": "ON REQUEST",
    },
}


def _utc_now() -> datetime:
    """Return current UTC datetime."""
    return datetime.now(timezone.utc)


class User(BaseModel):
    id: str
    email: EmailStr
    name: str
    password_hash: str
    created_at: datetime = Field(default_factory=_utc_now)
    updated_at: datetime = Field(default_factory=_utc_now)
    email_verified: bool = False
    avatar_url: Optional[str] = None

    # Subscription info
    plan: PlanType = PlanType.FREE
    tier: str = "free"  # binary-ish tier for JWT/auth: free for free/starter, pro for paid
    subscription_status: SubscriptionStatus = SubscriptionStatus.ACTIVE
    stripe_customer_id: Optional[str] = None
    stripe_subscription_id: Optional[str] = None
    subscription_ends_at: Optional[datetime] = None
    cancel_at_period_end: bool = False

    # Usage tracking
    docs_translated_this_month: int = 0
    pages_translated_this_month: int = 0
    api_calls_this_month: int = 0
    daily_translation_count: int = (
        0  # Daily count (reset at midnight UTC; synced with tier quota)
    )
    usage_reset_date: datetime = Field(default_factory=_utc_now)

    # Extra credits (purchased separately)
    extra_credits: int = 0  # Each credit = 1 page

    # Settings
    default_source_lang: str = "auto"
    default_target_lang: str = "en"
    default_provider: str = "google"



class UserCreate(BaseModel):
    email: EmailStr
    name: str = Field(..., min_length=1, max_length=100)
    password: str = Field(..., min_length=8)

    @field_validator("password")
    @classmethod
    def validate_password_strength(cls, v: str) -> str:
        """Validate password meets minimum security requirements."""
        if len(v) < 8:
            raise ValueError("Password must be at least 8 characters")
        if not re.search(r"[A-Z]", v):
            raise ValueError("Le mot de passe doit contenir au moins une majuscule")
        if not re.search(r"[a-z]", v):
            raise ValueError("Le mot de passe doit contenir au moins une minuscule")
        if not re.search(r"[0-9]", v):
            raise ValueError("Le mot de passe doit contenir au moins un chiffre")
        return v


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


class UserResponse(BaseModel):
    id: str
    email: EmailStr
    name: str
    avatar_url: Optional[str] = None
    plan: PlanType
    tier: PlanType
    subscription_status: SubscriptionStatus
    subscription_ends_at: Optional[datetime] = None
    cancel_at_period_end: bool = False
    docs_translated_this_month: int
    pages_translated_this_month: int
    api_calls_this_month: int
    extra_credits: int
    created_at: datetime

    plan_limits: Dict[str, Any] = {}


class Subscription(BaseModel):
    id: str
    user_id: str
    plan: PlanType
    status: SubscriptionStatus
    stripe_subscription_id: Optional[str] = None
    stripe_customer_id: Optional[str] = None
    current_period_start: datetime
    current_period_end: datetime
    cancel_at_period_end: bool = False
    created_at: datetime = Field(default_factory=_utc_now)


class UsageRecord(BaseModel):
    id: str
    user_id: str
    document_name: str
    document_type: str  # excel, word, pptx
    pages_count: int
    source_lang: str
    target_lang: str
    provider: str
    processing_time_seconds: float
    credits_used: int
    created_at: datetime = Field(default_factory=_utc_now)


class CreditPurchase(BaseModel):
    """For buying extra credits (pay-per-use)"""

    id: str
    user_id: str
    credits_amount: int
    price_paid: float  # in cents
    stripe_payment_id: str
    created_at: datetime = Field(default_factory=_utc_now)


# Credit packages for purchase
CREDIT_PACKAGES = [
    {
        "credits": 50,
        "price": 5.00,
        "price_per_credit": 0.10,
        "stripe_price_id": "price_credits_50",
    },
    {
        "credits": 100,
        "price": 9.00,
        "price_per_credit": 0.09,
        "stripe_price_id": "price_credits_100",
        "popular": True,
    },
    {
        "credits": 250,
        "price": 20.00,
        "price_per_credit": 0.08,
        "stripe_price_id": "price_credits_250",
    },
    {
        "credits": 500,
        "price": 35.00,
        "price_per_credit": 0.07,
        "stripe_price_id": "price_credits_500",
    },
    {
        "credits": 1000,
        "price": 60.00,
        "price_per_credit": 0.06,
        "stripe_price_id": "price_credits_1000",
    },
]
