# services/auth/app/schemas/auth.py - UPDATED WITH UNIFIED TOKEN RESPONSE
"""
Authentication schemas - Updated with unified token response format
Following industry best practices from Firebase, Cognito, etc.
"""

from pydantic import BaseModel, EmailStr, Field
from typing import Optional, Dict, Any
from datetime import datetime

# ================================================================
# REQUEST SCHEMAS
# ================================================================

class UserRegistration(BaseModel):
    """User registration request"""
    email: EmailStr
    password: str = Field(..., min_length=8, max_length=128)
    full_name: str = Field(..., min_length=1, max_length=255)
    tenant_name: Optional[str] = Field(None, max_length=255)
    role: Optional[str] = Field("admin", pattern=r'^(user|admin|manager|super_admin)$')
    subscription_plan: Optional[str] = Field("starter", description="Selected subscription plan (starter, professional, enterprise)")
    billing_cycle: Optional[str] = Field("monthly", description="Billing cycle (monthly, yearly)")
    coupon_code: Optional[str] = Field(None, description="Discount coupon code")
    payment_method_id: Optional[str] = Field(None, description="Stripe payment method ID")
    # GDPR Consent fields
    terms_accepted: Optional[bool] = Field(True, description="Accept terms of service")
    privacy_accepted: Optional[bool] = Field(True, description="Accept privacy policy")
    marketing_consent: Optional[bool] = Field(False, description="Consent to marketing communications")
    analytics_consent: Optional[bool] = Field(False, description="Consent to analytics cookies")

class UserLogin(BaseModel):
    """User login request"""
    email: EmailStr
    password: str

class RefreshTokenRequest(BaseModel):
    """Refresh token request"""
    refresh_token: str

class PasswordChange(BaseModel):
    """Password change request"""
    current_password: str
    new_password: str = Field(..., min_length=8, max_length=128)

class PasswordReset(BaseModel):
    """Password reset request"""
    email: EmailStr

class PasswordResetConfirm(BaseModel):
    """Password reset confirmation"""
    token: str
    new_password: str = Field(..., min_length=8, max_length=128)

# ================================================================
# RESPONSE SCHEMAS
# ================================================================

class UserData(BaseModel):
    """User data embedded in token responses"""
    id: str
    email: str
    full_name: str
    is_active: bool
    is_verified: bool
    created_at: str  # ISO format datetime string
    tenant_id: Optional[str] = None
    role: Optional[str] = "admin"

class TokenResponse(BaseModel):
    """
    Unified token response for both registration and login
    Follows industry standards (Firebase, AWS Cognito, etc.)
    """
    access_token: str
    refresh_token: Optional[str] = None
    token_type: str = "bearer"
    expires_in: int = 3600  # seconds
    user: Optional[UserData] = None
    subscription_id: Optional[str] = Field(None, description="Subscription ID if created during registration")
    # Payment action fields (3DS, SetupIntent, etc.)
    requires_action: Optional[bool] = Field(None, description="Whether payment action is required (3DS, SetupIntent confirmation)")
    action_type: Optional[str] = Field(None, description="Type of action required (setup_intent_confirmation, payment_intent_confirmation)")
    client_secret: Optional[str] = Field(None, description="Client secret for payment confirmation")
    payment_intent_id: Optional[str] = Field(None, description="Payment intent ID for 3DS authentication")
    setup_intent_id: Optional[str] = Field(None, description="SetupIntent ID for payment method verification")
    customer_id: Optional[str] = Field(None, description="Stripe customer ID")
    # Additional fields for post-confirmation subscription completion
    plan_id: Optional[str] = Field(None, description="Subscription plan ID")
    payment_method_id: Optional[str] = Field(None, description="Payment method ID")
    trial_period_days: Optional[int] = Field(None, description="Trial period in days")
    user_id: Optional[str] = Field(None, description="User ID for post-confirmation processing")
    billing_interval: Optional[str] = Field(None, description="Billing interval (monthly, yearly)")
    message: Optional[str] = Field(None, description="Additional message about payment action required")

    class Config:
        schema_extra = {
            "example": {
                "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
                "refresh_token": "def502004b8b7f8f...",
                "token_type": "bearer",
                "expires_in": 3600,
                "user": {
                    "id": "123e4567-e89b-12d3-a456-426614174000",
                    "email": "user@example.com",
                    "full_name": "John Doe",
                    "is_active": True,
                    "is_verified": False,
                    "created_at": "2025-07-22T10:00:00Z",
                    "role": "user"
                },
                "subscription_id": "sub_1234567890",
                "requires_action": True,
                "action_type": "setup_intent_confirmation",
                "client_secret": "seti_1234_secret_5678",
                "payment_intent_id": None,
                "setup_intent_id": "seti_1234567890",
                "customer_id": "cus_1234567890"
            }
        }

class UserResponse(BaseModel):
    """User response for user management endpoints - FIXED"""
    id: str
    email: str
    full_name: str
    is_active: bool
    is_verified: bool
    created_at: datetime  # ✅ Changed from str to datetime
    last_login: Optional[datetime] = None  # ✅ Added missing field
    phone: Optional[str] = None  # ✅ Added missing field  
    language: Optional[str] = None  # ✅ Added missing field
    timezone: Optional[str] = None  # ✅ Added missing field
    tenant_id: Optional[str] = None
    role: Optional[str] = "admin"
    payment_customer_id: Optional[str] = None  # ✅ Added payment integration field
    default_payment_method_id: Optional[str] = None  # ✅ Added payment integration field

    class Config:
        from_attributes = True  # ✅ Enable ORM mode for SQLAlchemy objects




class TokenVerification(BaseModel):
    """Token verification response"""
    valid: bool
    user_id: Optional[str] = None
    email: Optional[str] = None
    exp: Optional[int] = None
    message: Optional[str] = None

class PasswordResetResponse(BaseModel):
    """Password reset response"""
    message: str
    reset_token: Optional[str] = None

class LogoutResponse(BaseModel):
    """Logout response"""
    message: str
    success: bool = True

# ================================================================
# ERROR SCHEMAS
# ================================================================

class ErrorDetail(BaseModel):
    """Error detail for API responses"""
    message: str
    code: Optional[str] = None
    field: Optional[str] = None

class ErrorResponse(BaseModel):
    """Standardized error response"""
    success: bool = False
    error: ErrorDetail
    timestamp: str

    class Config:
        schema_extra = {
            "example": {
                "success": False,
                "error": {
                    "message": "Invalid credentials",
                    "code": "AUTH_001"
                },
                "timestamp": "2025-07-22T10:00:00Z"
            }
        }

# ================================================================
# VALIDATION SCHEMAS
# ================================================================

class EmailVerificationRequest(BaseModel):
    """Email verification request"""
    email: EmailStr

class EmailVerificationConfirm(BaseModel):
    """Email verification confirmation"""
    token: str

class ProfileUpdate(BaseModel):
    """Profile update request"""
    full_name: Optional[str] = Field(None, min_length=1, max_length=255)
    email: Optional[EmailStr] = None

# ================================================================
# INTERNAL SCHEMAS (for service communication)
# ================================================================

class UserContext(BaseModel):
    """User context for internal service communication"""
    user_id: str
    email: str
    tenant_id: Optional[str] = None
    roles: list[str] = ["admin"]
    is_verified: bool = False
    
class TokenClaims(BaseModel):
    """JWT token claims structure"""
    sub: str  # subject (user_id)
    email: str
    full_name: str
    user_id: str
    is_verified: bool
    tenant_id: Optional[str] = None
    iat: int  # issued at
    exp: int  # expires at
    iss: str = "bakery-auth"  # issuer