from datetime import date, datetime
from typing import List, Literal, Optional

from pydantic import BaseModel, EmailStr, field_validator, model_validator


class User(BaseModel):
    email: Optional[EmailStr] = None
    first_name: Optional[str] = None
    last_name: Optional[str] = None
    date_of_birth: Optional[date] = None
    address: Optional[str] = None
    national_code: Optional[str] = None
    about: Optional[str] = None

    @field_validator("date_of_birth", mode="after")
    def convert_dob_to_str(cls, v):
        return str(v) if v else None


class Profile(BaseModel):
    job: Optional[str]
    last_education_degree: Optional[str]
    major: Optional[str]
    father_name: Optional[str]
    first_name_en: Optional[str]
    last_name_en: Optional[str]
    marital_status: Optional[str]
    gender: Optional[str]
    mobile2: Optional[str]
    landline: Optional[str]
    email2: Optional[EmailStr]
    country: Optional[str]
    province: Optional[str]
    city: Optional[str]
    programming_interests: Optional[str]


class WorkExperience(BaseModel):
    programming_languages: Optional[str]
    programming_tools: Optional[str]
    summary: Optional[str]
    programming_level: Optional[str]


class Skill(BaseModel):
    problem_solving: Optional[int]
    technology_familiarity: Optional[int]


class EducationalExperience(BaseModel):
    previous_courses: Optional[str]
    feedback: Optional[str]
    learning_challenges: Optional[str]
    course_selection_criteria: Optional[str]


class Goal(BaseModel):
    course_discovery_method: Optional[str]
    course_participation_goal: Optional[str]
    daily_study_hours: Optional[str]
    preferred_device: Optional[str]
    preferred_learning_format: Optional[str]


class Suggestion(BaseModel):
    questions_or_notes: Optional[str]
    vip_interest: Optional[bool]
    future_course_suggestions: Optional[str]


class SocialMedia(BaseModel):
    active_social_media: Optional[str]
    notification_preference: Optional[str]
    online_profile: Optional[str]


class Transaction(BaseModel):
    title: str
    pay_amount: int
    credit_amount: int
    transaction_type: Literal["add", "spend", "gift"]
    status: Literal["success", "failed"]
    created_at: datetime


class Wallet(BaseModel):
    uuid_id: str
    owner_id: str
    inventory: int
    transactions: List[Transaction]

    @model_validator(mode="before")
    def fill_owner_id(cls, values):
        # if owner_id not provided directly, look for owner_identifier in input
        if values.get("owner_identifier"):
            values["owner_id"] = values["owner_identifier"]
        return values


class WalletPackage(BaseModel):
    pay_amount: int
    credit_amount: int
    gift_percentage: int


class WalletPackages(WalletPackage):
    name: str
