from functools import wraps
from flask import abort, g
from .database import Militante, Celula, Setor, CR, CC

def check_permission(permission_func):
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            if not permission_func(*args, **kwargs):
                abort(403)
            return f(*args, **kwargs)
        return decorated_function
    return decorator

def can_manage_militante(militante_id):
    """Verifica se o usuário atual pode gerenciar um militante específico."""
    if not g.user or not g.user.militante:
        return False
    
    militante = Militante.query.get(militante_id)
    if not militante:
        return False
    
    # Secretário Geral e Secretário de Organização podem gerenciar qualquer militante
    if g.user.militante.responsabilidades & (Militante.SECRETARIO_GERAL | Militante.SECRETARIO_ORGANIZACAO):
        return True
    
    # Secretário de CC pode gerenciar militantes do seu CC
    if g.user.militante.responsabilidades & Militante.SECRETARIO_CC:
        if militante.celula.setor.cr.cc_id == g.user.militante.celula.setor.cr.cc_id:
            return True
    
    # Secretário de CR pode gerenciar militantes do seu CR
    if g.user.militante.responsabilidades & Militante.SECRETARIO_CR:
        if militante.celula.setor.cr_id == g.user.militante.celula.setor.cr_id:
            return True
    
    # Secretário de Setor pode gerenciar militantes do seu setor
    if g.user.militante.responsabilidades & Militante.SECRETARIO_SETOR:
        if militante.celula.setor_id == g.user.militante.celula.setor_id:
            return True
    
    # Secretário de Célula pode gerenciar militantes da sua célula
    if g.user.militante.responsabilidades & Militante.SECRETARIO_CELULA:
        if militante.celula_id == g.user.militante.celula_id:
            return True
    
    return False

def can_manage_celula(celula_id):
    """Verifica se o usuário atual pode gerenciar uma célula específica."""
    if not g.user or not g.user.militante:
        return False
    
    celula = Celula.query.get(celula_id)
    if not celula:
        return False
    
    # Secretário Geral e Secretário de Organização podem gerenciar qualquer célula
    if g.user.militante.responsabilidades & (Militante.SECRETARIO_GERAL | Militante.SECRETARIO_ORGANIZACAO):
        return True
    
    # Secretário de CC pode gerenciar células do seu CC
    if g.user.militante.responsabilidades & Militante.SECRETARIO_CC:
        if celula.setor.cr.cc_id == g.user.militante.celula.setor.cr.cc_id:
            return True
    
    # Secretário de CR pode gerenciar células do seu CR
    if g.user.militante.responsabilidades & Militante.SECRETARIO_CR:
        if celula.setor.cr_id == g.user.militante.celula.setor.cr_id:
            return True
    
    # Secretário de Setor pode gerenciar células do seu setor
    if g.user.militante.responsabilidades & Militante.SECRETARIO_SETOR:
        if celula.setor_id == g.user.militante.celula.setor_id:
            return True
    
    return False

def can_manage_setor(setor_id):
    """Verifica se o usuário atual pode gerenciar um setor específico."""
    if not g.user or not g.user.militante:
        return False
    
    setor = Setor.query.get(setor_id)
    if not setor:
        return False
    
    # Secretário Geral e Secretário de Organização podem gerenciar qualquer setor
    if g.user.militante.responsabilidades & (Militante.SECRETARIO_GERAL | Militante.SECRETARIO_ORGANIZACAO):
        return True
    
    # Secretário de CC pode gerenciar setores do seu CC
    if g.user.militante.responsabilidades & Militante.SECRETARIO_CC:
        if setor.cr.cc_id == g.user.militante.celula.setor.cr.cc_id:
            return True
    
    # Secretário de CR pode gerenciar setores do seu CR
    if g.user.militante.responsabilidades & Militante.SECRETARIO_CR:
        if setor.cr_id == g.user.militante.celula.setor.cr_id:
            return True
    
    return False

def can_manage_cr(cr_id):
    """Verifica se o usuário atual pode gerenciar um CR específico."""
    if not g.user or not g.user.militante:
        return False
    
    cr = CR.query.get(cr_id)
    if not cr:
        return False
    
    # Secretário Geral e Secretário de Organização podem gerenciar qualquer CR
    if g.user.militante.responsabilidades & (Militante.SECRETARIO_GERAL | Militante.SECRETARIO_ORGANIZACAO):
        return True
    
    # Secretário de CC pode gerenciar CRs do seu CC
    if g.user.militante.responsabilidades & Militante.SECRETARIO_CC:
        if cr.cc_id == g.user.militante.celula.setor.cr.cc_id:
            return True
    
    return False

def can_manage_cc(cc_id):
    """Verifica se o usuário atual pode gerenciar um CC específico."""
    if not g.user or not g.user.militante:
        return False
    
    # Apenas Secretário Geral e Secretário de Organização podem gerenciar CCs
    if g.user.militante.responsabilidades & (Militante.SECRETARIO_GERAL | Militante.SECRETARIO_ORGANIZACAO):
        return True
    
    return False

def can_manage_financas(instancia_id, tipo_instancia):
    """Verifica se o usuário atual pode gerenciar finanças de uma instância específica."""
    if not g.user or not g.user.militante:
        return False
    
    # Secretário Geral e Secretário de Organização podem gerenciar finanças de qualquer instância
    if g.user.militante.responsabilidades & (Militante.SECRETARIO_GERAL | Militante.SECRETARIO_ORGANIZACAO):
        return True
    
    # Responsável de Finanças da instância pode gerenciar suas finanças
    if tipo_instancia == 'celula':
        celula = Celula.query.get(instancia_id)
        if celula and celula.responsavel_financas_id == g.user.militante.id:
            return True
    elif tipo_instancia == 'setor':
        setor = Setor.query.get(instancia_id)
        if setor and setor.responsavel_financas_id == g.user.militante.id:
            return True
    elif tipo_instancia == 'cr':
        cr = CR.query.get(instancia_id)
        if cr and cr.responsavel_financas_id == g.user.militante.id:
            return True
    elif tipo_instancia == 'cc':
        cc = CC.query.get(instancia_id)
        if cc and cc.responsavel_financas_id == g.user.militante.id:
            return True
    
    return False

def can_manage_imprensa(instancia_id, tipo_instancia):
    """Verifica se o usuário atual pode gerenciar imprensa de uma instância específica."""
    if not g.user or not g.user.militante:
        return False
    
    # Secretário Geral e Secretário de Organização podem gerenciar imprensa de qualquer instância
    if g.user.militante.responsabilidades & (Militante.SECRETARIO_GERAL | Militante.SECRETARIO_ORGANIZACAO):
        return True
    
    # Responsável de Imprensa da instância pode gerenciar sua imprensa
    if tipo_instancia == 'celula':
        celula = Celula.query.get(instancia_id)
        if celula and celula.responsavel_imprensa_id == g.user.militante.id:
            return True
    elif tipo_instancia == 'setor':
        setor = Setor.query.get(instancia_id)
        if setor and setor.responsavel_imprensa_id == g.user.militante.id:
            return True
    elif tipo_instancia == 'cr':
        cr = CR.query.get(instancia_id)
        if cr and cr.responsavel_imprensa_id == g.user.militante.id:
            return True
    elif tipo_instancia == 'cc':
        cc = CC.query.get(instancia_id)
        if cc and cc.responsavel_imprensa_id == g.user.militante.id:
            return True
    
    return False

def can_manage_responsabilidades(militante_id):
    """Verifica se o usuário atual pode gerenciar responsabilidades de um militante específico."""
    if not g.user or not g.user.militante:
        return False
    
    militante = Militante.query.get(militante_id)
    if not militante:
        return False
    
    # Secretário Geral e Secretário de Organização podem gerenciar responsabilidades de qualquer militante
    if g.user.militante.responsabilidades & (Militante.SECRETARIO_GERAL | Militante.SECRETARIO_ORGANIZACAO):
        return True
    
    # Secretário de CC pode gerenciar responsabilidades de militantes do seu CC
    if g.user.militante.responsabilidades & Militante.SECRETARIO_CC:
        if militante.celula.setor.cr.cc_id == g.user.militante.celula.setor.cr.cc_id:
            return True
    
    # Secretário de CR pode gerenciar responsabilidades de militantes do seu CR
    if g.user.militante.responsabilidades & Militante.SECRETARIO_CR:
        if militante.celula.setor.cr_id == g.user.militante.celula.setor.cr_id:
            return True
    
    # Secretário de Setor pode gerenciar responsabilidades de militantes do seu setor
    if g.user.militante.responsabilidades & Militante.SECRETARIO_SETOR:
        if militante.celula.setor_id == g.user.militante.celula.setor_id:
            return True
    
    return False 