from pydantic import BaseModel, EmailStr, Field, validator
from typing import Any, Optional, List
from fastapi import HTTPException
from datetime import datetime
from pydantic import field_serializer

class Token(BaseModel):
    access_token: str
    token_type: str

class TokenData(BaseModel):
    email: EmailStr


class CoursesResponse(BaseModel):
    course_id: str
    topic: str
    email: str
    status: str
    course_imscc_url: Optional[str] = None
    task_id: Optional[str] = None
    skills: Optional[str] = None
    degree: Optional[str] = None
    allocated_time: Optional[str] = None
    content_description: Optional[str] = None
    content_outcomes: Optional[str] = None
    language: Optional[str] = None
    mode_of_delivery: Optional[str] = None
    tone: Optional[str] = None,
    no_of_modules: Optional[int] = None
    taxonomy: Optional[str] = None
    outline: Optional[str] = None
    learning_approach: Optional[str] = None
    level_of_difficulty: Optional[str] = None
    type_of_assessment: Optional[str] = None
    no_of_questions: Optional[int] = None
    weblinks: Optional[str] = None
    markdown_content: Optional[str] = None
    markdown_url: Optional[str] = None
    created_at: datetime

    class Config:
        from_attributes = True
        json_encoders = {
            datetime: lambda v: v.isoformat()
        }

class CoursesCreate(BaseModel):
    topic: str = Field(..., min_length=5, max_length=100)
    email: Optional[str] = None
    user_id: Optional[str] = None
    skills: Optional[str] = None
    degree: Optional[str] = None
    allocated_time: Optional[str] = None
    language: Optional[str] = None
    mode_of_delivery: Optional[str] = None
    tone: Optional[str] = None
    no_of_modules: Optional[int] = None
    taxonomy: Optional[str] = None
    learning_approach: Optional[str] = None
    outline: Optional[str] = None
    weblinks: Optional[str] = None
    status: str = "pending"

class CoursesUpdate(BaseModel):
    content_description: Optional[str] = None
    content_outcomes: Optional[str] = None
    taxonomy: Optional[str] = None
    level_of_difficulty: Optional[str] = None
    type_of_assessment: Optional[str] = None
    no_of_questions: Optional[int] = None
    no_of_modules: Optional[int] = None
    outline: Optional[str] = None
    learning_approach: Optional[str] = None
    course_step: Optional[int] = 1

class CourseAISchema(BaseModel):
    field_type: str
    taxonomy: Optional[str] = None
    field_value: Optional[str] = None

    @validator('field_type')
    def validate_field_type(cls, v):
        valid_types = [
            "content_description", "content_outcomes", "taxonomy",
        ]
        if v not in valid_types:
            raise HTTPException(
                status_code=400,
                detail=f"Invalid content type. Must be one of {valid_types}."
            )
        return v

class CourseModuleCreate(BaseModel):
    course_id: str
    module_title: str = Field(..., min_length=5, max_length=100)
    module_subtopic: Optional[str] = None
    estimated_time: Optional[str] = None
    assessment: Optional[str] = None
    recommended_resourses: Optional[str] = None
    skills: Optional[str] = None

class RoleBase(BaseModel):
    name: str

class RoleCreate(RoleBase):
    pass

class RoleOut(RoleBase):
    id: int
    class Config:
        from_attributes = True

class UserCreate(BaseModel):
    name: str
    email: EmailStr
    password: str
    role_id: Optional[int] = None
    is_active: bool = True
    is_email_verified: bool = False
    is_phone_verified: bool = False
    phone_number: Optional[str] = None
    profile_picture: Optional[str] = None
    activation_date: Optional[datetime] = None
    educational_degree: Optional[str] = None
    department: Optional[str] = None
    subscription_package: Optional[str] = None
    subscription_start_date: Optional[datetime] = None
    subscription_end_date: Optional[datetime] = None
    subscription_status: Optional[str] = None  # e.g., 'active', 'expired', 'cancelled'
    subscription_renewal_date: Optional[datetime] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

class UserResponse(BaseModel):
    id: int
    name: str
    email: EmailStr
    is_active: bool
    role: RoleOut
    activation_date: datetime | None
    last_login: datetime | None
    is_email_verified: bool = False
    is_phone_verified: bool = False
    phone_number: str = None
    profile_picture: Optional[str] = None
    role_id: Optional[int]
    educational_degree: Optional[str] = None
    department: Optional[str] = None
    subscription_package: Optional[str] = None
    subscription_start_date: Optional[datetime] = None
    subscription_end_date: Optional[datetime] = None
    subscription_status: Optional[str] = None  # e.g., 'active', 'expired', 'cancelled'
    subscription_renewal_date: Optional[datetime] = None
    created_at: datetime
    updated_at: datetime


    class Config:
        from_attributes = True  # Allows Pydantic to work with SQLAlchemy models
        json_encoders = {
            int: lambda v: v.isoformat() if isinstance(v, datetime) else v
        }
        str_strip_whitespace = True  # Strips whitespace from string fields
        
        @field_serializer('activation_date', 'last_login', 'subscription_start_date', 'subscription_end_date', 'subscription_renewal_date', 'created_at', 'updated_at', when_used="json")
        def serialize_datetime(cls, value: datetime):
            return int(value.timestamp()) if value else None

# Base schema (common fields)
class UserCourseLogBase(BaseModel):
    user_id: int
    number_of_course: int

# Schema for creating a log
class UserCourseLogCreate(UserCourseLogBase):
    pass

# Schema for updating a log
class UserCourseLogUpdate(BaseModel):
    number_of_course: int

# Schema for returning log
class UserCourseLogResponse(UserCourseLogBase):
    id: int
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True  # For ORM compatibility
