#!/usr/bin/env python
"""
Script para identificar y corregir hashes de contraseña inválidos en la base de datos.
Este script busca usuarios con hashes de contraseña inválidos y permite resetear sus contraseñas.
"""

import os
import sys
from werkzeug.security import generate_password_hash, check_password_hash
from getpass import getpass

# Configurar el entorno
os.environ['FLASK_ENV'] = 'production'

# Importar la aplicación y modelos después de configurar el entorno
from app import create_app
from app.extensions import db
from app.models.user import User

def is_valid_hash(password_hash):
    """Verifica si un hash de contraseña tiene un formato válido"""
    if not password_hash:
        return False
    
    # Los hashes de Werkzeug tienen el formato: method$salt$hash
    parts = password_hash.split('$')
    return len(parts) >= 3 and parts[0]

def find_invalid_hashes():
    """Encuentra usuarios con hashes de contraseña inválidos"""
    app = create_app('production')
    
    with app.app_context():
        invalid_users = []
        all_users = User.query.all()
        
        print(f"\nRevisando {len(all_users)} usuarios en la base de datos...")
        
        for user in all_users:
            if not is_valid_hash(user.password_hash):
                invalid_users.append(user)
                print(f"- Usuario con hash inválido: {user.username} (ID: {user.id})")
                print(f"  Email: {user.email}")
                print(f"  Hash actual: {user.password_hash}")
        
        if not invalid_users:
            print("No se encontraron usuarios con hashes de contraseña inválidos.")
            return []
        
        print(f"\nSe encontraron {len(invalid_users)} usuarios con hashes de contraseña inválidos.")
        return invalid_users

def reset_password(user, new_password):
    """Resetea la contraseña de un usuario"""
    app = create_app('production')
    
    with app.app_context():
        user_obj = User.query.get(user.id)
        if not user_obj:
            print(f"Error: No se encontró el usuario con ID {user.id}")
            return False
        
        user_obj.password_hash = generate_password_hash(new_password)
        db.session.commit()
        
        # Verificar que el hash se haya guardado correctamente
        user_refreshed = User.query.get(user.id)
        if is_valid_hash(user_refreshed.password_hash):
            print(f"Contraseña actualizada correctamente para {user.username}")
            print(f"Nuevo hash: {user_refreshed.password_hash[:15]}...")
            return True
        else:
            print(f"Error: No se pudo actualizar el hash para {user.username}")
            return False

def main():
    """Función principal"""
    print("=== Herramienta de reparación de hashes de contraseña ===")
    
    # Encontrar usuarios con hashes inválidos
    invalid_users = find_invalid_hashes()
    
    if not invalid_users:
        return
    
    # Preguntar qué hacer con los usuarios encontrados
    print("\nOpciones:")
    print("1. Resetear contraseñas para todos los usuarios afectados")
    print("2. Resetear contraseña para un usuario específico")
    print("3. Salir sin hacer cambios")
    
    choice = input("\nSeleccione una opción (1-3): ")
    
    if choice == '1':
        default_password = input("Ingrese la contraseña predeterminada para todos los usuarios: ")
        
        for user in invalid_users:
            reset_password(user, default_password)
            
        print("\nProceso completado. Se actualizaron todas las contraseñas.")
        
    elif choice == '2':
        username = input("Ingrese el nombre de usuario a resetear: ")
        
        selected_user = None
        for user in invalid_users:
            if user.username == username:
                selected_user = user
                break
        
        if not selected_user:
            print(f"No se encontró un usuario con nombre '{username}' entre los usuarios afectados.")
            return
        
        new_password = getpass(f"Ingrese la nueva contraseña para {username}: ")
        confirm_password = getpass("Confirme la nueva contraseña: ")
        
        if new_password != confirm_password:
            print("Error: Las contraseñas no coinciden.")
            return
        
        reset_password(selected_user, new_password)
        
    else:
        print("Saliendo sin hacer cambios.")

if __name__ == '__main__':
    main()
