# ui_layout.py
import tkinter as tk
from tkinter import Menu, ttk, messagebox
from tkinter.scrolledtext import ScrolledText 
import threading
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import datetime 
import os 

# Importar funciones y variables
import system_utils
import monitor_manager
import config


def crear_ui_completa(root):
    """Configura el layout principal, crea todos los widgets e inicia hilos."""
    
    # Aplicar un tema más moderno para ttk
    style = ttk.Style()
    style.theme_use('clam') 
    
    # --- FUNCIONES AUXILIARES DE UI (Para llamadas a eventos y botones) ---
    
    def abrir_editor_alarma(event_or_none, treeview_alarmas):
        """
        Verifica la selección en el Treeview y abre la ventana flotante con los datos cargados.
        Puede ser llamada por un evento (doble clic) o por un botón.
        """
        # Obtenemos el ítem seleccionado (focus() funciona para botón y doble clic si hay foco)
        selected_item = treeview_alarmas.focus()
        
        # Si no hay selección, salimos.
        if not selected_item:
            messagebox.showwarning("Advertencia", "Selecciona una alarma para modificar.")
            return

        # Obtenemos el ID de la alarma (primer valor de la fila)
        alarma_id = int(treeview_alarmas.item(selected_item, 'values')[0])
        data = config.alarmas_programadas.get(alarma_id)

        if not data:
            messagebox.showerror("Error", "No se encontraron los datos de la alarma seleccionada.")
            return

        # Llamamos a la función flotante en modo modificación
        mostrar_selector_alarma_flotante(treeview_alarmas, alarma_id, data)


    def on_closing():
        config.monitor_running = False 
        system_utils.detener_sonido_alarma() 
        system_utils.detener_mp3() # Detener música al cerrar
        system_utils.limpiar_chat_al_cerrar()
        root.destroy()
        
    root.protocol("WM_DELETE_WINDOW", on_closing) 

    # Configuración de Layout
    root.columnconfigure(0, weight=0) 
    root.columnconfigure(1, weight=1) 
    root.columnconfigure(2, weight=0) 
    root.rowconfigure(0, weight=1)
    root.rowconfigure(1, weight=0)

    # --- Creación de Frames Principales ---
    frame_izquierdo = tk.Frame(root, bg="#f0f0f0", width=200) 
    frame_central = tk.Frame(root, bg="white")
    frame_derecho = tk.Frame(root, bg="#f0f0f0", width=10) 

    frame_izquierdo.grid(row=0, column=0, sticky="nsew")
    frame_central.grid(row=0, column=1, sticky="nsew")
    frame_derecho.grid(row=0, column=2, sticky="nsew")

    frame_izquierdo.grid_propagate(False) 
    frame_derecho.grid_propagate(False) 

    # Layout del Frame Central
    frame_central.rowconfigure(0, weight=1)
    frame_central.rowconfigure(1, weight=0)
    frame_central.columnconfigure(0, weight=1)

    frame_superior = tk.Frame(frame_central, bg="lightyellow")
    frame_inferior = tk.Frame(frame_central, bg="lightgray", height=100) 

    frame_superior.grid(row=0, column=0, sticky="nsew")
    frame_inferior.grid(row=1, column=0, sticky="ew")
    frame_inferior.grid_propagate(False)

    # --- Implementación del Progressbar (Frame Inferior) ---
    progress_bar = ttk.Progressbar(frame_inferior, orient="horizontal", length=800, mode="determinate")
    progress_bar.pack(pady=10, padx=20, fill="x")
    config.progress_bar = progress_bar
    # -----------------------------------------------

    # Notebook para las pestañas
    notebook = ttk.Notebook(frame_superior)
    notebook.pack(fill="both", expand=True)

    # --- PESTAÑA 1: PROGRAMADOR DE ALARMAS ---
    alarma_tab = ttk.Frame(notebook)
    notebook.add(alarma_tab, text="Programador de Alarmas")
    
    # --- PESTAÑA 2: BLOC DE NOTAS ---
    editor_tab = ttk.Frame(notebook)
    notebook.add(editor_tab, text="Bloc de Notas")
    
    # --- PESTAÑA 3: MONITOR DEL SISTEMA (DEFINICIÓN ÚNICA) ---
    monitor_tab = ttk.Frame(notebook)
    notebook.add(monitor_tab, text="Monitor del Sistema", padding=4)
    
    # --- PESTAÑA 4: WEB SCRAPING ---
    scraping_tab = ttk.Frame(notebook)
    notebook.add(scraping_tab, text="Web Scraping")
    
    # --- PESTAÑA 5: JUEGOS ---
    games_tab = ttk.Frame(notebook)
    notebook.add(games_tab, text="Juegos 🎲")
    
    # --- PESTAÑA 6: MÚSICA (NUEVO) ---
    music_tab = ttk.Frame(notebook)
    notebook.add(music_tab, text="Música 🎵")

    # --- PESTAÑA 7: CHAT LOCAL (NUEVO) ---
    chat_tab = ttk.Frame(notebook)
    notebook.add(chat_tab, text="Chat Local 💬")
    
    # --- PESTAÑA 8: CORREO (NUEVO) ---
    email_tab = ttk.Frame(notebook)
    notebook.add(email_tab, text="Correo 📧")
    # ---------------------------------------------
    
    
    # ===============================================
    # FUNCIÓN PARA MOSTRAR EL SELECTOR DE ALARMA FLOTANTE
    # ===============================================
    def mostrar_selector_alarma_flotante(treeview_alarmas, alarma_id=None, data=None):
        """
        Crea y muestra la interfaz de selección de hora flotante.
        Si se proporciona alarma_id y data, funciona en modo MODIFICACIÓN.
        """
        
        is_modifying = alarma_id is not None
        
        popup = tk.Toplevel(root)
        popup.title("Modificar Alarma" if is_modifying else "Añadir Alarma")
        popup.geometry("450x300") # TAMAÑO AJUSTADO PARA VISIBILIDAD
        popup.resizable(False, False)
        popup.transient(root) 
        
        # CORRECCIÓN CLAVE: Retrasar grab_set para evitar 'grab failed: window not viewable'
        popup.after(10, popup.grab_set)
        
        # Variables de entrada (Carga de datos si es modo modificación)
        initial_hora = data['time'].strftime("%H") if is_modifying else datetime.datetime.now().strftime("%H")
        initial_minuto = data['time'].strftime("%M") if is_modifying else datetime.datetime.now().strftime("%M")
        initial_tarea = data['message'] if is_modifying else ""
        initial_sound_file = data['sound_file'] if is_modifying else config.ALERTA_SOUND_FILE
        
        # Inicializar con valores cargados o por defecto
        hora_var = tk.StringVar(value=initial_hora)
        minuto_var = tk.StringVar(value=initial_minuto)
        tarea_var = tk.StringVar(value=initial_tarea)
        
        # --- Configuración del Label de Sonido ---
        config.ALERTA_SOUND_FILE = initial_sound_file # Seteamos la global para la función seleccionar_archivo_alarma
        initial_sound_text = os.path.basename(config.ALERTA_SOUND_FILE) if config.ALERTA_SOUND_FILE else "[No seleccionado]"
        
        main_frame = ttk.Frame(popup, padding="15")
        main_frame.pack(fill='both', expand=True)
        
        # Grid para el layout
        main_frame.columnconfigure(1, weight=1)
        main_frame.columnconfigure(2, weight=1)
        
        # --- SECCIÓN HORA Y MINUTO ---
        tk.Label(main_frame, text="Hora (HH):").grid(row=0, column=0, pady=5, sticky='w')
        tk.Label(main_frame, text="Minuto (MM):").grid(row=0, column=2, pady=5, sticky='w')

        horas = [f"{h:02d}" for h in range(24)]
        minutos = [f"{m:02d}" for m in range(60)]
        
        hora_cb = ttk.Combobox(main_frame, values=horas, textvariable=hora_var, width=5, state="readonly")
        minuto_cb = ttk.Combobox(main_frame, values=minutos, textvariable=minuto_var, width=5, state="readonly")
        
        hora_cb.grid(row=1, column=0, padx=(5, 10), sticky='ew')
        minuto_cb.grid(row=1, column=2, padx=(10, 5), sticky='ew')
        
        # --- SECCIÓN SONIDO ---
        tk.Label(main_frame, text="Sonido:", font=('Helvetica', 9, 'bold')).grid(row=2, column=0, pady=(10, 5), sticky='w')
        
        label_archivo_seleccionado = tk.Label(main_frame, text=initial_sound_text, anchor='w')
        label_archivo_seleccionado.grid(row=4, column=0, columnspan=3, padx=5, pady=(0, 0), sticky='ew')

        
        # Botón para abrir el diálogo de selección de archivo
        ttk.Button(
            main_frame, 
            text="Seleccionar Audio (.wav/.mp3)", 
            command=lambda: system_utils.seleccionar_archivo_alarma(root, label_archivo_seleccionado)
        ).grid(row=3, column=0, columnspan=3, padx=5, pady=(5, 5), sticky='ew')
        

        # --- SECCIÓN MENSAJE ---
        tk.Label(main_frame, text="Mensaje/Tarea:").grid(row=5, column=0, columnspan=3, pady=(10, 5), sticky='w')
        tarea_entry = ttk.Entry(main_frame, textvariable=tarea_var, width=35)
        tarea_entry.grid(row=6, column=0, columnspan=3, pady=5, sticky='ew')
        
        # Frame para botones de control (OK/CANCEL)
        button_frame = ttk.Frame(main_frame)
        button_frame.grid(row=7, column=0, columnspan=3, pady=(15, 0), sticky='e')
        
        # --- Lógica de Comando ---
        if is_modifying:
            action_command = lambda: system_utils.modificar_alarma_existente(
                root, alarma_id, hora_var.get(), minuto_var.get(), tarea_var.get(), treeview_alarmas, popup, config.ALERTA_SOUND_FILE
            )
            action_text = "💾 Guardar Cambios"
        else:
            action_command = lambda: system_utils.agregar_alarma(
                root, hora_var.get(), minuto_var.get(), tarea_var.get(), treeview_alarmas, popup, config.ALERTA_SOUND_FILE
            )
            action_text = "➕ Añadir"
            
        # Botón OK (Programar/Modificar)
        ttk.Button(
            button_frame,
            text=action_text,
            width=18,
            command=action_command
        ).pack(side=tk.LEFT, padx=5)
        
        # Botón Cancelar
        ttk.Button(
            button_frame,
            text="Cancelar",
            width=10,
            command=popup.destroy
        ).pack(side=tk.LEFT)


    # ===============================================
    # CONTENIDO DE LA SOLAPA DE ALARMA
    # ===============================================

    system_utils.inicializar_chat()
    
    main_alarm_frame = tk.Frame(alarma_tab)
    main_alarm_frame.pack(fill="both", expand=True)
    
    # --- Lista de Alarmas (Treeview) ---
    columns = ('ID', 'Hora', 'Tarea', 'Estado', 'Fecha')
    treeview_alarmas = ttk.Treeview(main_alarm_frame, columns=columns, show='headings')
    
    for col in columns:
        treeview_alarmas.heading(col, text=col, anchor=tk.W)
        
    treeview_alarmas.column('ID', width=40)
    treeview_alarmas.column('Hora', width=40)
    treeview_alarmas.column('Estado', width=70, anchor=tk.CENTER)
    treeview_alarmas.column('Tarea', minwidth=150, stretch=tk.YES)
    treeview_alarmas.column('Fecha', width=80)
    treeview_alarmas.pack(fill='both', expand=True, padx=10, pady=10)
    
    # [NUEVO] Llamar a cargar alarmas DESPUÉS de crear el Treeview
    system_utils.cargar_alarmas(treeview_alarmas, root) 
    
    # --- Evento de Doble Clic para Modificar (CORREGIDO) ---
    def handle_double_click(event):
        abrir_editor_alarma(event, treeview_alarmas)
        
    treeview_alarmas.bind('<Double-1>', handle_double_click)
    
    # --- Panel de Control de Alarmas (Parte inferior) ---
    control_frame = tk.LabelFrame(main_alarm_frame, text="Control", padx=15, pady=15)
    control_frame.pack(fill='x', padx=10, pady=(0, 10))
    
    # Botones principales
    ttk.Button(
        control_frame, 
        text="➕ Programar Nueva Alarma",
        command=lambda: mostrar_selector_alarma_flotante(treeview_alarmas) # Llama a la función que abre el popup
    ).pack(side=tk.LEFT, padx=10)
    
    # Botón Modificar (CORREGIDO: usa la función auxiliar)
    ttk.Button(
        control_frame, 
        text="✏️ Modificar Seleccionada",
        command=lambda: abrir_editor_alarma(None, treeview_alarmas)
    ).pack(side=tk.LEFT, padx=10)
    
    ttk.Button(
        control_frame, 
        text="✅ Activar/Desactivar Seleccionada",
        command=lambda: system_utils.toggle_alarma(treeview_alarmas)
    ).pack(side=tk.LEFT, padx=10)
    
    ttk.Button(
        control_frame, 
        text="🗑️ Eliminar Seleccionada",
        command=lambda: system_utils.eliminar_alarma(treeview_alarmas)
    ).pack(side=tk.LEFT, padx=10)

    # NUEVO: Separador
    ttk.Separator(control_frame, orient='vertical').pack(side=tk.LEFT, padx=10, fill='y')

    # NUEVO: Control de Sonido
    ttk.Button(
        control_frame, 
        text="🔇 Detener Sonido Alarma", 
        command=system_utils.detener_sonido_alarma
    ).pack(side=tk.LEFT, padx=10)

    tk.Label(control_frame, text="Volumen:").pack(side=tk.LEFT)
    
    volumen_scale = ttk.Scale(
        control_frame, 
        from_=0, to=100, 
        orient='horizontal',
        length=100,
        command=system_utils.ajustar_volumen_alarma
    )
    volumen_scale.set(config.alarma_volumen * 100) 
    volumen_scale.pack(side=tk.LEFT, padx=5)


    # ===============================================
    # CONTENIDO DE LA SOLAPA BLOC DE NOTAS
    # ===============================================
    
    # Frame para los botones de control
    control_frame_editor = tk.Frame(editor_tab)
    control_frame_editor.pack(pady=5)
    
    # Botones del Editor
    ttk.Button(control_frame_editor, text="Nuevo", command=system_utils.nuevo_archivo).pack(side=tk.LEFT, padx=5)
    ttk.Button(control_frame_editor, text="Abrir TXT...", command=lambda: system_utils.abrir_archivo(root)).pack(side=tk.LEFT, padx=5)
    ttk.Button(control_frame_editor, text="Guardar TXT", command=lambda: system_utils.guardar_texto(root)).pack(side=tk.LEFT, padx=15) 
    ttk.Button(
        control_frame_editor, 
        text="📂 Abrir Carpeta Notas", # CAMBIO DE ETIQUETA
        command=system_utils.abrir_carpeta_notas # LLAMA A LA FUNCIÓN DE NOTAS
    ).pack(side=tk.LEFT, padx=5)
    
    # Widget de Texto
    editor_text_widget = tk.Text(editor_tab, wrap='word', undo=True, font=('Courier New', 10))
    editor_text_widget.pack(fill="both", expand=True, padx=5, pady=5)
    
    # Asignar a la variable global
    config.editor_texto = editor_text_widget


    # --- Creación de la Barra de Estado ---
    barra_estado = tk.Label(root, text="Barra de estado", bg="lightgray", anchor="w")
    barra_estado.grid(row=1, column=0, columnspan=3, sticky="ew")

    label_1 = tk.Label(barra_estado, text="Estado Backup", bg="green", anchor="w", width=20)
    label_2 = tk.Label(barra_estado, text="Registro: Detenido", bg="gray", anchor="w", width=20) 
    label_fecha_hora = tk.Label(barra_estado, text="Hilo fecha-hora", font=("Helvetica", 14), bd=1, fg="blue", relief="sunken", anchor="w", width=20, padx=10)

    label_1.pack(side="left", fill="x", expand=True)
    label_2.pack(side="left", fill="x", expand=True)
    label_fecha_hora.pack(side="right", fill="x", expand=True)
    
    # Asignar los labels a la configuración global para que los hilos los encuentren
    config.label_1 = label_1
    config.label_2 = label_2
    config.label_fecha_hora = label_fecha_hora
    
    # --- Inicialización del Panel Lateral ---
    monitor_manager.crear_panel_lateral(frame_izquierdo, root) 

    # --- Creación del Menú Superior (SE MODIFICA) ---
    menu_bar = Menu(root)
    file_menu = Menu(menu_bar, tearoff=0); file_menu.add_command(label="Salir", command=on_closing)
    
    # MODIFICADO: Se elimina el comando de YouTube
    launch_menu = Menu(menu_bar, tearoff=0); 
    launch_menu.add_command(label="ChatGPT", command=lambda: system_utils.lanzar_url("https://chat.openai.com")) 
    launch_menu.add_command(label="Apuntes PSP", command=lambda: system_utils.lanzar_url("https://apuntes-informatica.ieslamar.org/psp/proyecto")) 
    launch_menu.add_command(label="Solitario Google", command=lambda: system_utils.lanzar_url("https://www.google.com/logos/fnbx/solitaire/standalone.html")) 
    launch_menu.add_command(label="Aules FP", command=lambda: system_utils.lanzar_url("https://aules.edu.gva.es/fp/my/")) 
    
    # MODIFICADO: Se ELIMINA el comando del juego thread-safe de este menú
    tools_menu = Menu(menu_bar, tearoff=0); 
    tools_menu.add_command(label="Ejecutar Copia de Seguridad", command=lambda: system_utils.ejecutar_script_en_hilo(label_1, root))
    tools_menu.add_command(label="Iniciar/Detener Registro CSV", command=lambda: system_utils.manejar_registro_csv(label_2)) 
    # tools_menu.add_command(label="Simular Juego (Thread-Safe) 🐫", command=lambda: system_utils.simular_juego_camellos(root)) # ELIMINADO
    tools_menu.add_command(label="📂 Abrir Carpeta Scraping", command=lambda: system_utils.abrir_carpeta_especifica(config.SCRAPING_FOLDER, "Scraping")) 
    tools_menu.add_command(label="📂 Abrir Config Scraping", command=lambda: system_utils.abrir_carpeta_especifica(config.SCRAPING_CONFIG_FOLDER, "Config Scraping")) 

    menu_bar.add_cascade(label="Archivo", menu=file_menu)
    menu_bar.add_cascade(label="Herramientas", menu=tools_menu)
    menu_bar.add_cascade(label="Lanzadores", menu=launch_menu) 
    menu_bar.add_cascade(label="Ayuda", menu=Menu(menu_bar, tearoff=0)) 
    root.config(menu=menu_bar)


    # ===============================================
    # Solapa de Monitor del Sistema (CONTENIDO ÚNICO)
    # ===============================================
    
    # Reutilizamos monitor_tab creado arriba para evitar la duplicidad
    main_monitor_frame = tk.Frame(monitor_tab)
    main_monitor_frame.pack(fill=tk.BOTH, expand=True)
    main_monitor_frame.rowconfigure(0, weight=3) 
    main_monitor_frame.rowconfigure(1, weight=1) 
    main_monitor_frame.columnconfigure(0, weight=1)

    # --- Fila 0: Gráficos ---
    plot_frame = tk.Frame(main_monitor_frame)
    plot_frame.grid(row=0, column=0, sticky="nsew", padx=5, pady=5)

    fig = plt.figure(figsize=(10, 8))
    gs = fig.add_gridspec(2, 3, hspace=0.6, wspace=0.3) 

    ax_cpu = fig.add_subplot(gs[0, 0])      
    ax_mem = fig.add_subplot(gs[0, 1])      
    ax_cores = fig.add_subplot(gs[0, 2])    
    ax_net = fig.add_subplot(gs[1, 0])      
    ax_pie = fig.add_subplot(gs[1, 1], aspect="equal") 
    ax_disk_io = fig.add_subplot(gs[1, 2]) 

    plt.style.use('ggplot')

    canvas = FigureCanvasTkAgg(fig, master=plot_frame)
    canvas_widget = canvas.get_tk_widget()
    canvas_widget.pack(side=tk.TOP, fill=tk.BOTH, expand=True)

    # --- Fila 1: Log y Procesos ---
    bottom_frame = tk.Frame(main_monitor_frame)
    bottom_frame.grid(row=1, column=0, sticky="nsew", padx=5, pady=5)
    bottom_frame.columnconfigure(0, weight=1) 
    bottom_frame.columnconfigure(1, weight=1) 

    # 1. Log de Eventos (Sección Izquierda)
    log_frame = tk.LabelFrame(bottom_frame, text="Log de Eventos del Sistema")
    log_frame.grid(row=0, column=0, sticky="nsew", padx=5, pady=5)
    log_frame.rowconfigure(0, weight=1)
    log_frame.columnconfigure(0, weight=1)

    config.system_log = ScrolledText(log_frame, height=8, font=("Courier", 8), bg="#2c3e50", fg="lightgray")
    config.system_log.grid(row=0, column=0, sticky="nsew")

    # 2. Treeview de Procesos (Sección Derecha)
    process_frame = tk.LabelFrame(bottom_frame, text=f"Top {10} Procesos (Ordenados por CPU)")
    process_frame.grid(row=0, column=1, sticky="nsew", padx=5, pady=5)
    process_frame.columnconfigure(0, weight=1)
    process_frame.rowconfigure(0, weight=1)

    columns = ('PID', 'CPU', 'MEM', 'HILOS', 'NOMBRE')
    treeview_processes = ttk.Treeview(process_frame, columns=columns, show='headings')

    for col in columns:
        treeview_processes.heading(col, text=col, anchor=tk.W)
        treeview_processes.column(col, width=50, anchor=tk.W) 
        
    treeview_processes.column('PID', width=50)
    treeview_processes.column('CPU', width=60)
    treeview_processes.column('MEM', width=70)
    treeview_processes.column('HILOS', width=60)
    treeview_processes.column('NOMBRE', minwidth=150, stretch=tk.YES)

    treeview_processes.grid(row=0, column=0, sticky="nsew")

    kill_button = tk.Button(
        process_frame, 
        text="Terminar Proceso Seleccionado (⚠️ DANGER)", 
        command=lambda: monitor_manager.terminar_proceso(treeview_processes),
        bg='darkred', 
        fg='white',
        font=('Helvetica', 10, 'bold')
    )
    kill_button.grid(row=1, column=0, sticky="ew", pady=(5,0))
    
    # ===============================================
    # Solapa de Web Scraping (Implementación completa y estética)
    # ===============================================
    
    # Marco principal para el scraping
    main_scraping_frame = ttk.Frame(scraping_tab, padding="15")
    main_scraping_frame.pack(fill=tk.BOTH, expand=True)
    
    main_scraping_frame.columnconfigure(0, weight=1)
    main_scraping_frame.columnconfigure(1, weight=0)
    main_scraping_frame.rowconfigure(5, weight=1) # Fila 5 es el Text Output
    
    # --- Fila 0 & 1: URL, Opciones y Configuración Personalizada ---
    
    # 1. Título y Carga de Configuración
    header_frame = ttk.Frame(main_scraping_frame)
    header_frame.grid(row=0, column=0, columnspan=2, sticky='ew', pady=(0, 5))
    header_frame.columnconfigure(0, weight=1)
    
    # CORRECCIÓN DE ORTOGRAFÍA: "Scrappear" -> "Scrapear"
    ttk.Label(header_frame, text="🌐 URL a Scrapear:", font=('Helvetica', 10, 'bold')).pack(side=tk.LEFT, padx=(0, 5)) 
    
    config.scraping_config_file_label = ttk.Label(header_frame, text="Config: [Ninguna]", foreground='blue')
    config.scraping_config_file_label.pack(side=tk.RIGHT, padx=5)

    ttk.Button(
        header_frame, 
        text="⚙️ Cargar Config. (.json)", 
        command=lambda: system_utils.abrir_archivo_scraping_config(root)
    ).pack(side=tk.RIGHT)
    
    # 2. Entrada de URL
    url_var = tk.StringVar(value="https://www.example.com") 
    url_entry = ttk.Entry(main_scraping_frame, textvariable=url_var, width=80)
    url_entry.grid(row=1, column=0, columnspan=2, sticky='ew', pady=(0, 10))
    
    # ASIGNAR A CONFIG para que system_utils pueda actualizarlo
    config.scraping_url_input = url_var
    
    # --- Fila 2: Controles Detallados ---
    control_frame_row2 = ttk.Frame(main_scraping_frame)
    control_frame_row2.grid(row=2, column=0, columnspan=2, sticky='ew', pady=5)
    control_frame_row2.columnconfigure(2, weight=1) 
    
    # Opciones de Extracción
    ttk.Label(control_frame_row2, text="Tipo de Extracción:", font=('Helvetica', 9, 'bold')).grid(row=0, column=0, sticky='w', padx=(0, 5))
    tipo_extraccion_var = tk.StringVar(value="Título y Metadatos")
    extracciones = [
        "Título y Metadatos", 
        "Primeros Párrafos", 
        "Enlaces (Links)", 
        "Imágenes (URLs)",
        "Tablas (Estructura Básica)",
        "Portátiles Gamer (Enlace + Precio)", # NUEVA OPCIÓN COMBINADA
        "-> Texto Específico (CSS Selector)", 
        "-> Atributo Específico (CSS Selector + Attr)" 
    ]
    
    extraccion_combobox = ttk.Combobox(
        control_frame_row2, 
        values=extracciones, 
        textvariable=tipo_extraccion_var, 
        state="readonly",
        width=30
    )
    extraccion_combobox.grid(row=0, column=1, sticky='w', padx=10)
    
    # Selector CSS
    ttk.Label(control_frame_row2, text="Selector CSS/Tag (avanzado):").grid(row=0, column=3, sticky='w', padx=(10, 5))
    config.scraping_selector_input = ttk.Entry(control_frame_row2, width=40)
    config.scraping_selector_input.grid(row=0, column=4, sticky='ew', padx=(0, 10))
    
    # Atributo
    ttk.Label(control_frame_row2, text="Atributo (ej: href/src):").grid(row=0, column=5, sticky='w', padx=(10, 5))
    config.scraping_attr_input = ttk.Entry(control_frame_row2, width=15)
    config.scraping_attr_input.grid(row=0, column=6, sticky='ew')
    
    # --- Fila 3: Ejecución y Control ---
    control_execution_frame = ttk.Frame(main_scraping_frame)
    control_execution_frame.grid(row=3, column=0, columnspan=2, sticky='ew', pady=(10, 5))
    control_execution_frame.columnconfigure(0, weight=1)
    
    # Botón Scrappear
    btn_scrap = ttk.Button(
        control_execution_frame, 
        text="🚀 Iniciar Scrapear",
        command=lambda: monitor_manager.scrappear_pagina_principal(
            url_var.get(), 
            tipo_extraccion_var.get(), 
            config.scraping_output_text, 
            config.scraping_progress_bar, 
            config.scraping_selector_input.get(), 
            config.scraping_attr_input.get(),
            config.scraping_config_data,
            root
        )
    )
    btn_scrap.pack(side=tk.LEFT, padx=(0, 10))

    # Barra de Progreso
    config.scraping_progress_bar = ttk.Progressbar(control_execution_frame, orient="horizontal", mode="indeterminate")
    config.scraping_progress_bar.pack(side=tk.LEFT, fill='x', expand=True, padx=(0, 10))
    
    # Botón Detener
    ttk.Button(
        control_execution_frame,
        text="🛑 Detener",
        command=lambda: system_utils.detener_scraping() 
    ).pack(side=tk.LEFT)
    
    # --- Fila 4 & 5: Área de Resultado y Guardar ---
    
    ttk.Label(main_scraping_frame, text="📊 Resultado de la Extracción:", font=('Helvetica', 10, 'bold')).grid(row=4, column=0, columnspan=2, sticky='w', pady=(10, 5))
    
    # Widget de Texto para la salida
    config.scraping_output_text = ScrolledText(main_scraping_frame, wrap='word', font=('Courier New', 9), height=18, bg='#f9f9f9')
    config.scraping_output_text.grid(row=5, column=0, columnspan=2, sticky='nsew', pady=(0, 10))
    
    # Botón Guardar Resultado
    ttk.Button(
        main_scraping_frame, 
        text="💾 Guardar Resultado en /data/scraping", # CORRECCIÓN DE RUTA
        command=lambda: system_utils.guardar_scraping(config.scraping_output_text.get("1.0", tk.END), root)
    ).grid(row=6, column=0, columnspan=2, sticky='ew')
    
    
    # ===============================================
    # CONTENIDO DE LA SOLAPA DE JUEGOS
    # ===============================================
    
    main_games_frame = ttk.Frame(games_tab, padding="20")
    main_games_frame.pack(fill=tk.BOTH, expand=True)

    ttk.Label(
        main_games_frame, 
        text="Simulaciones de Entretenimiento (Thread-Safe)", 
        font=('Helvetica', 14, 'bold')
    ).pack(pady=15)

    ttk.Separator(main_games_frame, orient='horizontal').pack(fill='x', pady=5)
    
    # Botón de juego de camellos
    ttk.Button(
        main_games_frame, 
        text="🏆 Iniciar Carrera de Camellos (Thread-Safe)",
        command=lambda: system_utils.simular_juego_camellos(root),
        cursor="hand2"
    ).pack(pady=10)
    
    ttk.Label(
        main_games_frame, 
        text="Este juego se ejecuta en una ventana 'Toplevel' para garantizar la seguridad del hilo principal.", 
        font=('Helvetica', 9, 'italic'),
        foreground='gray'
    ).pack(pady=5)
    
    # ===============================================
    # CONTENIDO DE LA SOLAPA DE MÚSICA (NUEVO)
    # ===============================================
    
    music_frame = ttk.Frame(music_tab, padding="20")
    music_frame.pack(fill=tk.BOTH, expand=True)

    ttk.Label(
        music_frame, 
        text="Reproductor de Audio Local (.mp3 / .wav)", 
        font=('Helvetica', 14, 'bold')
    ).pack(pady=15)

    # 1. Archivo Seleccionado
    ttk.Label(music_frame, text="Archivo Seleccionado:").pack(pady=(10, 5))
    label_music_file = ttk.Label(music_frame, text="[Ningún archivo cargado]", anchor='center', foreground='blue')
    label_music_file.pack(fill='x', padx=50)

    # 2. Botón Seleccionar
    ttk.Button(
        music_frame, 
        text="📂 Seleccionar MP3/WAV",
        command=lambda: system_utils.seleccionar_mp3(root, label_music_file)
    ).pack(pady=10, padx=50, fill='x')

    ttk.Separator(music_frame, orient='horizontal').pack(fill='x', pady=10, padx=50)

    # 3. Controles de Reproducción
    control_music_frame = ttk.Frame(music_frame)
    control_music_frame.pack(pady=10)

    ttk.Button(
        control_music_frame, 
        text="▶️ Reproducir",
        command=lambda: system_utils.reproducir_mp3(root)
    ).pack(side=tk.LEFT, padx=10)

    ttk.Button(
        control_music_frame, 
        text="⏹️ Detener",
        command=system_utils.detener_mp3
    ).pack(side=tk.LEFT, padx=10)

    # 4. Control de Volumen
    ttk.Label(music_frame, text="Volumen:").pack(pady=(15, 5))

    volumen_scale_music = ttk.Scale(
        music_frame, 
        from_=0, to=100, 
        orient='horizontal',
        length=200,
        command=system_utils.ajustar_volumen_mp3 # Reutilizamos la función que ajusta Pygame Mixer
    )
    volumen_scale_music.set(config.alarma_volumen * 100) 
    volumen_scale_music.pack(pady=5)

## ===============================================
    # CONTENIDO DE LA SOLAPA DE CHAT LOCAL
    # ===============================================
    system_utils.inicializar_chat()
    
    chat_frame = ttk.Frame(chat_tab, padding="25")
    chat_frame.pack(fill=tk.BOTH, expand=True)
    
    # Nombre de la aplicación en grande (Marko One)
    tk.Label(
        chat_frame, 
        text="Chat Multipípedo", 
        font=('Marko One', 24), 
        fg="#2C3E50"
    ).pack(pady=(0, 10))
    
    # Marco para la configuración del usuario
    user_config_frame = ttk.Frame(chat_frame)
    user_config_frame.pack(fill=tk.X, pady=(0, 15))
    
    # Variable para guardar el Alias
    alias_var = tk.StringVar(value=f"Instancia_{config.INSTANCE_ID}")
    
    # Títulos usando Trirong y texto normal en Nunito
    tk.Label(user_config_frame, text="Tu Alias:", font=('Trirong', 12, 'bold'), fg="#34495E").pack(side=tk.LEFT, padx=(0, 10))
    ttk.Entry(user_config_frame, textvariable=alias_var, font=('Nunito', 11), width=20).pack(side=tk.LEFT, ipady=3)
    
    tk.Label(user_config_frame, text=f"(ID Sistema: {config.INSTANCE_ID})", font=('Nunito', 10, 'italic'), fg="#7F8C8D").pack(side=tk.RIGHT)
    
    # Área de texto del chat (Texto normal en Nunito)
    chat_text_area = ScrolledText(
        chat_frame, 
        wrap='word', 
        state=tk.DISABLED, 
        font=('Nunito', 11), 
        bg='#F8F9FA', 
        fg='#2C3E50',
        bd=1,
        relief="solid",
        padx=15,
        pady=15
    )
    chat_text_area.pack(fill=tk.BOTH, expand=True, pady=(0, 20))
    
    chat_input_frame = ttk.Frame(chat_frame)
    chat_input_frame.pack(fill=tk.X)
    
    # Título secundario en Trirong
    tk.Label(chat_input_frame, text="Mensaje:", font=('Trirong', 12, 'bold'), fg="#34495E").pack(side=tk.LEFT, padx=(0, 10))
    
    chat_entry = ttk.Entry(chat_input_frame, font=('Nunito', 12))
    chat_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 10), ipady=5)
    
    # Vincular Enter y el Botón pasando el alias_var
    chat_entry.bind("<Return>", lambda event: system_utils.enviar_mensaje_chat(chat_entry, alias_var))
    
    ttk.Button(
        chat_input_frame, 
        text="Enviar 🚀", 
        command=lambda: system_utils.enviar_mensaje_chat(chat_entry, alias_var)
    ).pack(side=tk.RIGHT, ipady=4)
    
    threading.Thread(target=lambda: system_utils.monitor_chat_file(chat_text_area, root), daemon=True).start()

# ===============================================
    # CONTENIDO DE LA SOLAPA DE CORREO CLIENTE
    # ===============================================
    mail_main_container = ttk.Frame(email_tab)
    mail_main_container.pack(fill=tk.BOTH, expand=True)

    # Variables de credenciales globales para esta pestaña
    email_user_var = tk.StringVar()
    email_pass_var = tk.StringVar()

    # ---------------------------------------------------------
    # PANTALLA 1: LOGIN (Visible por defecto)
    # ---------------------------------------------------------
    login_frame = ttk.Frame(mail_main_container, padding="40")
    login_frame.pack(fill=tk.BOTH, expand=True)

    tk.Label(
        login_frame, 
        text="Gestor de Correo Interno", 
        font=('Marko One', 22), 
        fg="#2C3E50"
    ).pack(pady=(40, 30))
    
    form_frame = ttk.Frame(login_frame)
    form_frame.pack()

    tk.Label(form_frame, text="Email:", font=('Trirong', 12, 'bold')).grid(row=0, column=0, padx=10, pady=15, sticky="e")
    ttk.Entry(form_frame, textvariable=email_user_var, width=35, font=('Nunito', 11)).grid(row=0, column=1, padx=10, pady=15, ipady=5)

    tk.Label(form_frame, text="Contraseña:", font=('Trirong', 12, 'bold')).grid(row=1, column=0, padx=10, pady=15, sticky="e")
    ttk.Entry(form_frame, textvariable=email_pass_var, show="•", width=35, font=('Nunito', 11)).grid(row=1, column=1, padx=10, pady=15, ipady=5)

    # ---------------------------------------------------------
    # PANTALLA 2: BANDEJA DE CORREO (Oculta hasta iniciar sesión)
    # ---------------------------------------------------------
    mail_content_frame = ttk.Frame(mail_main_container, padding="15")
    
    # Dividir pantalla (Enviar vs Recibir)
    paned_window = ttk.PanedWindow(mail_content_frame, orient=tk.HORIZONTAL)
    paned_window.pack(fill=tk.BOTH, expand=True)
    
    # --- Bandeja de Salida (SMTP) ---
    send_frame = tk.LabelFrame(
        paned_window, 
        text=" Bandeja de Salida (SMTP) ", 
        font=('Trirong', 11, 'bold'),
        fg="#2980B9",
        padx=15, 
        pady=15
    )
    paned_window.add(send_frame, weight=1)
    
    tk.Label(send_frame, text="Destinatario:", font=('Trirong', 10, 'bold')).pack(anchor='w', pady=(0, 2))
    to_var = tk.StringVar()
    ttk.Entry(send_frame, textvariable=to_var, font=('Nunito', 11)).pack(fill=tk.X, pady=(0, 10), ipady=3)
    
    tk.Label(send_frame, text="Asunto:", font=('Trirong', 10, 'bold')).pack(anchor='w', pady=(0, 2))
    subject_var = tk.StringVar()
    ttk.Entry(send_frame, textvariable=subject_var, font=('Nunito', 11)).pack(fill=tk.X, pady=(0, 10), ipady=3)
    
    tk.Label(send_frame, text="Mensaje:", font=('Trirong', 10, 'bold')).pack(anchor='w', pady=(0, 2))
    body_text = tk.Text(send_frame, height=8, font=('Nunito', 11), bd=1, relief="solid")
    body_text.pack(fill=tk.BOTH, expand=True, pady=(0, 15))
    
    ttk.Button(
        send_frame, 
        text="📨 Enviar Email", 
        command=lambda: system_utils.enviar_correo(
            email_user_var.get(), email_pass_var.get(), to_var.get(), subject_var.get(), body_text.get("1.0", tk.END), root
        )
    ).pack(ipady=3)
    
    # --- Bandeja de Entrada (IMAP) ---
    recv_frame = tk.LabelFrame(
        paned_window, 
        text=" Bandeja de Entrada (IMAP) ", 
        font=('Trirong', 11, 'bold'),
        fg="#27AE60",
        padx=15, 
        pady=15
    )
    paned_window.add(recv_frame, weight=1)
    
    style = ttk.Style()
    style.configure("Treeview", font=('Nunito', 10), rowheight=28)
    style.configure("Treeview.Heading", font=('Trirong', 10, 'bold'))

    cols = ('ID', 'De', 'Asunto')
    treeview_emails = ttk.Treeview(recv_frame, columns=cols, show='headings')
    treeview_emails.heading('ID', text='ID')
    treeview_emails.heading('De', text='Remitente')
    treeview_emails.heading('Asunto', text='Asunto')
    treeview_emails.column('ID', width=50, anchor='center')
    treeview_emails.column('De', width=160)
    treeview_emails.column('Asunto', width=220)
    treeview_emails.pack(fill=tk.BOTH, expand=True, pady=(0, 15))
    
    ttk.Button(
        recv_frame, 
        text="📥 Actualizar Bandeja", 
        command=lambda: system_utils.cargar_correos(
            email_user_var.get(), email_pass_var.get(), treeview_emails, root
        )
    ).pack(ipady=3)

    # ---------------------------------------------------------
    # BOTÓN DE INICIO DE SESIÓN (Llama a la validación)
    # ---------------------------------------------------------
    ttk.Button(
        form_frame, 
        text="🔑 Autenticar e Iniciar", 
        command=lambda: system_utils.comprobar_login_correo(
            email_user_var.get(), email_pass_var.get(), login_frame, mail_content_frame, root
        )
    ).grid(row=2, column=0, columnspan=2, pady=25, ipady=5)
    
    # --- Iniciar Hilos ---
    system_utils.log_event("Monitor de sistema iniciado. Esperando la primera lectura de métricas...")
    monitor_manager.iniciar_monitor_sistema(fig, canvas, ax_cpu, ax_mem, ax_net, ax_cores, ax_pie, ax_disk_io, treeview_processes, root)
    
    update_thread = threading.Thread(target=lambda: system_utils.update_time(label_fecha_hora, root))
    update_thread.daemon = True
    update_thread.start()