from flask import (
    Blueprint,
    render_template,
    redirect,
    url_for,
    flash,
    request,
    jsonify,
    current_app,
)
from flask_login import login_required, current_user
from flask_wtf import FlaskForm
from wtforms import (
    StringField,
    PasswordField,
    SelectField,
    IntegerField,
    EmailField,
    BooleanField,
    SubmitField,
)
from wtforms.validators import DataRequired, Email, Length, Optional, EqualTo

from services.auth_service import (
    get_all_users,
    get_user_by_username,
    create_user,
    update_user,
    delete_user,
)
from services.user_service import (
    filter_users,
    get_user_stats,
    check_username_availability,
)
from utils.validators import validate_user_data
from utils.security import permission_required
from utils.logger import log_user_management

# Definir Blueprint
users_bp = Blueprint("users", __name__, url_prefix="/users")


# Formularios
class UserForm(FlaskForm):
    """Formulario para crear/editar usuarios."""

    nombre = StringField("Nombre completo", validators=[DataRequired(), Length(1, 100)])
    username = StringField(
        "Nombre de usuario", validators=[DataRequired(), Length(3, 20)]
    )
    email = EmailField("Email", validators=[DataRequired(), Email()])
    password = PasswordField("Contraseña", validators=[Optional(), Length(8, 64)])
    password_confirm = PasswordField(
        "Confirmar contraseña",
        validators=[
            Optional(),
            EqualTo("password", message="Las contraseñas deben coincidir"),
        ],
    )
    nivel = IntegerField("Nivel de acceso", validators=[DataRequired()])
    idioma = SelectField("Idioma", choices=[("es", "Español"), ("en", "Inglés")])
    empresa = StringField("Empresa", validators=[Optional(), Length(0, 100)])
    estado = SelectField(
        "Estado", choices=[("activo", "Activo"), ("inactivo", "Inactivo")]
    )
    fecha_caducidad = StringField(
        "Fecha de caducidad (YYYY-MM-DD)", validators=[Optional()]
    )
    submit = SubmitField("Guardar")


class UserFilterForm(FlaskForm):
    """Formulario para filtrar usuarios."""

    empresa = StringField("Empresa", validators=[Optional()])
    estado = SelectField(
        "Estado",
        choices=[("", "Todos"), ("activo", "Activo"), ("inactivo", "Inactivo")],
        validators=[Optional()],
    )
    nivel_min = IntegerField("Nivel mínimo", validators=[Optional()])
    nivel_max = IntegerField("Nivel máximo", validators=[Optional()])
    submit = SubmitField("Filtrar")


# Rutas
@users_bp.route("/")
@login_required
@permission_required(1000)  # Minimum permission level
def list():
    """List all users."""
    users = get_all_users()
    return render_template("users/list.html", users=users)


@users_bp.route("/create", methods=["GET", "POST"])
@login_required
@permission_required(9000)  # Admin level permission required
def create():  # Changed from create_user to create
    """Create a new user."""
    form = UserForm()

    if request.method == "POST" and form.validate_on_submit():
        try:
            # Extract user data from form
            user_data = {
                "username": form.username.data,
                "nombre": form.nombre.data,
                "email": form.email.data,
                "password": form.password.data,
                "nivel": form.nivel.data,
                "empresa": form.empresa.data,
                "idioma": form.idioma.data,
            }

            # Create the user
            result = create_user(user_data)  # This is a function call, not a route

            if result["success"]:
                flash("Usuario creado exitosamente.", "success")
                return redirect(url_for("users.list"))
            else:
                flash(f'Error al crear usuario: {result["error"]}', "danger")

        except Exception as e:
            flash(f"Error inesperado: {str(e)}", "danger")

    # If GET request or form validation failed
    return render_template("users/create.html", form=form)


@users_bp.route("/edit/<username>", methods=["GET", "POST"])
@login_required
@permission_required(9000)  # Solo administradores
def edit(username):
    """Editar usuario existente."""
    user = get_user_by_username(username)

    if not user:
        flash(f"Usuario {username} no encontrado.", "danger")
        return redirect(url_for("users.list"))

    form = UserForm(obj=user)

    if form.validate_on_submit():
        # Validar datos
        data = {
            "nombre": form.nombre.data,
            "email": form.email.data,
            "password": form.password.data,
            "nivel": form.nivel.data,
            "idioma": form.idioma.data,
            "empresa": form.empresa.data,
            "estado": form.estado.data,
            "fecha_caducidad": (
                form.fecha_caducidad.data if form.fecha_caducidad.data else None
            ),
        }

        is_valid, errors = validate_user_data(data, is_new_user=False)

        if not is_valid:
            for field, error in errors.items():
                flash(f"Error en {field}: {error}", "danger")
            return render_template("users/edit.html", form=form, username=username)

        # Actualizar usuario
        success, message = update_user(username, data)

        if success:
            flash(message, "success")

            # Registrar actividad
            log_user_management(
                admin_id=current_user.id,
                target_user_id=username,
                action="update",
                details={"fields_updated": list(data.keys())},
            )

            return redirect(url_for("users.list"))
        else:
            flash(message, "danger")

    return render_template("users/edit.html", form=form, username=username)


@users_bp.route("/delete/<username>", methods=["POST"])
@login_required
@permission_required(9000)  # Solo administradores
def delete(username):
    """Eliminar usuario."""
    if username == current_user.id:
        flash("No puede eliminar su propio usuario.", "danger")
        return redirect(url_for("users.list"))

    if username == "admin":
        flash("No se puede eliminar el usuario administrador.", "danger")
        return redirect(url_for("users.list"))

    success, message = delete_user(username)

    if success:
        flash(message, "success")

        # Registrar actividad
        log_user_management(
            admin_id=current_user.id, target_user_id=username, action="delete"
        )
    else:
        flash(message, "danger")

    return redirect(url_for("users.list"))


# API para verificar disponibilidad de nombre de usuario
@users_bp.route("/api/check_username", methods=["POST"])
@login_required
@permission_required(9000)  # Solo administradores
def api_check_username():
    """Verificar disponibilidad de nombre de usuario."""
    data = request.get_json()

    if not data or "username" not in data:
        return jsonify({"error": "Se requiere nombre de usuario"}), 400

    username = data["username"]
    available = check_username_availability(username)

    return jsonify({"available": available})
