import customtkinter as ctk
from core.process_runner import ProcessRunner
from core import reporting
import threading
import subprocess # To check Tor status

class AnonymityFrame(ctk.CTkFrame):
    def __init__(self, master, heading_font=None, text_font=None):
        super().__init__(master)
        self.heading_font = heading_font if heading_font else ctk.CTkFont(size=18, weight="bold")
        self.text_font = text_font if text_font else ctk.CTkFont(size=12)
        self.monospace_font = ctk.CTkFont(family="Fira Code", size=12) # For output textboxes
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(1, weight=1)

        title = ctk.CTkLabel(self, text="Capa de Anonimato (Tor)", font=self.heading_font)
        title.grid(row=0, column=0, padx=20, pady=(20, 10), sticky="ew")

        self.tab_view = ctk.CTkTabview(self)
        self.tab_view.grid(row=1, column=0, padx=20, pady=10, sticky="nsew")

        self.tab_view.add("Estado de Tor")
        self.tab_view.add("Torsocks/Proxychains")

        self.tor_status_output_textbox = None
        self.torsocks_process_runner = None
        self.current_session_name = None

        self.setup_tor_status_tab()
        self.setup_proxy_tools_tab()

    def setup_tor_status_tab(self):
        tab = self.tab_view.tab("Estado de Tor")
        tab.grid_columnconfigure(0, weight=1)
        tab.grid_rowconfigure(2, weight=1)

        status_label = ctk.CTkLabel(tab, text="Verificar el estado del servicio Tor en tu sistema.")
        status_label.grid(row=0, column=0, padx=10, pady=10, sticky="ew")

        check_button = ctk.CTkButton(tab, text="Verificar Estado de Tor", command=self.check_tor_status)
        check_button.grid(row=1, column=0, padx=10, pady=10, sticky="ew")

        self.tor_status_output_textbox = ctk.CTkTextbox(tab, state="disabled", font=self.monospace_font)
        self.tor_status_output_textbox.grid(row=2, column=0, padx=10, pady=10, sticky="nsew")

    def check_tor_status(self):
        self.tor_status_output_textbox.configure(state="normal")
        self.tor_status_output_textbox.delete("1.0", "end")
        self.tor_status_output_textbox.insert("1.0", "Verificando el estado del servicio Tor...\n")
        self.tor_status_output_textbox.configure(state="disabled")

        def _run_check():
            try:
                # Check if tor service is running
                tor_service_status = subprocess.run(["systemctl", "is-active", "tor"], capture_output=True, text=True, check=False)
                output = ""
                if tor_service_status.returncode == 0:
                    output += "Servicio Tor: ACTIVO y funcionando.\n"
                    # Try to get Tor's current IP if running and torsocks is available
                    try:
                        tor_ip_check = subprocess.run(["torsocks", "curl", "ident.me"], capture_output=True, text=True, check=False)
                        if tor_ip_check.returncode == 0:
                            output += f"Tu IP a través de Tor (ident.me): {tor_ip_check.stdout.strip()}\n"
                        else:
                            output += f"No se pudo obtener la IP a través de Tor (torsocks error o no instalado): {tor_ip_check.stderr.strip()}\n"
                    except FileNotFoundError:
                        output += "Comando 'torsocks' no encontrado. No se puede verificar la IP de salida de Tor.\n"
                    except Exception as e:
                        output += f"Error al verificar la IP de Tor: {e}\n"
                else:
                    output += f"Servicio Tor: INACTIVO o no encontrado.\n{tor_service_status.stderr.strip()}\n"
                    output += "Asegúrate de que Tor esté instalado y el servicio 'tor' esté iniciado (ej: sudo systemctl start tor).\n"
            except FileNotFoundError:
                output = "Comando 'systemctl' no encontrado. No se puede verificar el estado del servicio Tor.\n" \
                         "Asegúrate de que 'systemd' esté disponible o verifica el estado de Tor manualmente.\n"
            except Exception as e:
                output = f"Error inesperado al verificar Tor: {e}\n"

            self.master.after(0, lambda: self._update_tor_status_output(output))

        threading.Thread(target=_run_check, daemon=True).start()

    def _update_tor_status_output(self, output):
        self.tor_status_output_textbox.configure(state="normal")
        self.tor_status_output_textbox.insert("end", output)
        self.tor_status_output_textbox.configure(state="disabled")

    def setup_proxy_tools_tab(self):
        tab = self.tab_view.tab("Torsocks/Proxychains")
        tab.grid_columnconfigure(0, weight=1)
        tab.grid_rowconfigure(6, weight=1)

        description_label = ctk.CTkLabel(tab, text="Ejecuta comandos a través de Tor usando 'torsocks' o 'proxychains'.\n" 
                                                 "Asegúrate de que Tor esté activo y que la herramienta seleccionada esté instalada.", justify="left", font=self.text_font)
        description_label.grid(row=0, column=0, padx=10, pady=10, sticky="ew")

        # Proxy Tool Selection
        self.proxy_tool_label = ctk.CTkLabel(tab, text="Herramienta de Proxy:")
        self.proxy_tool_label.grid(row=1, column=0, padx=5, pady=5, sticky="w")
        self.proxy_tool_option = ctk.CTkOptionMenu(tab, values=["torsocks", "proxychains4"]) # proxychains usually proxychains4
        self.proxy_tool_option.set("torsocks")
        self.proxy_tool_option.grid(row=1, column=0, padx=5, pady=5, sticky="ew")

        # Command to Execute
        self.command_label = ctk.CTkLabel(tab, text="Comando a ejecutar (ej: nmap -sT example.com):")
        self.command_label.grid(row=2, column=0, padx=5, pady=5, sticky="w")
        self.command_entry = ctk.CTkEntry(tab, placeholder_text="ej: nmap -sT example.com")
        self.command_entry.grid(row=3, column=0, padx=10, pady=5, sticky="ew")

        # Start/Stop Buttons
        buttons_frame = ctk.CTkFrame(tab)
        buttons_frame.grid(row=4, column=0, padx=10, pady=10, sticky="ew")
        buttons_frame.grid_columnconfigure(0, weight=1)
        buttons_frame.grid_columnconfigure(1, weight=1)

        self.proxy_start_button = ctk.CTkButton(buttons_frame, text="Ejecutar con Proxy", command=self.start_proxy_command)
        self.proxy_start_button.grid(row=0, column=0, padx=5, pady=10, sticky="ew")

        self.proxy_stop_button = ctk.CTkButton(buttons_frame, text="Detener Ejecución", command=self.stop_proxy_command, fg_color="red", state="disabled")
        self.proxy_stop_button.grid(row=0, column=1, padx=5, pady=10, sticky="ew")
        
        # ---- Output ----
        self.proxy_output_textbox = ctk.CTkTextbox(tab, state="disabled", font=self.monospace_font)
        self.proxy_output_textbox.grid(row=6, column=0, padx=10, pady=10, sticky="nsew")

    def start_proxy_command(self):
        proxy_tool = self.proxy_tool_option.get()
        command_str = self.command_entry.get()

        if not command_str:
            return

        self.proxy_start_button.configure(state="disabled")
        self.proxy_stop_button.configure(state="normal")
        
        self.current_session_name = reporting.create_session(f"{proxy_tool}_{command_str[:20]}") # Shorten session name

        full_command = [proxy_tool] + command_str.split()

        self.proxy_output_textbox.configure(state="normal")
        self.proxy_output_textbox.delete("1.0", "end")
        self.proxy_output_textbox.insert("1.0", f"--- Ejecutando comando con {proxy_tool} ---\nComando: {' '.join(full_command)}\n\n")
        self.proxy_output_textbox.configure(state="disabled")

        self.torsocks_process_runner = ProcessRunner(full_command, self.proxy_output_textbox)
        self.torsocks_process_runner.start()
        
        threading.Thread(target=self.wait_and_save_proxy_command, daemon=True).start()

    def stop_proxy_command(self):
        if self.torsocks_process_runner:
            self.torsocks_process_runner.stop()
            self.proxy_start_button.configure(state="normal")
            self.proxy_stop_button.configure(state="disabled")

    def wait_and_save_proxy_command(self):
        if self.torsocks_process_runner:
            self.torsocks_process_runner.thread.join()

        full_output = self.proxy_output_textbox.get("1.0", "end")
        reporting.log_tool_output(self.current_session_name, "Proxy Command Execution", full_output)
        
        self.master.after(0, self._reset_proxy_buttons)

    def _reset_proxy_buttons(self):
        self.proxy_start_button.configure(state="normal")
        self.proxy_stop_button.configure(state="disabled")
