from flask import Blueprint, render_template, request, redirect, url_for, flash, session, abort
from ..models import db, Usuario, Campanha, MetaCadastrador, AuditoriaLog
from ..services.rede_service import validar_novo_pai
from ..utils.auth_decorators import login_required, write_required

usuarios_bp = Blueprint('usuarios', __name__, url_prefix='/usuarios')

def perfis_permitidos_para(usuario):
    """Mapeamento de perfis que um usuário pode criar/atribuir (dev, admin, multiplicador, visualizador)"""
    if usuario.is_dev or usuario.is_admin:
        return [Usuario.ROLE_ADMIN, Usuario.ROLE_DEV, Usuario.ROLE_VISUALIZADOR, Usuario.ROLE_CADASTRADOR]
    elif usuario.is_cadastrador:
        return [Usuario.ROLE_CADASTRADOR]
    return []

@usuarios_bp.route('/')
@login_required
def index():
    user_role = session.get('usuario_perfil')
    campanha_id = session.get('campanha_id')
    user_id = session.get('usuario_id')
    current_user = db.session.get(Usuario, user_id)
    
    query = Usuario.query
    if user_role not in [Usuario.ROLE_DEV, Usuario.ROLE_ADMIN, Usuario.ROLE_VISUALIZADOR, 'admin_1', 'admin_2', 'superadmin_dev', 'administrador']:
        query = query.filter((Usuario.id == user_id) | (Usuario.cadastrador_pai_id == user_id))
    elif campanha_id:
        query = query.filter_by(campanha_id=campanha_id)
        
    usuarios = query.all()
    campanha = db.session.get(Campanha, campanha_id) if campanha_id else None
    
    return render_template('usuarios/lista.html', usuarios=usuarios, campanha=campanha, current_user=current_user)

@usuarios_bp.route('/novo', methods=['GET', 'POST'])
@login_required
@write_required
def novo():
    user_id = session.get('usuario_id')
    current_user = db.session.get(Usuario, user_id)
    campanha_id = session.get('campanha_id')
    campanha = db.session.get(Campanha, campanha_id) if campanha_id else None
    
    allowed_roles = perfis_permitidos_para(current_user)
    if not allowed_roles:
        flash('Você não possui permissão para cadastrar outros usuários.', 'danger')
        return redirect(url_for('dashboards.index'))

    # Potenciais superiores hierárquicos
    potenciais_pais = Usuario.query.filter_by(campanha_id=campanha_id, perfil=Usuario.ROLE_CADASTRADOR).all() if campanha_id else []

    if request.method == 'POST':
        nome = request.form.get('nome', '').strip()
        email = request.form.get('email', '').strip()
        senha = request.form.get('senha', '')
        perfil_solicitado = request.form.get('perfil', Usuario.ROLE_CADASTRADOR)
        telefone = request.form.get('telefone', '').strip()
        pai_id_str = request.form.get('cadastrador_pai_id')
        meta_custom = request.form.get('meta_custom')
        
        # RN-USU-03: Rejeição no backend se tentar atribuir perfil não permitido
        if perfil_solicitado not in allowed_roles:
            AuditoriaLog.registrar(
                usuario_id=user_id,
                usuario_nome=current_user.nome,
                acao='VIOLACAO_PERMISSAO_RBAC',
                entidade='Usuario',
                detalhes=f'Tentativa não autorizada de criar perfil {perfil_solicitado}',
                ip=request.remote_addr
            )
            abort(403)
            
        cadastrador_pai_id = int(pai_id_str) if pai_id_str else (user_id if current_user.perfil == Usuario.ROLE_CADASTRADOR else None)
        
        # Validação Anti-Ciclos
        valido, msg_erro = validar_novo_pai(None, cadastrador_pai_id, campanha_id)
        if not valido:
            flash(msg_erro, 'danger')
            return render_template('usuarios/form.html', campanha=campanha, current_user=current_user, allowed_roles=allowed_roles, pais=potenciais_pais)

        if Usuario.query.filter_by(email=email).first():
            flash('Este e-mail já está cadastrado no sistema.', 'danger')
            return render_template('usuarios/form.html', campanha=campanha, current_user=current_user, allowed_roles=allowed_roles, pais=potenciais_pais)
            
        usuario = Usuario(
            nome=nome,
            email=email,
            perfil=perfil_solicitado,
            telefone=telefone,
            campanha_id=campanha_id,
            criado_por_id=user_id,
            cadastrador_pai_id=cadastrador_pai_id
        )
        usuario.set_senha(senha)
        db.session.add(usuario)
        db.session.flush()
        
        if perfil_solicitado == Usuario.ROLE_CADASTRADOR:
            meta_val = int(meta_custom) if meta_custom else (campanha.meta_por_cadastrador if campanha else 25)
            meta_obj = MetaCadastrador(
                cadastrador_id=usuario.id,
                campanha_id=campanha_id,
                meta=meta_val,
                quantidade_atual=0
            )
            db.session.add(meta_obj)
            
        db.session.commit()
        
        AuditoriaLog.registrar(
            usuario_id=user_id,
            usuario_nome=current_user.nome,
            acao='CRIAR_USUARIO_COMPLETO',
            entidade='Usuario',
            entidade_id=usuario.id,
            detalhes=f'Novo usuário {usuario.nome} ({usuario.perfil}) atribuído a pai ID: {cadastrador_pai_id}',
            ip=request.remote_addr
        )
        
        flash(f'Usuário {nome} registrado com sucesso!', 'success')
        return redirect(url_for('usuarios.index'))
        
    return render_template('usuarios/form.html', campanha=campanha, current_user=current_user, allowed_roles=allowed_roles, pais=potenciais_pais)

@usuarios_bp.route('/<int:user_id>/editar', methods=['GET', 'POST'])
@login_required
@write_required
def editar(user_id):
    current_user = db.session.get(Usuario, session.get('usuario_id'))
    usuario_alvo = db.session.get(Usuario, user_id)
    campanha_id = session.get('campanha_id')
    campanha = db.session.get(Campanha, campanha_id) if campanha_id else None
    
    allowed_roles = perfis_permitidos_para(current_user)
    potenciais_pais = Usuario.query.filter(
        Usuario.campanha_id == campanha_id,
        Usuario.perfil == Usuario.ROLE_CADASTRADOR,
        Usuario.id != user_id
    ).all() if campanha_id else []

    if request.method == 'POST':
        nome = request.form.get('nome', '').strip()
        email = request.form.get('email', '').strip()
        perfil_solicitado = request.form.get('perfil', usuario_alvo.perfil)
        pai_id_str = request.form.get('cadastrador_pai_id')
        
        if perfil_solicitado not in allowed_roles:
            abort(403)
            
        cadastrador_pai_id = int(pai_id_str) if pai_id_str else None
        
        # Validação Anti-Ciclos (RN-USU-01)
        valido, msg_erro = validar_novo_pai(usuario_alvo.id, cadastrador_pai_id, campanha_id)
        if not valido:
            flash(msg_erro, 'danger')
            return render_template('usuarios/form.html', usuario=usuario_alvo, campanha=campanha, current_user=current_user, allowed_roles=allowed_roles, pais=potenciais_pais)

        usuario_alvo.nome = nome
        usuario_alvo.email = email
        usuario_alvo.perfil = perfil_solicitado
        usuario_alvo.cadastrador_pai_id = cadastrador_pai_id
        
        # Atualizar meta personalizada do multiplicador se informada
        meta_custom = request.form.get('meta_custom')
        if meta_custom:
            try:
                meta_val = int(meta_custom)
                meta_obj = MetaCadastrador.query.filter_by(cadastrador_id=usuario_alvo.id).first()
                if not meta_obj:
                    meta_obj = MetaCadastrador(
                        cadastrador_id=usuario_alvo.id,
                        campanha_id=campanha_id,
                        meta=meta_val,
                        quantidade_atual=0
                    )
                    db.session.add(meta_obj)
                else:
                    meta_obj.meta = meta_val
            except ValueError:
                pass
                
        db.session.commit()
        
        AuditoriaLog.registrar(
            usuario_id=current_user.id,
            usuario_nome=current_user.nome,
            acao='EDITAR_USUARIO',
            entidade='Usuario',
            entidade_id=usuario_alvo.id,
            detalhes=f'Usuário {usuario_alvo.nome} atualizado (Pai ID: {cadastrador_pai_id})',
            ip=request.remote_addr
        )
        
        flash(f'Usuário {usuario_alvo.nome} atualizado com sucesso!', 'success')
        return redirect(url_for('usuarios.index'))
        
    meta_obj = MetaCadastrador.query.filter_by(cadastrador_id=usuario_alvo.id).first()
    meta_atual = meta_obj.meta if meta_obj else (campanha.meta_por_cadastrador if campanha else 50)
    
    return render_template('usuarios/form.html', usuario=usuario_alvo, campanha=campanha, current_user=current_user, allowed_roles=allowed_roles, pais=potenciais_pais, meta_atual=meta_atual)

@usuarios_bp.route('/<int:user_id>/toggle', methods=['POST'])
@login_required
@write_required
def toggle(user_id):
    current_user = db.session.get(Usuario, session.get('usuario_id'))
    if not current_user.can_manage_users():
        flash('Sem permissão para alterar status de usuários.', 'danger')
        return redirect(url_for('usuarios.index'))
        
    usuario = db.session.get(Usuario, user_id)
    if usuario:
        usuario.ativo = not usuario.ativo
        db.session.commit()
        
        status_str = "ativado" if usuario.ativo else "desativado"
        AuditoriaLog.registrar(
            usuario_id=current_user.id,
            usuario_nome=current_user.nome,
            acao='ALTERAR_STATUS_USUARIO',
            entidade='Usuario',
            entidade_id=usuario.id,
            detalhes=f'Usuário {usuario.nome} {status_str}',
            ip=request.remote_addr
        )
        flash(f'Usuário {usuario.nome} foi {status_str}.', 'info')
    return redirect(url_for('usuarios.index'))

@usuarios_bp.route('/<int:user_id>/reset-senha', methods=['POST'])
@login_required
@write_required
def reset_senha(user_id):
    current_user = db.session.get(Usuario, session.get('usuario_id'))
    if not current_user.can_create_cadastrador():
        flash('Sem permissão para resetar senhas de usuários.', 'danger')
        return redirect(url_for('usuarios.index'))
        
    usuario = db.session.get(Usuario, user_id)
    if usuario:
        cpf_limpo = ''.join(c for c in (usuario.cpf or '') if c.isdigit())
        senha_inicial = cpf_limpo if cpf_limpo else (usuario.cpf or usuario.email or '123456')
        
        usuario.set_senha(senha_inicial)
        usuario.primeiro_acesso = True
        usuario.solicitou_reset = False
        db.session.commit()
        
        AuditoriaLog.registrar(
            usuario_id=current_user.id,
            usuario_nome=current_user.nome,
            acao='RESET_SENHA_ADMINISTRATIVO',
            entidade='Usuario',
            entidade_id=usuario.id,
            detalhes=f'Senha do usuário {usuario.nome} resetada para o CPF e primeiro_acesso reativado',
            ip=request.remote_addr
        )
        flash(f'Senha de {usuario.nome} resetada com sucesso! No próximo login ele usará o CPF como senha inicial e criará uma nova senha.', 'success')
    return redirect(url_for('usuarios.index'))

@usuarios_bp.route('/pedidos-reset')
@login_required
def pedidos_reset():
    """Página dedicada aos Admin/Dev para visualizar e atender solicitações de esqueci a senha"""
    current_user = db.session.get(Usuario, session.get('usuario_id'))
    if not current_user.can_create_cadastrador():
        flash('Sem permissão para gerenciar solicitações de reset de senha.', 'danger')
        return redirect(url_for('dashboards.index'))

    campanha_id = session.get('campanha_id')
    query = Usuario.query.filter_by(solicitou_reset=True)
    if campanha_id:
        query = query.filter_by(campanha_id=campanha_id)

    pedidos = query.all()
    return render_template('usuarios/pedidos_reset.html', pedidos=pedidos, current_user=current_user)
