import tkinter as tk
from tkinter import ttk
import math
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

class TabSearch:
    def __init__(self, notebook, tab_simulator):
        self.notebook = notebook
        self.tab_sim = tab_simulator
        self.frame = tk.Frame(notebook, width=280)
        self.frame.pack(side="left", fill="both", expand=True)
        self.frame.pack_propagate(False)

        self.frame_left = tk.Frame(self.frame, width=240)
        self.frame_left.pack(side="left", fill="y", padx=5, pady=5)
        self.frame_left.pack_propagate(False)
        self.frame_right = tk.Frame(self.frame)
        self.frame_right.pack(side="right", fill="both", expand=True, padx=5, pady=5)

        tk.Button(self.frame_left, text="Importar config", command=self.import_config).pack(pady=5)
        tk.Button(self.frame_left, text="Ejecutar búsqueda", command=self.run_search).pack(pady=5)

        self.label_m = tk.Label(self.frame_left, text="Masa: ??? kg", bg="white"); self.label_m.pack(pady=2, anchor="w")
        self.label_b = tk.Label(self.frame_left, text="b: ???", bg="white"); self.label_b.pack(pady=2, anchor="w")
        self.label_h0 = tk.Label(self.frame_left, text="h0: ??? m", bg="white"); self.label_h0.pack(pady=2, anchor="w")
        self.label_drag = tk.Label(self.frame_left, text="Drag: ???", bg="white"); self.label_drag.pack(pady=2, anchor="w")
        self.label_x_target = tk.Label(self.frame_left, text="X_target: ???", bg="white"); self.label_x_target.pack(pady=2, anchor="w")

        self.label_result = tk.Label(self.frame_left, text="Resultado:\n...", fg="green", bg="white")
        self.label_result.pack(pady=10, fill="x")

        self.fig = plt.Figure(figsize=(4,3), dpi=100)
        self.ax = self.fig.add_subplot(111)
        self.ax.set_xlabel("Ángulo (grados)")
        self.ax.set_ylabel("Vel. requerida (m/s)")

        self.canvas = FigureCanvasTkAgg(self.fig, master=self.frame_right)
        self.canvas_widget = self.canvas.get_tk_widget()
        self.canvas_widget.pack(fill="both", expand=True)

        self.m, self.b, self.h0 = 1.0, 0.0, 0.0
        self.has_drag = False
        self.x_target = None

    def import_config(self):
        try:
            self.m = float(self.tab_sim.entry_masa.get())
            if self.tab_sim.check_rozamiento.get():
                self.has_drag = True
                self.b = float(self.tab_sim.entry_b.get())
            else:
                self.has_drag = False
                self.b = 0.0
            self.h0 = float(self.tab_sim.entry_h0.get())
            if self.tab_sim.parametro_var.get() == "Alcance (m)":
                self.x_target = float(self.tab_sim.entry_v0.get())
            else:
                self.x_target = None

            self.label_m.config(text=f"Masa: {self.m:.2f} kg")
            self.label_b.config(text=f"b: {self.b:.4f}")
            self.label_h0.config(text=f"h0: {self.h0:.2f} m")
            self.label_drag.config(text=f"Drag: {self.has_drag}")
            if self.x_target is not None:
                self.label_x_target.config(text=f"X_target: {self.x_target:.2f} m")
            else:
                self.label_x_target.config(text="X_target: (No hay)")
            self.label_result.config(text="Config importada OK", bg="lightgreen", fg="black")
        except ValueError:
            self.label_result.config(text="Error al leer config", bg="red", fg="white")
            self.x_target = None

    def run_search(self):
        if self.x_target is None:
            self.label_result.config(text="Error: en la pestaña 1 no se eligió 'Alcance (m)'", bg="red", fg="white")
            return
        X_target = self.x_target
        angulos, velocidades = [], []
        best_angle, best_v = None, 1e9
        for angle_deg in range(0, 91):
            v0_min, v0_max, final_v = 0.0, 300.0, 0.0
            for _ in range(100):
                guess = 0.5*(v0_min+v0_max)
                dist = self.simular_dist(guess, angle_deg, self.has_drag)
                if abs(dist - X_target) < 0.1:
                    final_v = guess
                    break
                if dist < X_target: v0_min = guess
                else: v0_max = guess
                final_v = guess
            angulos.append(angle_deg)
            velocidades.append(final_v)
            if final_v < best_v:
                best_v, best_angle = final_v, angle_deg

        self.ax.clear()
        self.ax.set_xlabel("Ángulo (grados)")
        self.ax.set_ylabel("Vel. requerida (m/s)")
        self.ax.plot(angulos, velocidades, color="red")
        self.ax.plot([best_angle],[best_v], marker="o", markersize=8, color="green")
        self.canvas.draw()

        self.label_result.config(text=f"Mín. en {best_angle}°, v0={best_v:.2f} m/s", bg="white", fg="green")

    def simular_dist(self, v0_guess, angle_deg, drag):
        dt = 0.01
        x, y = 0.0, self.h0
        alpha = math.radians(angle_deg)
        vx = v0_guess*math.cos(alpha)
        vy = v0_guess*math.sin(alpha)
        while True:
            if drag:
                ax = -(self.b/self.m)*vx
                ay = -9.8 - (self.b/self.m)*vy
            else:
                ax, ay = 0.0, -9.8
            vx += ax*dt
            vy += ay*dt
            x += vx*dt
            y += vy*dt
            if y <= 0: break
        return x
