"""
app/routes/usuarios.py – CRUD completo de usuarios (solo Administrador).
"""
import logging
from flask import Blueprint, render_template, redirect, url_for, flash, request
from flask_login import login_required

from app import db
from app.models import Usuario, Rol
from app.forms  import UsuarioForm
from app.utils.decorators import role_required

usuarios_bp = Blueprint('usuarios', __name__, url_prefix='/usuarios')
logger       = logging.getLogger(__name__)


@usuarios_bp.route('/')
@login_required
@role_required('Administrador')
def lista():
    page    = request.args.get('page', 1, type=int)
    por_pag = 15
    usuarios = (Usuario.query
                .join(Rol)
                .order_by(Usuario.nombre_completo)
                .paginate(page=page, per_page=por_pag, error_out=False))
    return render_template('usuarios/list.html', usuarios=usuarios)


@usuarios_bp.route('/nuevo', methods=['GET', 'POST'])
@login_required
@role_required('Administrador')
def nuevo():
    form = UsuarioForm()
    form.rol_id.choices = [(r.id, r.nombre) for r in Rol.query.order_by(Rol.nombre).all()]

    if form.validate_on_submit():
        if not form.password.data:
            flash('La contraseña es obligatoria al crear un usuario.', 'danger')
            return render_template('usuarios/form.html', form=form, titulo='Nuevo Usuario')

        if Usuario.query.filter_by(correo=form.correo.data.strip().lower()).first():
            flash('Ya existe un usuario con ese correo.', 'danger')
            return render_template('usuarios/form.html', form=form, titulo='Nuevo Usuario')

        usuario = Usuario(
            nombre_completo=form.nombre_completo.data.strip(),
            correo=form.correo.data.strip().lower(),
            puesto=form.puesto.data.strip(),
            rol_id=form.rol_id.data,
            activo=form.activo.data,
        )
        usuario.set_password(form.password.data)
        db.session.add(usuario)
        db.session.commit()
        logger.info('Usuario creado: %s', usuario.correo)
        flash('Usuario creado correctamente.', 'success')
        return redirect(url_for('usuarios.lista'))

    return render_template('usuarios/form.html', form=form, titulo='Nuevo Usuario')


@usuarios_bp.route('/<int:id>/editar', methods=['GET', 'POST'])
@login_required
@role_required('Administrador')
def editar(id):
    usuario = Usuario.query.get_or_404(id)
    form    = UsuarioForm(obj=usuario)
    form.rol_id.choices = [(r.id, r.nombre) for r in Rol.query.order_by(Rol.nombre).all()]

    if form.validate_on_submit():
        correo_nuevo = form.correo.data.strip().lower()
        existe = Usuario.query.filter(
            Usuario.correo == correo_nuevo, Usuario.id != id
        ).first()
        if existe:
            flash('Ya existe otro usuario con ese correo.', 'danger')
            return render_template('usuarios/form.html', form=form,
                                   titulo='Editar Usuario', usuario=usuario)

        usuario.nombre_completo = form.nombre_completo.data.strip()
        usuario.correo          = correo_nuevo
        usuario.puesto          = form.puesto.data.strip()
        usuario.rol_id          = form.rol_id.data
        usuario.activo          = form.activo.data

        if form.password.data:
            usuario.set_password(form.password.data)

        db.session.commit()
        logger.info('Usuario editado: %s', usuario.correo)
        flash('Usuario actualizado correctamente.', 'success')
        return redirect(url_for('usuarios.lista'))

    return render_template('usuarios/form.html', form=form,
                           titulo='Editar Usuario', usuario=usuario)


@usuarios_bp.route('/<int:id>/toggle', methods=['POST'])
@login_required
@role_required('Administrador')
def toggle_activo(id):
    usuario = Usuario.query.get_or_404(id)
    usuario.activo = not usuario.activo
    db.session.commit()
    estado = 'activado' if usuario.activo else 'desactivado'
    flash(f'Usuario {estado} correctamente.', 'success')
    logger.info('Usuario %s: %s', usuario.correo, estado)
    return redirect(url_for('usuarios.lista'))
