from datetime import datetime
from typing import Literal, Optional
from fastapi import HTTPException
from pydantic import Field
from sqlalchemy import (INTEGER,VARCHAR, DateTime, Enum, Double)
from sqlalchemy.orm import (Mapped,Session,mapped_column, relationship)
from app.models.main import Base
from app.utils.schemas_utils import CustomModel

class UserBase(CustomModel):
    __tablename__ = "tbl_user"

    user_id: int | None = Field(default=None)  
    first_name: str | None = Field(default=None)
    last_name: str | None = Field(default=None)
    email_id: str | None = Field(default=None)
    password: str | None = Field(default=None)
    mobile_number : str | None = Field(default=None)
    role: Literal["superadmin", "admin"] = Field(default="admin")
    
class UserFilter(CustomModel):
    user_id: int | None = Field(default=None) 
    email_id: str | None = Field(default=None) 

class TblUser(Base):
    __tablename__ = "tbl_user"

    user_id: Mapped[int] = mapped_column("user_id", INTEGER, primary_key=True, autoincrement=True)
    first_name: Mapped[str] = mapped_column("first_name", VARCHAR(255), nullable=True, server_default=None)
    last_name: Mapped[str] = mapped_column("last_name", VARCHAR(255), nullable=True, server_default=None)
    email_id: Mapped[str] = mapped_column("email_id", VARCHAR(255), nullable=True, server_default=None) 
    password: Mapped[str] = mapped_column("password", VARCHAR(255), nullable=True, server_default=None)
    role: Mapped[str] = mapped_column("role", Enum("superadmin", "admin", name="user_roles"), nullable=False, server_default="admin")
    mobile_number : Mapped[str] = mapped_column("mobile_number", VARCHAR(10), nullable=True, server_default=None)
    otp: Mapped[Optional[str]] = mapped_column(VARCHAR(6), nullable=True, server_default=None)
    otp_expiry: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
    
    user_sim_user = relationship("TblUserSimulation", back_populates="user")

    
    @classmethod
    def create(cls, data: UserBase, db: Session) -> "TblUser":
        data_dict = data.model_dump()  
        new_data = cls(**data_dict)  
        db.add(new_data)  
        db.flush()
        return new_data
    
    @classmethod
    def get_usr_id(cls, user_id: int, db: Session) -> "TblUser":  
        get_data = db.query(cls).filter(cls.user_id == user_id).first()
        if not get_data:
            raise HTTPException(status_code=404, detail="User not found") 
        return get_data  

    @classmethod
    def update(cls, user_id: int, data: UserBase, db: Session) -> "TblUser":
        get_data = db.query(cls).filter(cls.user_id == user_id).first() 
        if not get_data:
            raise HTTPException(status_code=404, detail="User not found")  
        data_dict = data.model_dump()  
        for key, value in data_dict.items():
            setattr(get_data, key, value)  
        db.add(get_data)  
        db.flush() 
        return get_data
    
    @classmethod
    def get_by_user_filter(cls, request: dict | UserFilter, db: Session) -> UserBase | None:
        if isinstance(request, dict):
            filter_data = request
        else:
            filter_data = request.model_dump(exclude_none=True)

        get_user_data = db.query(cls).filter_by(**filter_data).first()
        if not get_user_data:
            return None
        return UserBase(**get_user_data.__dict__)

    
