#!/usr/bin/env python3
"""
app.py - Backend principal de Auris con Flask y MySQL
Sistema de autenticación con encriptación de contraseñas
"""

import os
import sys
import json
import mysql.connector
from datetime import datetime, timedelta
from flask import Flask, request, jsonify, render_template, send_from_directory, redirect, make_response
from flask_cors import CORS
import bcrypt
import jwt
import docx2txt
from PyPDF2 import PdfReader
from werkzeug.utils import secure_filename
import base64
import requests
import shutil
import uuid
import asyncio

# Configuración de rutas
# Como app.py está en la raíz, el proyecto es __file__'s directorio
project_root = os.path.dirname(__file__)  # Directorio actual (raíz)
template_dir = os.path.join(project_root, 'frontend', 'templates')
static_dir = os.path.join(project_root, 'frontend', 'static')

# Crear la aplicación Flask
app = Flask(__name__,
            template_folder=template_dir,
            static_folder=static_dir)
CORS(app, supports_credentials=True)

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)

# Registrar blueprints
from backend.routes.tts_routes import tts_bp
app.register_blueprint(tts_bp)

from backend.routes.edge_tts_routes import edge_tts_bp
app.register_blueprint(edge_tts_bp)


# Configurar clave secreta para sesiones
app.secret_key = os.environ.get('SECRET_KEY', 'auris-secret-key-2025')

# ===== CONFIGURACIÓN DE BASE DE DATOS MYSQL =====
DB_CONFIG = {
    'host': os.environ.get('DB_HOST', 'localhost'),
    'user': os.environ.get('DB_USER', 'myadmon'),
    'password': os.environ.get('DB_PASSWORD', 'Quick25$$.'),
    'database': os.environ.get('DB_NAME', 'Auris'),
    'port': int(os.environ.get('DB_PORT', '3306')),
    'charset': 'utf8mb4',
    'autocommit': True
}

# Configuración de JWT
JWT_SECRET_KEY = os.environ.get('JWT_SECRET_KEY', 'auris-jwt-secret-2025')
JWT_ACCESS_TOKEN_EXPIRES = int(os.environ.get('JWT_ACCESS_TOKEN_EXPIRES', '86400'))

def get_db_connection():
    """Función para obtener conexión a MySQL"""
    try:
        connection = mysql.connector.connect(**DB_CONFIG)
        return connection
    except mysql.connector.Error as e:
        return None

def init_database():
    """Inicializar base de datos y crear tablas si no existen"""
    connection = None
    cursor = None
    try:
        connection = get_db_connection()
        if not connection:
            return False
        cursor = connection.cursor()
        connection.commit()
        return True
    except mysql.connector.Error as e:
        return False
    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()

# ===== RUTAS DE PRUEBA =====
@app.route('/api/test-db')
def test_db():
    """Probar conexión a la base de datos"""
    connection = get_db_connection()
    if connection:
        try:
            cursor = connection.cursor()
            cursor.execute("SELECT 1")
            result = cursor.fetchone()
            cursor.close()
            connection.close()
            return jsonify({
                'status': 'success',
                'message': 'Conexión a MySQL exitosa',
                'database': DB_CONFIG['database'],
                'test_query': 'SELECT 1',
                'result': result[0] if result else None
            }), 200
        except Exception as e:
            if connection:
                connection.close()
            return jsonify({
                'status': 'error',
                'message': f'Error ejecutando query de prueba: {str(e)}'
            }), 500
    else:
        return jsonify({
            'status': 'error',
            'message': 'Error de conexión a MySQL'
        }), 500

# ===== RUTAS DE AUTENTICACIÓN =====
@app.route('/api/register', methods=['POST'])
def register():
    """Registro de nuevos usuarios"""
    try:
        print("📝 Procesando registro de usuario...")
        data = request.json
        
        if not all(k in data for k in ('nombre_usuario', 'correo_electronico', 'contraseña')):
            return jsonify({'error': 'Faltan datos requeridos'}), 400
        
        nombre_usuario = data['nombre_usuario'].strip()
        correo_electronico = data['correo_electronico'].strip().lower()
        contraseña = data['contraseña']
        
        if len(nombre_usuario) < 3:
            return jsonify({'error': 'El nombre de usuario debe tener al menos 3 caracteres'}), 400
        if len(contraseña) < 6:
            return jsonify({'error': 'La contraseña debe tener al menos 6 caracteres'}), 400
        if '@' not in correo_electronico:
            return jsonify({'error': 'Correo electrónico inválido'}), 400
        
        connection = None
        cursor = None
        try:
            connection = get_db_connection()
            if not connection:
                print("❌ Error de conexión en registro")
                return jsonify({'error': 'Error de conexión a la base de datos'}), 500
                
            cursor = connection.cursor()
            cursor.execute("SELECT id FROM Usuarios WHERE correo_electronico = %s OR nombre_usuario = %s", 
                           (correo_electronico, nombre_usuario))
            if cursor.fetchone():
                print("❌ Usuario ya existe")
                return jsonify({'error': 'El usuario o correo ya existe'}), 409
            
            hashed_password = bcrypt.hashpw(contraseña.encode('utf-8'), bcrypt.gensalt())
            cursor.execute("""
                INSERT INTO Usuarios (nombre_usuario, correo_electronico, contraseña) 
                VALUES (%s, %s, %s)
            """, (nombre_usuario, correo_electronico, hashed_password.decode('utf-8')))
            
            user_id = cursor.lastrowid
            print(f"✅ Usuario creado con ID: {user_id}")
            
            default_configs = [
                ('tipo_voz', 'mujer'),
                ('velocidad_lectura', '1.0'),
                ('tamaño_fuente', 'medium'),
                ('contraste_alto', 'false'),
                ('retroalimentacion_audio', 'true')
            ]
            for config_name, config_value in default_configs:
                cursor.execute("""
                    INSERT INTO Configuraciones_Usuario (usuario_id, nombre_configuracion, valor_configuracion) 
                    VALUES (%s, %s, %s)
                """, (user_id, config_name, config_value))
            
            connection.commit()
            print("✅ Registro completado exitosamente")
            
            return jsonify({
                'status': 'success',
                'message': 'Usuario registrado exitosamente',
                'user_id': user_id
            }), 201
            
        except mysql.connector.Error as e:
            return jsonify({'error': f'Error de base de datos: {str(e)}'}), 500
        except Exception as e:
            return jsonify({'error': f'Error interno: {str(e)}'}), 500
        finally:
            if cursor:
                cursor.close()
            if connection:
                connection.close()
    
    except Exception as e:
        return jsonify({'error': f'Error crítico: {str(e)}'}), 500

@app.route('/api/login', methods=['POST'])
def login():
    """Autenticación de usuarios"""
    try:
        data = request.json
        
        if not all(k in data for k in ('correo_electronico', 'contraseña')):
            return jsonify({'error': 'Faltan datos requeridos'}), 400
        
        correo_electronico = data['correo_electronico'].strip().lower()
        contraseña = data['contraseña']
        
        connection = None
        cursor = None
        try:
            connection = get_db_connection()
            if not connection:
                return jsonify({'error': 'Error de conexión a la base de datos'}), 500
                
            cursor = connection.cursor(dictionary=True)
            cursor.execute("SELECT * FROM Usuarios WHERE correo_electronico = %s", (correo_electronico,))
            usuario = cursor.fetchone()
            
            if not usuario:
                print("❌ Usuario no encontrado")
                return jsonify({'error': 'Credenciales inválidas'}), 401
            
            if not bcrypt.checkpw(contraseña.encode('utf-8'), usuario['contraseña'].encode('utf-8')):
                print("❌ Contraseña incorrecta")
                return jsonify({'error': 'Credenciales inválidas'}), 401
            
            payload = {
                'user_id': usuario['id'],
                'exp': datetime.utcnow() + timedelta(seconds=JWT_ACCESS_TOKEN_EXPIRES)
            }
            token = jwt.encode(payload, JWT_SECRET_KEY, algorithm='HS256')
            
            cursor.execute("SELECT nombre_configuracion, valor_configuracion FROM Configuraciones_Usuario WHERE usuario_id = %s", (usuario['id'],))
            configs = cursor.fetchall()
            
            configuraciones = {}
            for config in configs:
                key = config['nombre_configuracion']
                value = config['valor_configuracion']
                if key in ['contraste_alto', 'retroalimentacion_audio']:
                    configuraciones[key] = value.lower() == 'true'
                elif key == 'velocidad_lectura':
                    configuraciones[key] = float(value)
                else:
                    configuraciones[key] = value
            
            response = make_response(jsonify({
                'status': 'success',
                'message': 'Login exitoso',
                'token': token,
                'usuario': {
                    'id': usuario['id'],
                    'nombre_usuario': usuario['nombre_usuario'],
                    'correo_electronico': usuario['correo_electronico'],
                    'foto_perfil': usuario['foto_perfil']
                },
                'configuraciones': configuraciones
            }))
            response.set_cookie('auth_token', token,
                                httponly=False,
                                secure=False,
                                samesite='Lax',
                                max_age=86400,
                                path='/')
            return response
            
        except mysql.connector.Error as e:
            return jsonify({'error': f'Error de base de datos: {str(e)}'}), 500
        except Exception as e:
            return jsonify({'error': f'Error interno: {str(e)}'}), 500
        finally:
            if cursor:
                cursor.close()
            if connection:
                connection.close()
    
    except Exception as e:
        return jsonify({'error': f'Error crítico: {str(e)}'}), 500

# ===== MIDDLEWARE DE AUTENTICACIÓN =====
def verify_token(token):
    try:
        payload = jwt.decode(token, JWT_SECRET_KEY, algorithms=['HS256'])
        return payload['user_id']
    except jwt.ExpiredSignatureError:
        print("❌ Token expirado")
        return None
    except jwt.InvalidTokenError:
        print("❌ Token inválido")
        return None

def auth_required(f):
    def decorated_function(*args, **kwargs):
        token = None
        
        auth_header = request.headers.get('Authorization')
        if auth_header and auth_header.startswith('Bearer '):
            token = auth_header[7:]
            print(f"🔍 Token en Authorization: {token[:20]}...")
        elif 'auth_token' in request.cookies:
            token = request.cookies.get('auth_token')
            print(f"🔍 Token en cookie: {token[:20] if token else 'None'}...")
        elif 'token' in request.args:
            token = request.args.get('token')
            print(f"🔍 Token en query: {token[:20] if token else 'None'}...")
        
        if not token:
            print("❌ No se encontró token")
            if request.endpoint in ['inicio', 'modo_visual', 'modo_auditivo', 'biblioteca', 'configuracion']:
                return redirect('/')
            return jsonify({'error': 'Token requerido'}), 401
        
        user_id = verify_token(token)
        if not user_id:
            print("❌ Token inválido o expirado")
            if request.endpoint in ['inicio', 'modo_visual', 'modo_auditivo', 'biblioteca', 'configuracion']:
                return redirect('/')
            return jsonify({'error': 'Token inválido'}), 401
        
        request.user_id = user_id
        return f(*args, **kwargs)
    
    decorated_function.__name__ = f.__name__
    return decorated_function

# ===== RUTAS DE DOCUMENTOS (CORREGIDAS) =====
@app.route('/api/documents', methods=['POST'])
@auth_required
def save_document():
    """Guardar documento del usuario"""
    data = request.json

    if not all(k in data for k in ('titulo', 'contenido')):
        return jsonify({'error': 'Faltan datos requeridos'}), 400

    titulo = data['titulo'].strip()
    contenido = data['contenido'].strip()

    if len(titulo) < 1:
        return jsonify({'error': 'El título no puede estar vacío'}), 400

    if len(titulo) > 50:
        return jsonify({'error': 'El título no puede exceder 50 caracteres'}), 400

    # Variables para el audio
    archivo_audio_blob = None
    nombre_archivo_audio = None
    ruta_archivo_audio = None
    tipo_mime = 'audio/mpeg'

    connection = None
    try:
        # --- 1. Obtener configuración del usuario ---
        connection = get_db_connection()
        if not connection:
            return jsonify({'error': 'Error de conexión a la base de datos'}), 500

        cursor_config = connection.cursor(dictionary=True)
        cursor_config.execute("""
            SELECT nombre_configuracion, valor_configuracion
            FROM Configuraciones_Usuario
            WHERE usuario_id = %s
        """, (request.user_id,))
        configs = cursor_config.fetchall()
        cursor_config.close()

        # Convertir configuraciones a diccionario
        configuraciones = {}
        for config in configs:
            key = config['nombre_configuracion']
            value = config['valor_configuracion']
            if key in ['contraste_alto', 'retroalimentacion_audio']:
                configuraciones[key] = value.lower() == 'true'
            elif key == 'velocidad_lectura':
                configuraciones[key] = float(value)
            else:
                configuraciones[key] = value

        voice_type = configuraciones.get('tipo_voz', 'mujer')
        speed = configuraciones.get('velocidad_lectura', 1.0)

        # --- 2. Intentar generar audio con Edge TTS ---
        try:
            tts_response = requests.post(
                'http://localhost:5001/api/synthesize-speech',
                json={
                    'text': contenido,
                    'voice_type': voice_type,
                    'speed': speed
                },
                timeout=10  # Timeout para evitar bloqueos
            )
            tts_response.raise_for_status()  # Lanzar excepción si hay error HTTP
            tts_data = tts_response.json()

            if tts_data.get('success'):
                # Crear nombre de archivo personalizado
                titulo_seguro = secure_filename(titulo)
                if not titulo_seguro:
                    titulo_seguro = f"documento_{uuid.uuid4().hex[:8]}"

                timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
                nombre_archivo_audio = f"{titulo_seguro}_{timestamp}.mp3"

                # Crear directorio de destino si no existe
                audio_dir = os.path.join(project_root, 'frontend', 'static', 'assets', 'audio')
                os.makedirs(audio_dir, exist_ok=True)
                ruta_archivo_audio = os.path.join(audio_dir, nombre_archivo_audio)

                # Descargar o copiar el audio generado
                audio_url = tts_data['audio_url']
                if audio_url.startswith('/static/'):
                    # Es una URL local
                    audio_file_path = os.path.join(project_root, 'frontend', audio_url.lstrip('/'))
                    if os.path.exists(audio_file_path):
                        shutil.copy2(audio_file_path, ruta_archivo_audio)
                        with open(ruta_archivo_audio, 'rb') as audio_file:
                            archivo_audio_blob = audio_file.read()
                        # Eliminar archivo temporal
                        try:
                            os.remove(audio_file_path)
                        except Exception as e:
                            print(f"⚠️ No se pudo eliminar el archivo temporal: {e}")
                    else:
                        print(f"⚠️ Archivo de audio no encontrado: {audio_file_path}")
                else:
                    # Es una URL externa
                    audio_response = requests.get(audio_url, timeout=10)
                    if audio_response.status_code == 200:
                        archivo_audio_blob = audio_response.content
                        with open(ruta_archivo_audio, 'wb') as f:
                            f.write(archivo_audio_blob)
            else:
                print(f"⚠️ Error en síntesis TTS: {tts_data.get('error', 'Desconocido')}")

        except requests.exceptions.RequestException as e:
            print(f"⚠️ Error al llamar al servicio TTS: {e}")
            # Continuar sin audio si hay error

        # --- 3. Guardar el documento en la base de datos ---
        cursor = connection.cursor()
        cursor.execute("""
            INSERT INTO Documentos
            (usuario_id, titulo, contenido, archivo_audio, nombre_archivo, tipo_mime)
            VALUES (%s, %s, %s, %s, %s, %s)
        """, (
            request.user_id,
            titulo,
            contenido,
            archivo_audio_blob,  # Puede ser None
            nombre_archivo_audio,  # Puede ser None
            tipo_mime
        ))

        document_id = cursor.lastrowid
        connection.commit()

        # --- 4. Respuesta al cliente ---
        audio_status = "con audio" if archivo_audio_blob else "sin audio"
        return jsonify({
            'status': 'success',
            'message': f'Documento guardado exitosamente {audio_status}',
            'document_id': document_id,
            'has_audio': archivo_audio_blob is not None,
            'audio_filename': nombre_archivo_audio if archivo_audio_blob else None
        }), 201

    except mysql.connector.Error as e:
        print(f"⚠️ Error de base de datos: {e}")
        return jsonify({'error': f'Error de base de datos: {str(e)}'}), 500

    except Exception as e:
        print(f"⚠️ Error inesperado: {e}")
        return jsonify({'error': f'Error interno: {str(e)}'}), 500

    finally:
        if connection:
            connection.close()

@app.route('/api/documents', methods=['GET'])
@auth_required
def get_user_documents():
    """Obtener documentos del usuario"""
    connection = None
    cursor = None
    try:
        connection = get_db_connection()
        if not connection:
            return jsonify({'error': 'Error de conexión a la base de datos'}), 500
            
        cursor = connection.cursor(dictionary=True)
        
        # Obtener documentos del usuario
        cursor.execute("""
            SELECT id, titulo, contenido, 
                   CASE WHEN archivo_audio IS NOT NULL THEN TRUE ELSE FALSE END as has_audio,
                   nombre_archivo, tipo_mime, creado_en, actualizado_en 
            FROM Documentos 
            WHERE usuario_id = %s 
            ORDER BY actualizado_en DESC
        """, (request.user_id,))
        
        documents = cursor.fetchall()
        
        # Convertir datetime a string para JSON
        for doc in documents:
            if doc['creado_en']:
                doc['creado_en'] = doc['creado_en'].isoformat()
            if doc['actualizado_en']:
                doc['actualizado_en'] = doc['actualizado_en'].isoformat()
        
        return jsonify({
            'status': 'success',
            'documents': documents
        }), 200
        
    except mysql.connector.Error as e:
        return jsonify({'error': f'Error de base de datos: {str(e)}'}), 500
    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()

@app.route('/api/documents/<int:document_id>', methods=['GET'])
@auth_required
def get_document(document_id):
    """Obtener un documento específico"""
    connection = None
    cursor = None
    try:
        connection = get_db_connection()
        if not connection:
            return jsonify({'error': 'Error de conexión a la base de datos'}), 500
            
        cursor = connection.cursor(dictionary=True)
        
        # Obtener documento específico del usuario
        cursor.execute("""
            SELECT id, titulo, contenido, 
                   CASE WHEN archivo_audio IS NOT NULL THEN TRUE ELSE FALSE END as has_audio,
                   nombre_archivo, tipo_mime, creado_en, actualizado_en 
            FROM Documentos 
            WHERE id = %s AND usuario_id = %s
        """, (document_id, request.user_id))
        
        document = cursor.fetchone()
        
        if not document:
            return jsonify({'error': 'Documento no encontrado'}), 404
        
        # Convertir datetime a string para JSON
        if document['creado_en']:
            document['creado_en'] = document['creado_en'].isoformat()
        if document['actualizado_en']:
            document['actualizado_en'] = document['actualizado_en'].isoformat()
        
        return jsonify({
            'status': 'success',
            'document': document
        }), 200
        
    except mysql.connector.Error as e:
        return jsonify({'error': f'Error de base de datos: {str(e)}'}), 500
    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()

@app.route('/api/documents/<int:document_id>/audio', methods=['GET'])
@auth_required
def get_document_audio(document_id):
    """Obtener el audio de un documento específico"""
    connection = None
    cursor = None
    try:
        connection = get_db_connection()
        if not connection:
            return jsonify({'error': 'Error de conexión a la base de datos'}), 500
            
        cursor = connection.cursor()
        
        # Primero intentar obtener el archivo desde la ruta guardada
        cursor.execute("""
            SELECT nombre_archivo, tipo_mime, archivo_audio
            FROM Documentos 
            WHERE id = %s AND usuario_id = %s AND (nombre_archivo IS NOT NULL OR archivo_audio IS NOT NULL)
        """, (document_id, request.user_id))
        
        result = cursor.fetchone()
        
        if not result:
            return jsonify({'error': 'Audio no encontrado'}), 404
        
        nombre_archivo, tipo_mime, archivo_audio = result
        
        # Intentar servir desde archivo guardado primero
        if nombre_archivo:
            audio_file_path = os.path.join(project_root, 'frontend', 'static', 'assets', 'audio', nombre_archivo)
            if os.path.exists(audio_file_path):
                return send_from_directory(
                    os.path.join(project_root, 'frontend', 'static', 'assets', 'audio'),
                    nombre_archivo,
                    mimetype=tipo_mime or 'audio/mpeg',
                    as_attachment=False
                )
        
        # Fallback al BLOB si no existe el archivo
        if archivo_audio:
            from flask import Response
            response = Response(
                archivo_audio,
                mimetype=tipo_mime or 'audio/mpeg',
                headers={
                    'Content-Disposition': f'inline; filename="{nombre_archivo or "audio.mp3"}"',
                    'Cache-Control': 'public, max-age=3600'
                }
            )
            return response
        
        return jsonify({'error': 'Audio no disponible'}), 404
        
    except mysql.connector.Error as e:
        return jsonify({'error': f'Error de base de datos: {str(e)}'}), 500
    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()

@app.route('/api/documents/<int:document_id>', methods=['PUT'])
@auth_required
def update_document(document_id):
    """Actualizar documento del usuario"""
    data = request.json
    
    if not data:
        return jsonify({'error': 'No se proporcionaron datos'}), 400
    
    connection = None
    cursor = None
    try:
        connection = get_db_connection()
        if not connection:
            return jsonify({'error': 'Error de conexión a la base de datos'}), 500
            
        cursor = connection.cursor()
        
        # Verificar que el documento pertenece al usuario
        cursor.execute("SELECT id FROM Documentos WHERE id = %s AND usuario_id = %s", 
                        (document_id, request.user_id))
        if not cursor.fetchone():
            return jsonify({'error': 'Documento no encontrado'}), 404
        
        # Construir query de actualización dinámicamente
        update_fields = []
        values = []
        
        if 'titulo' in data:
            titulo = data['titulo'].strip()
            if len(titulo) < 1:
                return jsonify({'error': 'El título no puede estar vacío'}), 400
            if len(titulo) > 50:
                return jsonify({'error': 'El título no puede exceder 50 caracteres'}), 400
            update_fields.append("titulo = %s")
            values.append(titulo)
        
        if 'contenido' in data:
            update_fields.append("contenido = %s")
            values.append(data['contenido'])
        
        if 'archivo_audio' in data:
            update_fields.append("archivo_audio = %s")
            values.append(data['archivo_audio'])
        
        if not update_fields:
            return jsonify({'error': 'No hay campos para actualizar'}), 400
        
        values.append(document_id)
        values.append(request.user_id)
        
        query = f"UPDATE Documentos SET {', '.join(update_fields)} WHERE id = %s AND usuario_id = %s"
        cursor.execute(query, values)
        connection.commit()
        
        return jsonify({
            'status': 'success',
            'message': 'Documento actualizado exitosamente'
        }), 200
        
    except mysql.connector.Error as e:
        return jsonify({'error': f'Error de base de datos: {str(e)}'}), 500
    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()

@app.route('/api/documents/<int:document_id>', methods=['DELETE'])
@auth_required
def delete_document(document_id):
    """Eliminar documento del usuario"""
    connection = None
    cursor = None
    try:
        connection = get_db_connection()
        if not connection:
            return jsonify({'error': 'Error de conexión a la base de datos'}), 500
            
        cursor = connection.cursor()
        
        # Verificar que el documento pertenece al usuario y eliminarlo
        cursor.execute("DELETE FROM Documentos WHERE id = %s AND usuario_id = %s", 
                      (document_id, request.user_id))
        
        if cursor.rowcount == 0:
            return jsonify({'error': 'Documento no encontrado'}), 404
        
        connection.commit()
        
        return jsonify({
            'status': 'success',
            'message': 'Documento eliminado exitosamente'
        }), 200
        
    except mysql.connector.Error as e:
        return jsonify({'error': f'Error de base de datos: {str(e)}'}), 500
    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()

@app.route('/api/audio-transcriptions', methods=['POST'])
@auth_required
def save_audio_transcription():
    # Verificar que el título y el texto transcrito estén presentes
    titulo = request.form.get('titulo')
    texto_transcrito = request.form.get('texto_transcrito')

    if not titulo or not texto_transcrito:
        return jsonify({'error': 'Faltan datos requeridos: título o texto transcrito'}), 400

    titulo = titulo.strip()
    texto_transcrito = texto_transcrito.strip()

    if len(titulo) < 1:
        return jsonify({'error': 'El título no puede estar vacío'}), 400

    if len(titulo) > 255:
        return jsonify({'error': 'El título no puede exceder 255 caracteres'}), 400

    # Guardar el archivo de audio si existe
    audio_file = request.files.get('archivo_audio_blob')
    audio_path = None

    if audio_file:
        audio_filename = secure_filename(f"{titulo}.webm")
        audio_path = os.path.join('frontend/static/assets/audios', audio_filename)
        os.makedirs(os.path.dirname(audio_path), exist_ok=True)
        audio_file.save(audio_path)

    # Guardar en la base de datos
    connection = None
    cursor = None
    try:
        connection = get_db_connection()
        cursor = connection.cursor()
        cursor.execute("""
            INSERT INTO Audio_a_Texto (usuario_id, archivo_audio, texto_transcrito, nombre_transcripcion)
            VALUES (%s, %s, %s, %s)
        """, (request.user_id, audio_path, texto_transcrito, titulo))
        connection.commit()
        return jsonify({'status': 'success', 'message': 'Transcripción guardada exitosamente'}), 201
    except mysql.connector.Error as e:
        return jsonify({'error': f'Error de base de datos: {str(e)}'}), 500
    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()


@app.route('/api/audio-transcriptions', methods=['GET'])
@auth_required
def get_user_audio_transcriptions():
    """Obtener transcripciones de audio del usuario"""
    connection = None
    cursor = None
    try:
        connection = get_db_connection()
        if not connection:
            return jsonify({'error': 'Error de conexión a la base de datos'}), 500

        cursor = connection.cursor(dictionary=True)

        # Obtener transcripciones del usuario
        cursor.execute("""
            SELECT id, nombre_transcripcion, creado_en, actualizado_en
            FROM Audio_a_Texto
            WHERE usuario_id = %s
            ORDER BY actualizado_en DESC
        """, (request.user_id,))

        transcriptions = cursor.fetchall()

        # Convertir datetime a string para JSON
        for trans in transcriptions:
            if trans['creado_en']:
                trans['creado_en'] = trans['creado_en'].isoformat()
            if trans['actualizado_en']:
                trans['actualizado_en'] = trans['actualizado_en'].isoformat()

        return jsonify({
            'status': 'success',
            'transcriptions': transcriptions
        }), 200

    except mysql.connector.Error as e:
        return jsonify({'error': f'Error de base de datos: {str(e)}'}), 500
    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()

@app.route('/api/audio-transcriptions/<int:transcription_id>', methods=['GET'])
@auth_required
def get_audio_transcription(transcription_id):
    """Obtener una transcripción específica"""
    connection = None
    cursor = None
    try:
        connection = get_db_connection()
        if not connection:
            return jsonify({'error': 'Error de conexión a la base de datos'}), 500

        cursor = connection.cursor(dictionary=True)

        # Obtener transcripción específica del usuario
        cursor.execute("""
            SELECT id, nombre_transcripcion, texto_transcrito, creado_en, actualizado_en
            FROM Audio_a_Texto
            WHERE id = %s AND usuario_id = %s
        """, (transcription_id, request.user_id))

        transcription = cursor.fetchone()

        if not transcription:
            return jsonify({'error': 'Transcripción no encontrada'}), 404

        # Convertir datetime a string para JSON
        if transcription['creado_en']:
            transcription['creado_en'] = transcription['creado_en'].isoformat()
        if transcription['actualizado_en']:
            transcription['actualizado_en'] = transcription['actualizado_en'].isoformat()

        return jsonify({
            'status': 'success',
            'transcription': transcription
        }), 200

    except mysql.connector.Error as e:
        return jsonify({'error': f'Error de base de datos: {str(e)}'}), 500
    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()

@app.route('/api/audio-transcriptions/<int:transcription_id>/audio', methods=['GET'])
@auth_required
def get_audio_transcription_audio(transcription_id):
    """Obtener el audio de una transcripción específica"""
    connection = None
    cursor = None
    try:
        connection = get_db_connection()
        if not connection:
            return jsonify({'error': 'Error de conexión a la base de datos'}), 500

        cursor = connection.cursor()

        # Obtener el audio de la transcripción
        cursor.execute("""
            SELECT archivo_audio
            FROM Audio_a_Texto
            WHERE id = %s AND usuario_id = %s
        """, (transcription_id, request.user_id))

        result = cursor.fetchone()

        if not result:
            return jsonify({'error': 'Audio no encontrado'}), 404

        archivo_audio = result[0]

        if archivo_audio:
            from flask import Response
            response = Response(
                archivo_audio,
                mimetype='audio/mpeg',
                headers={
                    'Content-Disposition': f'inline; filename="audio_{transcription_id}.mp3"',
                    'Cache-Control': 'public, max-age=3600'
                }
            )
            return response

        return jsonify({'error': 'Audio no disponible'}), 404

    except mysql.connector.Error as e:
        return jsonify({'error': f'Error de base de datos: {str(e)}'}), 500
    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()

@app.route('/api/audio-transcriptions/<int:transcription_id>', methods=['DELETE'])
@auth_required
def delete_audio_transcription(transcription_id):
    """Eliminar una transcripción del usuario"""
    connection = None
    cursor = None
    try:
        connection = get_db_connection()
        if not connection:
            return jsonify({'error': 'Error de conexión a la base de datos'}), 500

        cursor = connection.cursor()

        # Verificar que la transcripción pertenece al usuario y eliminarla
        cursor.execute("DELETE FROM Audio_a_Texto WHERE id = %s AND usuario_id = %s",
                      (transcription_id, request.user_id))

        if cursor.rowcount == 0:
            return jsonify({'error': 'Transcripción no encontrada'}), 404

        connection.commit()

        return jsonify({
            'status': 'success',
            'message': 'Transcripción eliminada exitosamente'
        }), 200

    except mysql.connector.Error as e:
        return jsonify({'error': f'Error de base de datos: {str(e)}'}), 500
    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()

@app.route('/api/library-items', methods=['GET'])
@auth_required
def get_library_items():
    connection = None
    cursor = None
    try:
        connection = get_db_connection()
        if not connection:
            return jsonify({'error': 'Error de conexión a la base de datos'}), 500

        cursor = connection.cursor(dictionary=True)

        # Obtener documentos
        cursor.execute("""
            SELECT 
                id, 
                titulo, 
                contenido, 
                creado_en, 
                actualizado_en,
                archivo_audio IS NOT NULL as has_audio,  -- ✅ Corregido: no existe has_audio
                nombre_archivo
            FROM documentos
            WHERE usuario_id = %s
            ORDER BY actualizado_en DESC
        """, (request.user_id,))
        documentos = cursor.fetchall()

        # Obtener transcripciones
        cursor.execute("""
            SELECT 
                id, 
                nombre_transcripcion as titulo, 
                texto_transcrito as contenido, 
                creado_en, 
                actualizado_en, 
                archivo_audio
            FROM Audio_a_Texto
            WHERE usuario_id = %s
            ORDER BY actualizado_en DESC
        """, (request.user_id,))
        transcripciones = cursor.fetchall()

        # Procesar documentos
        for doc in documentos:
            doc['tipo'] = 'documento'
            doc['has_audio'] = bool(doc['has_audio'])  # ya es booleano gracias a IS NOT NULL
            if doc['creado_en']:
                doc['creado_en'] = doc['creado_en'].isoformat()
            if doc['actualizado_en']:
                doc['actualizado_en'] = doc['actualizado_en'].isoformat()

        # Procesar transcripciones
        for trans in transcripciones:
            trans['tipo'] = 'transcripcion'
            trans['has_audio'] = bool(trans['archivo_audio'])
            trans['titulo'] = trans['titulo'] or "Sin título"
            if trans['creado_en']:
                trans['creado_en'] = trans['creado_en'].isoformat()
            if trans['actualizado_en']:
                trans['actualizado_en'] = trans['actualizado_en'].isoformat()

        # Combinar y ordenar por fecha de actualización
        all_items = documentos + transcripciones
        all_items.sort(key=lambda x: x['actualizado_en'], reverse=True)

        return jsonify({
            'status': 'success',
            'items': all_items
        }), 200

    except Exception as e:
        return jsonify({'error': f'Error interno del servidor: {str(e)}'}), 500
# ===== RUTAS DE CONFIGURACIÓN DE USUARIO =====

@app.route('/api/user/config', methods=['GET'])
@auth_required
def get_user_config():
    """Obtener configuración del usuario"""
    connection = None
    cursor = None
    try:
        connection = get_db_connection()
        if not connection:
            return jsonify({'error': 'Error de conexión a la base de datos'}), 500
            
        cursor = connection.cursor(dictionary=True)
        
        # Obtener datos del usuario
        cursor.execute("SELECT id, nombre_usuario, correo_electronico, foto_perfil FROM Usuarios WHERE id = %s", (request.user_id,))
        usuario = cursor.fetchone()
        
        # Obtener configuraciones
        cursor.execute("SELECT nombre_configuracion, valor_configuracion FROM Configuraciones_Usuario WHERE usuario_id = %s", (request.user_id,))
        configs = cursor.fetchall()
        
        # Convertir configuraciones a diccionario
        configuraciones = {}
        for config in configs:
            key = config['nombre_configuracion']
            value = config['valor_configuracion']
            
            # Convertir valores según el tipo
            if key in ['contraste_alto', 'retroalimentacion_audio']:
                configuraciones[key] = value.lower() == 'true'
            elif key == 'velocidad_lectura':
                configuraciones[key] = float(value)
            else:
                configuraciones[key] = value
        
        return jsonify({
            'status': 'success',
            'usuario': usuario,
            'configuraciones': configuraciones
        }), 200
        
    except mysql.connector.Error as e:
        return jsonify({'error': f'Error de base de datos: {str(e)}'}), 500
    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()

@app.route('/api/user/config', methods=['PUT'])
@auth_required
def update_user_config():
    """Actualizar configuración del usuario"""
    data = request.json
    
    connection = None
    cursor = None
    try:
        connection = get_db_connection()
        if not connection:
            return jsonify({'error': 'Error de conexión a la base de datos'}), 500
            
        cursor = connection.cursor()
        
        # Actualizar cada configuración
        for key, value in data.items():
            # Convertir valor a string para almacenar
            if isinstance(value, bool):
                str_value = 'true' if value else 'false'
            else:
                str_value = str(value)
            
            # Verificar si la configuración existe
            cursor.execute("SELECT id FROM Configuraciones_Usuario WHERE usuario_id = %s AND nombre_configuracion = %s", 
                            (request.user_id, key))
            
            if cursor.fetchone():
                # Actualizar configuración existente
                cursor.execute("""
                    UPDATE Configuraciones_Usuario 
                    SET valor_configuracion = %s 
                    WHERE usuario_id = %s AND nombre_configuracion = %s
                """, (str_value, request.user_id, key))
            else:
                # Crear nueva configuración
                cursor.execute("""
                    INSERT INTO Configuraciones_Usuario (usuario_id, nombre_configuracion, valor_configuracion) 
                    VALUES (%s, %s, %s)
                """, (request.user_id, key, str_value))
        
        connection.commit()
        
        return jsonify({
            'status': 'success',
            'message': 'Configuración actualizada exitosamente'
        }), 200
        
    except mysql.connector.Error as e:
        return jsonify({'error': f'Error de base de datos: {str(e)}'}), 500
    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()

# ===== RUTAS DE NAVEGACIÓN =====

@app.route('/')
def index():
    """Página de login"""
    try:
        print("🏠 Accediendo a página de login")
        return render_template('login.html')
    except Exception as e:
        print(f"❌ Error cargando template login.html: {e}")
        return f"Error: No se pudo cargar la página de login. {str(e)}", 500

@app.route('/modo_visual')
@auth_required
def modo_visual():
    """Página del asistente en modo visual"""
    try:
        return render_template('Modo_Visual.html')
    except Exception as e:
        print(f"❌ Error cargando template Modo_Visual.html: {e}")
        return f"Error: No se pudo cargar la página. {str(e)}", 500

@app.route('/modo_auditivo')
@auth_required
def modo_auditivo():
    """Página del asistente en modo auditivo"""
    try:
        return render_template('Modo_Auditivo.html')
    except Exception as e:
        print(f"❌ Error cargando template Modo_Auditivo.html: {e}")
        return f"Error: No se pudo cargar la página. {str(e)}", 500

@app.route('/biblioteca')
@auth_required
def biblioteca():
    """Página de la biblioteca de recursos"""
    try:
        return render_template('library.html')
    except Exception as e:
        print(f"❌ Error cargando template library.html: {e}")
        return f"Error: No se pudo cargar la página. {str(e)}", 500

@app.route('/configuracion')
@auth_required
def configuracion():
    """Página de configuración"""
    try:
        return render_template('config.html')
    except Exception as e:
        print(f"❌ Error cargando template config.html: {e}")
        return f"Error: No se pudo cargar la página. {str(e)}", 500

@app.route('/inicio')
@auth_required
def inicio():
    """Página principal después del login"""
    try:
        return render_template('index.html')
    except Exception as e:
        print(f"❌ Error cargando template index.html: {e}")
        return f"Error: No se pudo cargar la página. {str(e)}", 500

# ===== RUTAS DE PROCESAMIENTO DE ARCHIVOS =====

@app.route('/leer-archivo', methods=['POST'])
def leer_archivo():
    """Leer contenido de archivos subidos"""
    if 'file' not in request.files:
        return jsonify({'error': 'No se ha seleccionado ningún archivo'}), 400

    archivo = request.files['file']
    if archivo.filename == '':
        return jsonify({'error': 'Archivo vacío'}), 400

    filename = archivo.filename.lower()

    try:
        if filename.endswith('.txt'):
            contenido = archivo.read().decode('utf-8')

        elif filename.endswith('.pdf'):
            archivo.save("temp.pdf")
            reader = PdfReader("temp.pdf")
            contenido = ""
            for page in reader.pages:
                contenido += page.extract_text()
            os.remove("temp.pdf")

        elif filename.endswith('.docx'):
            archivo.save("temp.docx")
            contenido = docx2txt.process("temp.docx")
            os.remove("temp.docx")

        else:
            return jsonify({'error': 'Formato no soportado. Usa .txt, .pdf o .docx'}), 400

        return jsonify({
            'status': 'success',
            'nombre': archivo.filename, 
            'texto': contenido
        }), 200

    except Exception as e:
        return jsonify({'error': f'Error al leer el archivo: {e}'}), 500

# ===== RUTAS DE HEALTH CHECK =====

@app.route('/health')
def health_check():
    """Health check endpoint"""
    connection = get_db_connection()
    db_status = 'connected' if connection else 'disconnected'
    if connection:
        connection.close()
    
    return jsonify({
        'status': 'healthy',
        'timestamp': datetime.now().isoformat(),
        'database': db_status,
        'templates_dir': template_dir,
        'static_dir': static_dir,
        'templates_exists': os.path.exists(template_dir),
        'static_exists': os.path.exists(static_dir)
    }), 200

# ===== INICIALIZACIÓN =====

if __name__ == '__main__':
    print("🚀 Iniciando aplicación Auris...")
    
    # Mostrar información del entorno
    print(f"🌍 Python: {sys.version}")
    print(f"🌍 Directorio de trabajo: {os.getcwd()}")
    print(f"🌍 Variables de entorno DB: HOST={os.environ.get('DB_HOST', 'localhost')}")
    
    # Inicializar base de datos
    if init_database():
        print("✅ Base de datos inicializada correctamente")
    else:
        print("⚠️ Error al inicializar base de datos - continuando...")
    
    port = int(os.environ.get("PORT", 5000))
    print(f"🌐 Servidor ejecutándose en puerto {port}")
    
    debug_mode = os.environ.get('FLASK_ENV') == 'development'
    app.run(host='0.0.0.0', port=port, debug=debug_mode)
