from typing import Optional
from datetime import datetime
from uuid import UUID
from sqlalchemy import String, DateTime, ForeignKey, Boolean, Text
from sqlalchemy.dialects.postgresql import UUID as PG_UUID
from sqlalchemy.orm import Mapped, mapped_column, relationship
from src.database.base import BaseModel, SoftDeleteMixin
from src.core.constants import UserRole, UserStatus


class User(BaseModel, SoftDeleteMixin):
    __tablename__ = "users"

    tenant_id: Mapped[Optional[UUID]] = mapped_column(
        PG_UUID(as_uuid=True),
        ForeignKey("accounts.id", ondelete="SET NULL"),
        nullable=True,  # NULL for site_admin users
        index=True,
    )
    email: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
    password_hash: Mapped[str] = mapped_column(String(255), nullable=False)
    first_name: Mapped[str] = mapped_column(String(100), nullable=False)
    last_name: Mapped[str] = mapped_column(String(100), nullable=False)
    role: Mapped[str] = mapped_column(
        String(50), nullable=False, default=UserRole.STAFF.value, index=True
    )
    status: Mapped[str] = mapped_column(
        String(50), nullable=False, default=UserStatus.INVITED.value, index=True
    )
    avatar_url: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
    last_login_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)

    # Relationships
    tenant: Mapped[Optional[object]] = relationship(
        "Account", back_populates="users", foreign_keys=[tenant_id], lazy="noload"
    )
    refresh_tokens: Mapped[list] = relationship(
        "RefreshToken", back_populates="user", lazy="noload", cascade="all, delete-orphan"
    )

    @property
    def full_name(self) -> str:
        return f"{self.first_name} {self.last_name}"

    @property
    def is_site_admin(self) -> bool:
        return self.role == UserRole.SITE_ADMIN.value

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