from sqlalchemy import Column, Integer, String, Text, ForeignKey, Table
from sqlalchemy.orm import relationship
from .base import Base

# Tabela de mapeamento Role-Permission
role_permissions = Table(
    'role_permissions',
    Base.metadata,
    Column('role_id', Integer, ForeignKey('roles.id'), primary_key=True),
    Column('permission_id', Integer, ForeignKey('permissions.id'), primary_key=True)
)

# Tabela de mapeamento User-Role
user_roles = Table(
    'user_roles',
    Base.metadata,
    Column('user_id', Integer, ForeignKey('usuarios.id'), primary_key=True),
    Column('role_id', Integer, ForeignKey('roles.id'), primary_key=True)
)

class Role(Base):
    __tablename__ = 'roles'
    
    id = Column(Integer, primary_key=True, autoincrement=True)
    nome = Column(String(50), unique=True, nullable=False)
    nivel = Column(Integer, nullable=False)  # Nível hierárquico
    descricao = Column(Text)
    
    # Relacionamentos
    permissions = relationship("Permission", secondary=role_permissions, back_populates="roles")
    users = relationship("Usuario", secondary=user_roles, back_populates="roles")

    # Níveis de role
    MILITANTE_BASICO = 1
    SECRETARIO_CELULA = 2
    MEMBRO_SETOR = 3
    SECRETARIO_SETOR = 4
    MEMBRO_CR = 5
    SECRETARIO_CR = 6
    MEMBRO_CC = 7
    SECRETARIO_GERAL = 8

    @staticmethod
    def get_roles_list():
        return [
            (Role.MILITANTE_BASICO, "Militante Básico"),
            (Role.SECRETARIO_CELULA, "Secretário de Célula"),
            (Role.MEMBRO_SETOR, "Membro de Setor"),
            (Role.SECRETARIO_SETOR, "Secretário de Setor"),
            (Role.MEMBRO_CR, "Membro de CR"),
            (Role.SECRETARIO_CR, "Secretário de CR"),
            (Role.MEMBRO_CC, "Membro do CC"),
            (Role.SECRETARIO_GERAL, "Secretário Geral")
        ]

class Permission(Base):
    __tablename__ = 'permissions'
    
    id = Column(Integer, primary_key=True, autoincrement=True)
    nome = Column(String(50), unique=True, nullable=False)
    descricao = Column(Text)
    
    # Relacionamentos
    roles = relationship("Role", secondary=role_permissions, back_populates="permissions")

    # Permissões básicas
    VIEW_OWN_DATA = "view_own_data"
    EDIT_OWN_DATA = "edit_own_data"
    VIEW_CELL_DATA = "view_cell_data"
    CREATE_MILITANT = "create_militant"  # Nova permissão para criar militantes

    # Permissões de célula
    MANAGE_CELL_MEMBERS = "manage_cell_members"
    CREATE_CELL_MEMBER = "create_cell_member"
    VIEW_CELL_REPORTS = "view_cell_reports"
    MANAGE_CELL_REPORTS = "manage_cell_reports"  # Nova permissão
    REGISTER_CELL_PAYMENT = "register_cell_payment"

    # Permissões de setor
    MANAGE_SECTOR_CELLS = "manage_sector_cells"
    CREATE_SECTOR_CELL = "create_sector_cell"
    VIEW_SECTOR_REPORTS = "view_sector_reports"
    REGISTER_SECTOR_PAYMENT = "register_sector_payment"

    # Permissões de CR
    MANAGE_CR_SECTORS = "manage_cr_sectors"
    CREATE_CR_SECTOR = "create_cr_sector"
    VIEW_CR_REPORTS = "view_cr_reports"
    REGISTER_CR_PAYMENT = "register_cr_payment"

    # Permissões de CC
    MANAGE_CC_CRS = "manage_cc_crs"
    CREATE_CC_CR = "create_cc_cr"
    VIEW_CC_REPORTS = "view_cc_reports"
    REGISTER_CC_PAYMENT = "register_cc_payment"
    SYSTEM_CONFIG = "system_config"

    @staticmethod
    def get_permissions_list():
        return [
            # Permissões básicas
            (Permission.VIEW_OWN_DATA, "Visualizar próprios dados"),
            (Permission.EDIT_OWN_DATA, "Editar próprios dados"),
            (Permission.VIEW_CELL_DATA, "Visualizar dados da célula"),
            (Permission.CREATE_MILITANT, "Criar novos militantes"),  # Nova permissão
            
            # Permissões de célula
            (Permission.MANAGE_CELL_MEMBERS, "Gerenciar membros da célula"),
            (Permission.CREATE_CELL_MEMBER, "Criar membros na célula"),
            (Permission.VIEW_CELL_REPORTS, "Visualizar relatórios da célula"),
            (Permission.MANAGE_CELL_REPORTS, "Gerenciar relatórios da célula"),  # Nova permissão
            (Permission.REGISTER_CELL_PAYMENT, "Registrar pagamentos da célula"),
            
            # Permissões de setor
            (Permission.MANAGE_SECTOR_CELLS, "Gerenciar células do setor"),
            (Permission.CREATE_SECTOR_CELL, "Criar células no setor"),
            (Permission.VIEW_SECTOR_REPORTS, "Visualizar relatórios do setor"),
            (Permission.REGISTER_SECTOR_PAYMENT, "Registrar pagamentos do setor"),
            
            # Permissões de CR
            (Permission.MANAGE_CR_SECTORS, "Gerenciar setores do CR"),
            (Permission.CREATE_CR_SECTOR, "Criar setores no CR"),
            (Permission.VIEW_CR_REPORTS, "Visualizar relatórios do CR"),
            (Permission.REGISTER_CR_PAYMENT, "Registrar pagamentos do CR"),
            
            # Permissões de CC
            (Permission.MANAGE_CC_CRS, "Gerenciar CRs"),
            (Permission.CREATE_CC_CR, "Criar CRs"),
            (Permission.VIEW_CC_REPORTS, "Visualizar relatórios nacionais"),
            (Permission.REGISTER_CC_PAYMENT, "Registrar pagamentos nacionais"),
            (Permission.SYSTEM_CONFIG, "Configurar sistema")
        ]

def init_rbac():
    """Inicializa o sistema RBAC com roles e permissões básicas"""
    from .database import Usuario, get_db_connection
    session = get_db_connection()
    
    try:
        # Criar role de administrador primeiro
        admin_role = session.query(Role).filter_by(nome="Administrador").first()
        if not admin_role:
            admin_role = Role(nome="Administrador", nivel=Role.SECRETARIO_GERAL)
            session.add(admin_role)
            session.commit()
        
        # Criar outras roles
        for nivel, nome in Role.get_roles_list():
            if nome != "Administrador":  # Pular Administrador pois já foi criado
                role = session.query(Role).filter_by(nivel=nivel).first()
                if not role:
                    role = Role(nome=nome, nivel=nivel)
                    session.add(role)
        
        # Criar permissões
        for nome, descricao in Permission.get_permissions_list():
            permission = session.query(Permission).filter_by(nome=nome).first()
            if not permission:
                permission = Permission(nome=nome, descricao=descricao)
                session.add(permission)
        
        session.commit()
        
        # Dar todas as permissões para o admin
        all_permissions = session.query(Permission).all()
        admin_role.permissions = all_permissions
        session.commit()
        
        # Buscar usuário admin e atribuir role de administrador
        admin_user = session.query(Usuario).filter_by(username="admin").first()
        if admin_user:
            if admin_role not in admin_user.roles:
                admin_user.roles = [admin_role]  # Substituir roles existentes
                session.commit()
        
        # Mapear permissões para outros roles
        for role in session.query(Role).filter(Role.nome != "Administrador").all():
            # Militante Básico
            if role.nivel == Role.MILITANTE_BASICO:
                role.permissions = [
                    session.query(Permission).filter_by(nome=Permission.VIEW_OWN_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.EDIT_OWN_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CELL_DATA).first()
                ]
            
            # Secretário de Célula
            elif role.nivel == Role.SECRETARIO_CELULA:
                role.permissions = [
                    session.query(Permission).filter_by(nome=Permission.VIEW_OWN_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.EDIT_OWN_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CELL_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_CELL_MEMBERS).first(),
                    session.query(Permission).filter_by(nome=Permission.CREATE_CELL_MEMBER).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CELL_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_CELL_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.REGISTER_CELL_PAYMENT).first()
                ]
            
            # Membro de Setor
            elif role.nivel == Role.MEMBRO_SETOR:
                role.permissions = [
                    session.query(Permission).filter_by(nome=Permission.VIEW_OWN_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.EDIT_OWN_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CELL_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_CELL_MEMBERS).first(),
                    session.query(Permission).filter_by(nome=Permission.CREATE_CELL_MEMBER).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CELL_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_CELL_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_SECTOR_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.REGISTER_SECTOR_PAYMENT).first()
                ]
            
            # Secretário de Setor
            elif role.nivel == Role.SECRETARIO_SETOR:
                role.permissions = [
                    session.query(Permission).filter_by(nome=Permission.VIEW_OWN_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.EDIT_OWN_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CELL_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_CELL_MEMBERS).first(),
                    session.query(Permission).filter_by(nome=Permission.CREATE_CELL_MEMBER).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CELL_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_CELL_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_SECTOR_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_SECTOR_CELLS).first(),
                    session.query(Permission).filter_by(nome=Permission.CREATE_SECTOR_CELL).first(),
                    session.query(Permission).filter_by(nome=Permission.REGISTER_SECTOR_PAYMENT).first()
                ]
            
            # Membro de CR
            elif role.nivel == Role.MEMBRO_CR:
                role.permissions = [
                    session.query(Permission).filter_by(nome=Permission.VIEW_OWN_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.EDIT_OWN_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CELL_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_CELL_MEMBERS).first(),
                    session.query(Permission).filter_by(nome=Permission.CREATE_CELL_MEMBER).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CELL_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_CELL_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_SECTOR_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_SECTOR_CELLS).first(),
                    session.query(Permission).filter_by(nome=Permission.CREATE_SECTOR_CELL).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CR_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.REGISTER_CR_PAYMENT).first()
                ]
            
            # Secretário de CR
            elif role.nivel == Role.SECRETARIO_CR:
                role.permissions = [
                    session.query(Permission).filter_by(nome=Permission.VIEW_OWN_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.EDIT_OWN_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CELL_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_CELL_MEMBERS).first(),
                    session.query(Permission).filter_by(nome=Permission.CREATE_CELL_MEMBER).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CELL_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_CELL_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_SECTOR_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_SECTOR_CELLS).first(),
                    session.query(Permission).filter_by(nome=Permission.CREATE_SECTOR_CELL).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CR_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_CR_SECTORS).first(),
                    session.query(Permission).filter_by(nome=Permission.CREATE_CR_SECTOR).first(),
                    session.query(Permission).filter_by(nome=Permission.REGISTER_CR_PAYMENT).first()
                ]
            
            # Membro do CC
            elif role.nivel == Role.MEMBRO_CC:
                role.permissions = [
                    session.query(Permission).filter_by(nome=Permission.VIEW_OWN_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.EDIT_OWN_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CELL_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_CELL_MEMBERS).first(),
                    session.query(Permission).filter_by(nome=Permission.CREATE_CELL_MEMBER).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CELL_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_CELL_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_SECTOR_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_SECTOR_CELLS).first(),
                    session.query(Permission).filter_by(nome=Permission.CREATE_SECTOR_CELL).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CR_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_CR_SECTORS).first(),
                    session.query(Permission).filter_by(nome=Permission.CREATE_CR_SECTOR).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CC_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.REGISTER_CC_PAYMENT).first()
                ]
            
            # Secretário Geral
            elif role.nivel == Role.SECRETARIO_GERAL:
                role.permissions = [
                    session.query(Permission).filter_by(nome=Permission.VIEW_OWN_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.EDIT_OWN_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CELL_DATA).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_CELL_MEMBERS).first(),
                    session.query(Permission).filter_by(nome=Permission.CREATE_CELL_MEMBER).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CELL_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_CELL_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_SECTOR_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_SECTOR_CELLS).first(),
                    session.query(Permission).filter_by(nome=Permission.CREATE_SECTOR_CELL).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CR_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_CR_SECTORS).first(),
                    session.query(Permission).filter_by(nome=Permission.CREATE_CR_SECTOR).first(),
                    session.query(Permission).filter_by(nome=Permission.VIEW_CC_REPORTS).first(),
                    session.query(Permission).filter_by(nome=Permission.MANAGE_CC_CRS).first(),
                    session.query(Permission).filter_by(nome=Permission.CREATE_CC_CR).first(),
                    session.query(Permission).filter_by(nome=Permission.REGISTER_CC_PAYMENT).first(),
                    session.query(Permission).filter_by(nome=Permission.SYSTEM_CONFIG).first()
                ]
        
        session.commit()
        
    except Exception as e:
        print(f"Erro ao inicializar RBAC: {e}")
        session.rollback()
        raise
    finally:
        session.close() 