# Role-permission join expression
from sqlalchemy import Enum, ForeignKey, Integer

from sqlalchemy import JSON, Boolean, Column, DateTime, String, func, join
from src.constants import CompanyUserRoleEnum, DepartmentEnum
from src.core.database import Base
from src.core.utils import generate_uuid
from src.models.company import Permission, RoleDepartmentPermission, UserRole
from sqlalchemy.orm import relationship
from sqlalchemy.ext.hybrid import hybrid_property

role_permission_join = join(
    UserRole,
    RoleDepartmentPermission,
    UserRole.role_department_id == RoleDepartmentPermission.role_department_id
)

class User(Base):
    __tablename__ = "users"

    id = Column(String, primary_key=True, index=True, default=generate_uuid)
    company_name = Column(String(100), nullable=False)
    
    company_id = Column(String) 
    full_name = Column(String(100), nullable=False)
    email = Column(String(100), unique=True, index=True, nullable=False)
    hashed_password = Column(String(255), nullable=False)

    is_2FA_required = Column(Boolean, default=False, nullable=False)
    is_2FA_enabled = Column(Boolean, default=False, nullable=False)
    temp_2fa_secret = Column(String(100), nullable=True)
    secret_2fa = Column(String(100), nullable=True)

    department = Column(Enum(DepartmentEnum), nullable=False)
    role = Column(Enum(CompanyUserRoleEnum), default=CompanyUserRoleEnum.VIEWER, nullable=False)
    permissions = Column(JSON, default=list)

    system_password_reset = Column(Boolean, default=False, nullable=False)
    password_reset_token = Column(String(512), nullable=True)
    is_active = Column(Boolean, default=True, nullable=False)
    created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), onupdate=func.now(), nullable=True)
    deleted_at = Column(DateTime(timezone=True), nullable=True)

   
    user_roles = relationship("UserRole", back_populates="user", cascade="all, delete-orphan")

    permissions_via_roles = relationship(
        "Permission",
        secondary=role_permission_join,
        primaryjoin=id == UserRole.user_id,
        secondaryjoin=Permission.permission_id == RoleDepartmentPermission.permission_id,
        viewonly=True,
        lazy="dynamic"
    )

    @hybrid_property
    def all_permissions(self):
        role_perms = [p.name for p in self.permissions_via_roles]
        custom_perms = self.permissions or []
        return list(set(custom_perms + role_perms))
