# Archivo: login.py
# Ruta: src\App\Security\login.py
# Lenguaje: Python con Flask

from flask import current_app as app
from flask import request, render_template, redirect, url_for, jsonify, session
import bcrypt
from functools import wraps
from datetime import datetime
import jwt
from Consultas_SQL.conexion import get_connection
from App.Security_Module.UserPassword import send_activation_email
from Consultas_SQL.Security.loginSQL import consultar_users, Actualizar_ultimo_login

def auth_routes(app, mail=None):
    @app.route('/auth/login', methods=['POST'])
    def login_auth():
        """
        Autenticación de usuarios.
        Verifica las credenciales contra la base de datos.
        """
        try:
            
            data = request.get_json()
            
            if not data:
                return jsonify({'success': False, 'message': 'No se recibieron datos.'}), 400
            
            email = data.get('email')
            password = data.get('password')
            remember = data.get('remember', False)
            
            if not email or not password:
                return jsonify({'success': False, 'message': 'Falta correo o contraseña.'}), 400
            
            result = consultar_users(email)
            # Verificar si la consulta devolvió un error (respuesta JSON)
            if isinstance(result, tuple) and len(result) == 2:
                return result  # Devuelve la respuesta JSON de error (401 o 500)

            # Si no hay error, result es un diccionario con los datos del usuario
            user_data = result
            user_id = user_data['UserID']
            db_email = user_data['Email']
            password_hash = user_data['PasswordHash']
            status = user_data['Status']
            
            # Verificar estado del usuario
            if status != 'ACTIVO':
            
                return jsonify({
                    'success': False, 
                    'message': 'Tu cuenta no está activa. Por favor, activa tu cuenta primero.'
                }), 401
                
            # Verificar contraseña con bcrypt
            if password_hash is None:
            
                return jsonify({
                    'success': False, 
                    'message': 'Debes establecer tu contraseña primero. Verifica tu correo electrónico para el enlace de activación.'
                }), 401
                
            try:
                # Limpiar posibles espacios u otros caracteres del hash
                clean_hash = str(password_hash).strip()

                # Verificar contraseña con bcrypt
                is_valid = bcrypt.checkpw(
                    password.encode('utf-8'), 
                    clean_hash.encode('utf-8')
                )
                
                if not is_valid:
                
                    return jsonify({
                        'success': False, 
                        'message': 'Credenciales incorrectas. Por favor, verifica tu correo y contraseña.'
                    }), 401
                
                # Actualizar último login
                update_success = Actualizar_ultimo_login(user_id)
                if not update_success:
                    print(f"Advertencia: No se pudo actualizar último login para usuario: {user_id}")
                
                # Crear sesión
                session.clear()  # Limpiar sesión actual por seguridad
                session['user_id'] = user_id
                session['email'] = email
                
                # Si 'remember me' está activado, aumentar la duración de la sesión
                if remember:
                    # Configurar para que la sesión dure 30 días
                    session.permanent = True
               
                return jsonify({
                    'success': True,
                    'message': 'Inicio de sesión exitoso.',
                    'redirect': '/index'
                })
                
            except Exception as e:
                print(f"Error al verificar contraseña: {e}")
                return jsonify({
                    'success': False, 
                    'message': 'Error al verificar credenciales. Por favor, inténtalo de nuevo.'
                }), 500
    
        except Exception as e:
            print(f"Error en login: {e}")
            return jsonify({
                'success': False, 
                'message': f'Error durante el inicio de sesión: {str(e)}'
            }), 500
    
    @app.route('/auth/logout')
    def logout_auth():
        """
        Cierra la sesión del usuario.
        """
        session.clear()
        return redirect(url_for('login'))
    
    # Decorator para proteger rutas que requieren autenticación
    def login_required(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            if 'user_id' not in session:
                return redirect(url_for('login'))
            return f(*args, **kwargs)
        return decorated_function
    
    # Agregar login_required al contexto de la aplicación para usarlo en otras partes
    app.login_required = login_required
    
    # Ejemplo de ruta protegida
    @app.route('/profile')
    @login_required
    def profile():
        return render_template('profile.html')
   
    @app.route('/auth/reset-password-request', methods=['POST'])
    def auth_request_password_reset(): 
        """
        Procesa la solicitud de recuperación de contraseña.
        Genera un token y envía un correo electrónico al usuario.
        """
        try:
            data = request.get_json()
            
            if not data or not data.get('email'):
                return jsonify({'success': False, 'message': 'Correo electrónico requerido'}), 400
            
            email = data.get('email')
            
            # Verificar si el correo existe en la base de datos
            check_query = """
                SELECT UserID, Email, Status
                FROM Users
                WHERE Email = ?
            """
            
            with get_connection() as conn:
                cursor = conn.cursor()
                cursor.execute(check_query, [email])
                user_data = cursor.fetchone()
                
                if not user_data:
                    # No informar al usuario si el correo no existe (por seguridad)
                    # Simular un envío exitoso para evitar enumeración de cuentas
                    return jsonify({
                        'success': True,
                        'message': 'Si tu correo está registrado, recibirás un enlace para restablecer tu contraseña.'
                    })
                
                user_id, user_email, status = user_data
                
                # Llamar a send_activation_email para enviar email de activación/restablecimiento
                token_result = send_activation_email(app, mail, user_id)
                
                # Si token_result es una tupla, significa que hubo un error
                if isinstance(token_result, tuple):
                    # Obtener la respuesta JSON y el código de estado
                    json_response, status_code = token_result
                    
                    # Extraer el contenido del error
                    try:
                        if hasattr(json_response, 'get_json'):
                            error_data = json_response.get_json()
                        else:
                            error_data = json_response.json
                            
                        # Devolver el error manteniendo el código de estado original
                        return jsonify({
                            'success': False,
                            'message': error_data.get('error', 'Error al enviar correo de restablecimiento')
                        }), status_code
                    except Exception as e:
                        print(f"Error al procesar respuesta de error: {e}")
                        return jsonify({
                            'success': False,
                            'message': 'Error al enviar correo de restablecimiento'
                        }), 500
                
                return jsonify({
                    'success': True,
                    'message': 'Se ha enviado un enlace para restablecer tu contraseña. Por favor, revisa tu correo electrónico.'
                })
                
        except Exception as e:
            print(f"Error en solicitud de restablecimiento: {e}")
            import traceback
            print(traceback.format_exc())
            return jsonify({
                'success': False,
                'message': 'Error al procesar la solicitud. Por favor, inténtalo más tarde.'
            }), 500
            
    # No olvides este return al final de la función auth_routes
    return auth_routes