from typing import Optional, List
from datetime import datetime
from pydantic import BaseModel, EmailStr, Field, validator
from app.schemas.user_address import AddressResponse

# Base schema for user registration
class UserBase(BaseModel):
    """Base user schema with required fields for registration"""
    email: EmailStr
    first_name: str = Field(..., min_length=2, max_length=50)
    last_name: str = Field(..., min_length=2, max_length=50)
    phone_code: str = Field(..., pattern=r'^\+?[0-9]{1,4}$')
    phone: str = Field(..., pattern=r'^[0-9]{10,15}$')

# Schema for creating a new user with additional information
class UserCreate(UserBase):
    """Schema for user creation with additional fields"""
    password: str = Field(..., min_length=6)
    country_code: str = Field(..., min_length=2, max_length=2)
    gender: str = Field(..., pattern=r'^[MF]$')  # M for Male, F for Female
    birth_date: str = Field(..., pattern=r'^\d{4}-\d{2}-\d{2}$')
    reference_code_used: Optional[str] = Field(None, min_length=6, max_length=6)
    profile_image: Optional[str] = None

    @validator("reference_code_used", pre=True, always=True)
    def set_reference_code_used_nullable(cls, v):
        if isinstance(v, str) and v.strip() == "":
            return None
        return v

# Schema for updating user information with optional fields
class UserUpdate(BaseModel):
    """Schema for updating user information with all fields optional"""
    full_name: Optional[str] = Field(None, pattern=r'^[a-zA-Z]+\s+[a-zA-Z]+$')
    email: Optional[EmailStr] = None
    phone: Optional[str] = Field(None, pattern=r'^[0-9]{10,15}$')
    daily_step_goal: Optional[int] = Field(None, ge=5000, le=100000)
    profile_image: Optional[str] = None
    # gender: Optional[str] = Field(None, pattern=r'^[MF]$')  # Allow updating gender optionally
    # birth_date: Optional[str] = Field(None, pattern=r'^\d{4}-\d{2}-\d{2}$')  # Allow updating birth_date optionally

    @validator('full_name')
    def split_full_name(cls, v):
        if v:
            names = v.split()
            if len(names) != 2:
                raise ValueError('Full name must contain exactly first name and last name')
        return v

# Base schema representing user data as stored in the database
class UserInDBBase(BaseModel):
    """Base schema for user data as stored in the database"""
    id: int
    email: str
    first_name: str
    last_name: str
    phone_code: str
    phone: str
    gender: str  # Reflects the gender column
    birth_date: str  # Birth date in YYYY-MM-DD format
    daily_step_goal: int = 10000
    profile_image: str = "profile/default_avatar.png"
    background_image: Optional[str] = None
    total_points: int = 0
    reference_code: str
    reference_code_used: Optional[str] = None
    health_sync_status: bool = False
    last_login: Optional[datetime] = None
    status: int = 1
    country_code: str
    created_at: datetime
    updated_at: datetime
    addresses: List[AddressResponse] = []
    step_notification_frequency: int = 3
    last_step_notification_time: Optional[datetime] = None
    step_notifications_sent_today: int = 0

    class Config:
        from_attributes = True

# Public user schema for API responses
class User(UserInDBBase):
    """Public user schema for API responses"""
    pass

# Added new model for referral code validation
class UserReferralCode(BaseModel):
    id: int
    reference_code: str