"""User model with combinable roles and admin flag."""
from datetime import datetime
from typing import Optional

from sqlalchemy import Boolean, DateTime, Enum, Integer, JSON, String, func
from sqlalchemy.orm import Mapped, mapped_column

from src.backend.database import Base


class User(Base):
    __tablename__ = "users"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    username: Mapped[str] = mapped_column(String(100), unique=True, nullable=False, index=True)
    password_hash: Mapped[str] = mapped_column(String(255), nullable=False)
    email: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
    display_name: Mapped[str] = mapped_column(String(255), nullable=False)

    # Roles: combinable JSON array of "Maker", "MeasurementTec", "Metrologist"
    roles: Mapped[list] = mapped_column(JSON, nullable=False, default=list)
    # Admin flag separate from roles
    is_admin: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)

    # User preferences
    language_pref: Mapped[str] = mapped_column(
        Enum("it", "en", name="language_enum"), nullable=False, default="it"
    )
    theme_pref: Mapped[str] = mapped_column(
        Enum("light", "dark", name="theme_enum"), nullable=False, default="light"
    )

    # Status
    active: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
    api_key: Mapped[Optional[str]] = mapped_column(String(64), unique=True, nullable=True, index=True)

    # Timestamps
    created_at: Mapped[datetime] = mapped_column(
        DateTime, nullable=False, server_default=func.now()
    )
    last_login: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)

    def has_role(self, role: str) -> bool:
        """Check if user has a specific role."""
        return role in (self.roles or [])

    def __repr__(self) -> str:
        return f"<User {self.username} roles={self.roles}>"
