from flask import Blueprint, request, jsonify
from database import db
from auth import token_required
import mysql.connector
import hashlib
import base64
import logging

logger = logging.getLogger(__name__)

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

@usuarios_bp.route('/registro', methods=['POST'])
def registro():
    data = request.get_json()
    
    required_fields = ['nombre', 'apellido', 'username', 'mail', 'password']
    for field in required_fields:
        if not data.get(field):
            return jsonify({
                "status": "error",
                "message": f"Campo {field} es obligatorio"
            }), 400
    
    nombre = data['nombre']
    apellido = data['apellido']
    username = data['username']
    mail = data['mail']
    password = data['password']
    privacidad = data.get('privacidad', 0)
    tokenFCM = data.get('tokenFCM', '')
    
    connection = db.get_connection()
    if not connection:
        return jsonify({
            "status": "error", 
            "message": "Error de conexión a la base de datos"
        }), 500
    
    try:
        cursor = connection.cursor(dictionary=True)
        
        # Check if user exists
        cursor.execute(
            "SELECT id FROM Xalarrazabal025_usuarios WHERE username = %s OR mail = %s",
            (username, mail)
        )
        if cursor.fetchone():
            return jsonify({
                "status": "error",
                "message": "El usuario o correo ya existe"
            }), 400
        
        # Hash password
        hashed_password = hashlib.md5(password.encode()).hexdigest()
        
        # Insert user
        cursor.execute(
            """INSERT INTO Xalarrazabal025_usuarios 
            (nombre, apellido, username, mail, contrasenia, privacidad) 
            VALUES (%s, %s, %s, %s, %s, %s)""",
            (nombre, apellido, username, mail, hashed_password, privacidad)
        )
        
        user_id = cursor.lastrowid
        
        # Generate token
        import secrets
        token = secrets.token_hex(32)
        
        # Save token
        cursor.execute(
            """INSERT INTO Xalarrazabal025_user_app 
            (idUser, token, tokenFCM) VALUES (%s, %s, %s)""",
            (user_id, token, tokenFCM)
        )
        
        connection.commit()
        
        return jsonify({
            "status": "success",
            "message": "Registro exitoso",
            "token": token,
            "nombre": nombre,
            "apellido": apellido,
            "username": username,
            "mail": mail
        }), 201
        
    except mysql.connector.Error as e:
        connection.rollback()
        logger.error(f"Database error: {e}")
        return jsonify({
            "status": "error",
            "message": "Error al registrar usuario"
        }), 500
    finally:
        cursor.close()
        connection.close()

@usuarios_bp.route('/login', methods=['POST'])
def login():
    data = request.get_json()
    
    username = data.get('username')
    password = data.get('password')
    tokenFCM = data.get('tokenFCM', '')
    
    if not username or not password:
        return jsonify({
            "status": "error",
            "message": "Usuario y contraseña son obligatorios"
        }), 400
    
    connection = db.get_connection()
    if not connection:
        return jsonify({
            "status": "error", 
            "message": "Error de conexión a la base de datos"
        }), 500
    
    try:
        cursor = connection.cursor(dictionary=True)
        
        cursor.execute(
            """SELECT id, nombre, apellido, username, mail, contrasenia, foto 
            FROM Xalarrazabal025_usuarios WHERE username = %s""",
            (username,)
        )
        user = cursor.fetchone()
        
        if not user:
            return jsonify({
                "status": "error",
                "message": "Usuario no encontrado"
            }), 404
        
        # Verify password
        hashed_input = hashlib.md5(password.encode()).hexdigest()
        if hashed_input != user['contrasenia']:
            return jsonify({
                "status": "error",
                "message": "Contraseña incorrecta"
            }), 401
        
        # Generate new token
        import secrets
        token = secrets.token_hex(32)
        
        # Save token
        cursor.execute(
            """INSERT INTO Xalarrazabal025_user_app 
            (idUser, token, tokenFCM) VALUES (%s, %s, %s)""",
            (user['id'], token, tokenFCM)
        )
        
        connection.commit()
        
        # Prepare photo data
        foto_data = None
        if user['foto']:
            foto_data = base64.b64encode(user['foto']).decode('utf-8')
        
        return jsonify({
            "status": "success",
            "token": token,
            "mensaje": "Inicio de sesión exitoso",
            "nombre": user['nombre'],
            "apellido": user['apellido'],
            "username": user['username'],
            "mail": user['mail'],
            "foto": foto_data
        })
        
    except mysql.connector.Error as e:
        connection.rollback()
        logger.error(f"Database error: {e}")
        return jsonify({
            "status": "error",
            "message": "Error en el servidor"
        }), 500
    finally:
        cursor.close()
        connection.close()

@usuarios_bp.route('/perfil', methods=['PUT'])
@token_required
def actualizar_perfil():
    data = request.get_json()
    
    nombre = data.get('nombre')
    apellido = data.get('apellido')
    mail = data.get('mail')
    password = data.get('password')
    
    # Check if at least one field is provided
    if all(field is None for field in [nombre, apellido, mail, password]):
        return jsonify({
            "status": "error",
            "message": "Debe proporcionar al menos un campo para actualizar"
        }), 400
    
    connection = db.get_connection()
    if not connection:
        return jsonify({
            "status": "error", 
            "message": "Error de conexión a la base de datos"
        }), 500
    
    try:
        cursor = connection.cursor(dictionary=True)
        
        # Check if email is already used
        if mail:
            cursor.execute(
                "SELECT id FROM Xalarrazabal025_usuarios WHERE mail = %s AND id != %s",
                (mail, request.user_id)
            )
            if cursor.fetchone():
                return jsonify({
                    "status": "error",
                    "message": "El correo electrónico ya está en uso por otro usuario"
                }), 400
        
        # Build dynamic update query
        updates = []
        params = []
        
        if nombre is not None:
            updates.append("nombre = %s")
            params.append(nombre)
        
        if apellido is not None:
            updates.append("apellido = %s")
            params.append(apellido)
        
        if mail is not None:
            updates.append("mail = %s")
            params.append(mail)
        
        if password is not None:
            hashed_password = hashlib.md5(password.encode()).hexdigest()
            updates.append("contrasenia = %s")
            params.append(hashed_password)
        
        params.append(request.user_id)
        
        query = f"UPDATE Xalarrazabal025_usuarios SET {', '.join(updates)} WHERE id = %s"
        cursor.execute(query, params)
        
        # Get updated user data
        cursor.execute(
            "SELECT nombre, apellido, username, mail FROM Xalarrazabal025_usuarios WHERE id = %s",
            (request.user_id,)
        )
        user = cursor.fetchone()
        
        connection.commit()
        
        return jsonify({
            "status": "success",
            "message": "Datos actualizados correctamente",
            "user": user
        })
        
    except mysql.connector.Error as e:
        connection.rollback()
        logger.error(f"Database error: {e}")
        return jsonify({
            "status": "error",
            "message": "Error al actualizar los datos"
        }), 500
    finally:
        cursor.close()
        connection.close()

@usuarios_bp.route('/foto', methods=['GET', 'PUT'])
@token_required
def gestionar_foto():
    connection = db.get_connection()
    if not connection:
        return jsonify({
            "status": "error", 
            "message": "Error de conexión a la base de datos"
        }), 500
    
    try:
        cursor = connection.cursor(dictionary=True)
        
        if request.method == 'GET':
            cursor.execute(
                "SELECT foto FROM Xalarrazabal025_usuarios WHERE id = %s",
                (request.user_id,)
            )
            result = cursor.fetchone()
            
            if not result:
                return jsonify({
                    "status": "error",
                    "message": "Usuario no encontrado",
                    "foto": None
                }), 404
            
            foto_data = result['foto']
            return jsonify({
                "status": "success",
                "message": "Foto obtenida correctamente",
                "foto": foto_data
            })
        
        elif request.method == 'PUT':
            data = request.get_json()
            img = data.get('img')
            
            if not img:
                return jsonify({
                    "status": "error",
                    "message": "Imagen no proporcionada"
                }), 400
            
            cursor.execute(
                "UPDATE Xalarrazabal025_usuarios SET foto = %s WHERE id = %s",
                (img, request.user_id)
            )
            
            connection.commit()
            
            return jsonify({
                "status": "success",
                "message": "Imagen actualizada correctamente",
                "img": img
            })
            
    except mysql.connector.Error as e:
        connection.rollback()
        logger.error(f"Database error: {e}")
        return jsonify({
            "status": "error",
            "message": "Error de base de datos"
        }), 500
    finally:
        cursor.close()
        connection.close()

@usuarios_bp.route('/logout', methods=['POST'])
@token_required
def logout():
    connection = db.get_connection()
    if not connection:
        return jsonify({
            "status": "error", 
            "message": "Error de conexión a la base de datos"
        }), 500
    
    try:
        cursor = connection.cursor()
        cursor.execute(
            "DELETE FROM Xalarrazabal025_user_app WHERE token = %s",
            (request.token,)
        )
        
        connection.commit()
        
        if cursor.rowcount > 0:
            return jsonify({
                "status": "success",
                "message": "Sesión cerrada correctamente"
            })
        else:
            return jsonify({
                "status": "error",
                "message": "Token no encontrado"
            }), 404
            
    except mysql.connector.Error as e:
        connection.rollback()
        logger.error(f"Database error: {e}")
        return jsonify({
            "status": "error",
            "message": "Error al cerrar sesión"
        }), 500
    finally:
        cursor.close()
        connection.close()

@usuarios_bp.route('/verificar-token', methods=['POST'])
def verificar_token():
    data = request.get_json()
    
    token = data.get('token')
    tokenFCM = data.get('tokenFCM')
    
    if not token:
        return jsonify({
            "status": "error",
            "message": "Token de usuario no proporcionado"
        }), 400
    
    if not tokenFCM:
        return jsonify({
            "status": "error",
            "message": "Token FCM no proporcionado"
        }), 400
    
    connection = db.get_connection()
    if not connection:
        return jsonify({
            "status": "error", 
            "message": "Error de conexión a la base de datos"
        }), 500
    
    try:
        cursor = connection.cursor(dictionary=True)
        cursor.execute(
            "SELECT idUser, fecha FROM Xalarrazabal025_user_app WHERE token = %s",
            (token,)
        )
        result = cursor.fetchone()
        
        if result:
            # Update FCM token
            cursor.execute(
                "UPDATE Xalarrazabal025_user_app SET tokenFCM = %s WHERE token = %s",
                (tokenFCM, token)
            )
            connection.commit()
            
            return jsonify({
                "status": "success",
                "message": "Token válido y FCM actualizado",
                "idUser": result['idUser'],
                "fecha": result['fecha'].isoformat() if result['fecha'] else None
            })
        else:
            return jsonify({
                "status": "invalid",
                "message": "Token no válido o expirado"
            }), 401
            
    except mysql.connector.Error as e:
        connection.rollback()
        logger.error(f"Database error: {e}")
        return jsonify({
            "status": "error",
            "message": "Error de base de datos"
        }), 500
    finally:
        cursor.close()
        connection.close()