""" User models """
import uuid

from sqlmodel import Field, Relationship
from .base import SQLModel
from pydantic import EmailStr
from typing import Annotated, Optional
from enum import Enum

class RoleEnum(str, Enum):
    CLIENT_PARTICULAR = "client_particular"
    CLIENT_BUSINESS = "client_business"
    VENDOR_BUSINESS = "vendor_business"
    VENDOR_PARTICULAR = "vendor_particular"

# Shared properties
class UserBase(SQLModel):
    email: Annotated[str, EmailStr] = Field(unique=True, index=True, max_length=255)
    full_name: str = Field(max_length=255)
    is_active: bool = True
    is_superuser: bool = False
    role: RoleEnum
    cif: str | None = Field(default=None, unique=True, index=True, max_length=20)
    dni: str | None = Field(default=None, unique=True, index=True, max_length=20)

# Database model, database table inferred from class name
class User(UserBase, table=True):
    id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
    hashed_password: str
    account: "Account" = Relationship(back_populates="user")

# Properties to receive via API on creation
class UserCreate(UserBase):
    username: str = Field(max_length=100)
    password: str = Field(min_length=8, max_length=40)

# Properties to return via API, id is always required
class UserPublic(UserBase):
    id: uuid.UUID

class UsersPublic(SQLModel):
    data: list[UserPublic]
    count: int

class UserRegister(SQLModel):
    email: Annotated[str, EmailStr] = Field(max_length=255) 
    password: str = Field(min_length=8, max_length=40)
    full_name: str = Field(max_length=255)
    username: str = Field(max_length=100)
    role: RoleEnum
    cif: str | None = Field(default=None, max_length=20) # Only for Vendor Business
    dni: str | None = Field(default=None, max_length=20) # Only for Vendor Particular


# Properties to receive via API on update, all are optional
class UserUpdate(SQLModel):
    email: Optional[Annotated[str, EmailStr]] = Field(default=None, max_length=255) 
    password: Optional[str] = Field(default=None, min_length=8, max_length=40)
    full_name: Optional[str] = Field(default=None, max_length=255)
    role: Optional[RoleEnum] = Field(default=None)
    cif: Optional[str] = Field(default=None, max_length=20)
    dni: Optional[str] = Field(default=None, max_length=20)
    is_active: Optional[bool] = None

class UserUpdateMe(SQLModel):
    full_name: str | None = Field(default=None, max_length=255)
    email: Annotated[str, EmailStr] | None = Field(default=None, max_length=255)

# JSON payload containing access token
class Token(SQLModel):
    access_token: str
    token_type: str = "bearer"

# Contents of JWT token
class TokenPayload(SQLModel):
    sub: uuid.UUID | None = None

# Update password
class UpdatePassword(SQLModel):
    current_password: str = Field(min_length=8, max_length=40)
    new_password: str = Field(min_length=8, max_length=40)

# Generic message
class Message(SQLModel):
    message: str

# New password with token
class NewPassword(SQLModel):
    token: str
    new_password: str = Field(min_length=8, max_length=40)
