from sqlalchemy import Column, String, Table, ForeignKey, Integer, Boolean
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship, declarative_base, Mapped, mapped_column
from fastapi_users.db import SQLAlchemyBaseUserTableUUID, SQLAlchemyBaseUserTable
from typing import List

Base = declarative_base()


class Permissao(Base):
    __tablename__ = "permissoes"
    id = Column(Integer, primary_key=True, index=True)
    nome: Mapped[str] = mapped_column(String(50), nullable=False, unique=True)
    papeis: Mapped[List["Papel"]] = relationship(secondary='papel_permissoes',
                                                 back_populates='permissoes',
                                                 passive_deletes=True,
                                                 lazy="selectin",
                                                 join_depth=1)


class Papel(Base):
    __tablename__ = "papeis"
    id = Column(UUID(as_uuid=True), primary_key=True, index=True)
    nome: Mapped[str] = mapped_column(String(50), nullable=False, unique=True)
    permissoes: Mapped[List[Permissao]] = relationship(secondary='papel_permissoes',
                                                       back_populates='papeis',
                                                       passive_deletes=True,
                                                       lazy="selectin",
                                                       join_depth=1)
    usuarios: Mapped[List["User"]] = relationship(secondary='papeis_usuario',
                                                  back_populates='papeis',
                                                  passive_deletes=True,
                                                  lazy="selectin",
                                                  join_depth=1)


class User(SQLAlchemyBaseUserTable, Base):
    __tablename__ = "user"
    id = Column(UUID(as_uuid=True), primary_key=True, index=True)
    username = Column(String, nullable=False, unique=True)
    papeis: Mapped[List[Papel]] = relationship(secondary='papeis_usuario',
                                               back_populates='usuarios',
                                               passive_deletes=True,
                                               lazy="selectin",
                                               join_depth=1)
    is_active = Column(Boolean, default=True, nullable=False)
    is_superuser = Column(Boolean, default=False, nullable=False)


papeis_usuario = Table(
    'papeis_usuario', Base.metadata,
    Column('user_uuid', UUID(as_uuid=True), ForeignKey('user.id'), primary_key=True),
    Column('papel_uuid', UUID(as_uuid=True), ForeignKey('papeis.id'), primary_key=True)
)

papel_permissoes = Table(
    'papel_permissoes', Base.metadata,
    Column('papel_uuid', UUID(as_uuid=True), ForeignKey('papeis.id'), primary_key=True),
    Column('permissao_id', Integer, ForeignKey('permissoes.id'), primary_key=True)
)
