import os
import tkinter as tk
from tkinter import messagebox, ttk
import pandas as pd
from datetime import datetime
import threading

class PaqueteRepoApp:
    def __init__(self, root):
        self.root = root
        self.root.title("PaqueteRepo App")

        # Rutas y configuraciones
        self.base_path = r"C:\Users\ismael.gallardo\Documents\paquetes"
        self.old_path = os.path.join(self.base_path, "Old")
        self.paquetes_path = os.path.join(self.base_path, "Paquetes")
        self.filepath = os.path.join(self.base_path, "PaquetesRepo.xlsx")

        # Asegúrate de que las rutas existen
        self.verificar_ruta_archivo(self.old_path)
        self.verificar_ruta_archivo(self.paquetes_path)

        # Cargar datos iniciales
        self.cargar_bd()

        # Configuración de la interfaz
        self.configurar_interfaz()

    def verificar_ruta_archivo(self, filepath):
        if not os.path.exists(filepath):
            os.makedirs(filepath)

    def configurar_interfaz(self):
        botones = [
            ("Cargar BD", self.cargar_bd),
            ("Nueva Línea", self.nueva_linea),
            ("Modificar Estaciones", self.modificar_estaciones),
            ("BBDD", self.abrir_submenu_bbdd),
            ("Crear y Completar Paquetes", self.start_hilo_paquetes)
        ]
        for texto, comando in botones:
            tk.Button(self.root, text=texto, command=comando).pack(pady=5)

    def safe_int_conversion(self, value, label="Value"):
        try:
            return int(value)
        except ValueError:
            messagebox.showerror("Error", f"No se pudo convertir {label}: '{value}' a entero.")
            return 0

    def cargar_bd(self):
        try:
            self.listado_reposicion = pd.read_excel(self.filepath, sheet_name='Listado Reposición').dropna(subset=['Sucursales', 'TIPO DE REPOSICIÓN'])
            self.cortes = pd.read_excel(self.filepath, sheet_name='Cortes')
            self.estaciones_activas = pd.read_excel(self.filepath, sheet_name='Estaciones Activas')
            self.listado_reposicion.columns = self.listado_reposicion.columns.str.strip()
            self.filtrar_y_ordenar_reposicion()
            messagebox.showinfo("Éxito", "Base de datos cargada y ordenada correctamente.")
        except FileNotFoundError:
            messagebox.showerror("Archivo no encontrado", f"No se pudo encontrar el archivo: {self.filepath}")
        except Exception as e:
            messagebox.showerror("Error", f"Error al cargar BD: {e}")

    def filtrar_y_ordenar_reposicion(self):
        self.listado_reposicion = self.listado_reposicion[
            self.listado_reposicion['TIPO DE REPOSICIÓN'].isin(["Reposición Urgente = stock 0", "Reposición "])
        ]
        tipo_reposicion_orden = pd.CategoricalDtype(
            categories=["Reposición Urgente = stock 0", "Reposición "],
            ordered=True
        )
        self.listado_reposicion['TIPO DE REPOSICIÓN'] = self.listado_reposicion['TIPO DE REPOSICIÓN'].astype(tipo_reposicion_orden)
        self.listado_reposicion.sort_values(by=['TIPO DE REPOSICIÓN', 'Fecha de creación', 'Hora de Creación'], inplace=True)

    def abrir_submenu_bbdd(self):
        submenu = tk.Toplevel(self.root)
        submenu.title("Base de Datos")

        datasets = [
            ("Listado Reposición", self.listado_reposicion),
            ("Cortes", self.cortes),
            ("Estaciones Activas", self.estaciones_activas)
        ]

        for nombre, datos in datasets:
            tk.Button(submenu, text=nombre, command=lambda df=datos: self.mostrar_tabla(df)).pack(pady=5)

    def mostrar_tabla(self, dataframe):
        ventana_tabla = tk.Toplevel(self.root)
        ventana_tabla.title("Tabla")
        frame = tk.Frame(ventana_tabla)
        frame.pack(fill=tk.BOTH, expand=True)

        headers = [self.procesar_nombre_columna(col) for col in dataframe.columns]

        tree = ttk.Treeview(frame, columns=headers, show='headings')
        tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        for col in headers:
            tree.heading(col, text=col.replace('_', ' '))
            tree.column(col, anchor='center')

        for _, row in dataframe.iterrows():
            tree.insert("", "end", values=list(row))

        scrollbar_y = ttk.Scrollbar(frame, orient='vertical', command=tree.yview)
        scrollbar_y.pack(side=tk.RIGHT, fill='y')
        tree.configure(yscrollcommand=scrollbar_y.set)

        scrollbar_x = ttk.Scrollbar(ventana_tabla, orient='horizontal', command=tree.xview)
        scrollbar_x.pack(side=tk.BOTTOM, fill='x')
        tree.configure(xscrollcommand=scrollbar_x.set)

    def procesar_nombre_columna(self, nombre):
        return str(nombre).strip().replace(' ', '_').replace('.', '_')

    def nueva_linea(self):
        nueva_ventana = tk.Toplevel(self.root)
        nueva_ventana.title("Nueva Línea")
        campos = [
            ("Referencia", tk.Entry(nueva_ventana)),
            ("Cantidad", tk.Entry(nueva_ventana))
        ]
        valores = {}

        for texto, entrada in campos:
            tk.Label(nueva_ventana, text=texto).pack()
            entrada.pack()
            valores[texto] = entrada

        sucursal_var, ruta_var, tipo_suc_var, tipo_reposicion_var = tk.StringVar(), tk.StringVar(), tk.StringVar(), tk.StringVar()
        sucursales_lista = self.listado_reposicion['Sucursales'].dropna().unique()
        if sucursales_lista.any():
            sucursal_menu = tk.OptionMenu(nueva_ventana, sucursal_var, *sucursales_lista)
            sucursal_menu.pack()

        sucursal_var.trace('w', lambda *args: self.actualizar_info_sucursal(sucursal_var, ruta_var, tipo_suc_var))

        for texto, var in [("Ruta", ruta_var), ("Tipo Sucursal", tipo_suc_var)]:
            tk.Label(nueva_ventana, text=texto).pack()
            tk.Label(nueva_ventana, textvariable=var).pack()

        tk.Label(nueva_ventana, text="Tipo de Reposición").pack()
        tipo_reposicion_menu = tk.OptionMenu(nueva_ventana, tipo_reposicion_var, "Reposición Urgente = stock 0", "Reposición ")
        tipo_reposicion_menu.pack()
        tk.Button(nueva_ventana, text="Guardar", command=lambda: self.guardar_nueva_linea(
            valores['Referencia'].get(), valores['Cantidad'].get(), sucursal_var.get(), ruta_var.get(), tipo_suc_var.get(), tipo_reposicion_var.get()
        )).pack()

    def actualizar_info_sucursal(self, sucursal_var, ruta_var, tipo_suc_var):
        sucursal_seleccionada = sucursal_var.get()
        if sucursal_seleccionada:
            fila = self.listado_reposicion[self.listado_reposicion['Sucursales'] == sucursal_seleccionada].iloc[0]
            ruta_var.set(fila.get('Ruta', ''))
            tipo_suc_var.set(fila.get('TIPO Suc.', ''))

    def guardar_nueva_linea(self, referencia, cantidad, sucursal, ruta, tipo_suc, tipo_reposicion):
        fecha_creacion, hora_creacion = datetime.now().strftime("%Y-%m-%d"), datetime.now().strftime("%H:%M:%S")
        nueva_linea = pd.DataFrame({
            'Referencia': [referencia],
            'Cantitat': [cantidad],
            'Sucursales': [sucursal],
            'Ruta': [ruta],
            'TIPO Suc.': [tipo_suc],
            'TIPO DE REPOSICIÓN': [tipo_reposicion],
            'Fecha de creación': [fecha_creacion],
            'Hora de Creación': [hora_creacion]
        })
        self.listado_reposicion = pd.concat([self.listado_reposicion, nueva_linea], ignore_index=True)
        self.guardar_cambios_excel()
        messagebox.showinfo("Éxito", "La nueva línea ha sido añadida correctamente.")

    def modificar_estaciones(self):
        mod_window = tk.Toplevel(self.root)
        mod_window.title("Modificar Estaciones")

        headers = [self.procesar_nombre_columna(col) for col in self.estaciones_activas.columns]

        tree = ttk.Treeview(mod_window, columns=headers, show='headings')
        tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        for col in headers:
            tree.heading(col, text=col.replace('_', ' '))
            tree.column(col, anchor='center')

        for _, row in self.estaciones_activas.iterrows():
            tree.insert("", "end", values=list(row))

        scrollbar = ttk.Scrollbar(mod_window, orient='vertical', command=tree.yview)
        scrollbar.pack(side=tk.RIGHT, fill='y')
        tree.configure(yscrollcommand=scrollbar.set)

        def edit_cell(event):
            item_id = tree.focus()
            column_id = tree.identify_column(event.x)
            col_idx = int(column_id[1:]) - 1

            if col_idx not in [1, 2]:
                return

            x, y, width, height = tree.bbox(item_id, column=column_id)
            current_value = tree.set(item_id, column=column_id)

            entry = tk.Entry(mod_window)
            entry.insert(0, current_value)
            entry.place(x=x, y=y, width=width, height=height)
            entry.focus()

            def set_value(e):
                new_value = entry.get()
                if new_value.isdigit():
                    tree.set(item_id, column=column_id, value=new_value)
                    row_values = list(tree.item(item_id)["values"])
                    row_values[3] = int(row_values[1]) * int(row_values[2])
                    tree.item(item_id, values=row_values)
                entry.destroy()

            entry.bind('<Return>', set_value)
            entry.bind('<FocusOut>', lambda e: entry.destroy())

        tree.bind('<Double-1>', edit_cell)

    def guardar_cambios_excel(self):
        temp_filepath = os.path.join(self.base_path, "TempPaquetesRepo.xlsx")
        try:
            with pd.ExcelWriter(temp_filepath, engine='xlsxwriter') as writer:
                self.listado_reposicion.to_excel(writer, sheet_name='Listado Reposición', index=False)
                self.cortes.to_excel(writer, sheet_name='Cortes', index=False)
                self.estaciones_activas.to_excel(writer, sheet_name='Estaciones Activas', index=False)
                
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            backup_filepath = os.path.join(self.old_path, f"PaquetesRepo_Old_{timestamp}.xlsx")
            os.rename(self.filepath, backup_filepath)

            os.rename(temp_filepath, self.filepath)
            messagebox.showinfo("Guardado", "Cambios guardados correctamente en Excel y archivo original respaldado.")
        except Exception as e:
            messagebox.showerror("Error", f"Error al guardar en Excel: {e}")

    def crear_y_completar_paquetes(self):
        try:
            listed_ordenada = pd.read_excel(self.filepath, sheet_name='Listado Reposición')

            hora_actual = datetime.now().time()
            hora_corte_actual = None
            total_cortes = len(self.cortes.filter(like='Horas de corte').columns)

            for i in range(total_cortes):
                hora_inicio_str = str(self.cortes.iloc[0, i])
                hora_fin_str = str(self.cortes.iloc[1, i])
                hora_inicio = datetime.strptime(hora_inicio_str, '%H:%M:%S').time()
                hora_fin = datetime.strptime(hora_fin_str, '%H:%M:%S').time()

                if hora_inicio <= hora_fin and hora_inicio <= hora_actual < hora_fin:
                    hora_corte_actual = i + 1
                    break
                elif hora_inicio > hora_fin and (hora_actual >= hora_inicio or hora_actual < hora_fin):
                    hora_corte_actual = i + 1
                    break

            if hora_corte_actual is None:
                hora_corte_actual = 1

            capacidad = self.safe_int_conversion(
                self.estaciones_activas.loc[
                    self.estaciones_activas['Hora de Corte'] == f'Horas de corte {hora_corte_actual}',
                    'Capacidad lineas por minuto'
                ].values[0],
                "Capacidad Líneas por Minuto"
            )
            minutos_corte_val = self.cortes.iloc[2, hora_corte_actual]
            minutos_en_el_corte = self.safe_int_conversion(minutos_corte_val, "Minutos en el Corte")
            lineas_en_corte = capacidad * minutos_en_el_corte

            df_paquetes_completo = []

            for sucursal in self.determinar_sucursales(listed_ordenada):
                lineas_necesarias = self.obtener_lineas_necesarias(sucursal)
                lineas_sucursal = listed_ordenada[listed_ordenada['Sucursales'] == sucursal]
                lineas_a_asignar = lineas_sucursal.head(lineas_necesarias).copy()

                if not lineas_a_asignar.empty:
                    lineas_a_asignar['Paquete'] = [f"Corte1{sucursal}_1"] * len(lineas_a_asignar)
                    df_paquetes_completo.append(lineas_a_asignar)

            if df_paquetes_completo:
                resultado_final = pd.concat(df_paquetes_completo, ignore_index=True)
                columnas_finales = [
                    'Referencia', 'Cantitat', 'Sucursales', 'Ruta', 'TIPO Suc.',
                    'TIPO DE REPOSICIÓN', 'Fecha de creación', 'Hora de Creación', 'Paquete'
                ]
                timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
                paquetes_output = os.path.join(self.paquetes_path, f"Paquetes_{timestamp}.xlsx")
                resultado_final.to_excel(paquetes_output, index=False, columns=columnas_finales)
                messagebox.showinfo("Éxito", f"Paquetes generados y guardados en: {paquetes_output}")

                self.listado_reposicion.drop(resultado_final.index, inplace=True)
                self.guardar_cambios_excel()

        except Exception as e:
            messagebox.showerror("Error", f"Ocurrió un error al procesar los paquetes: {e}")

    def determinar_sucursales(self, dataframe):
        return dataframe['Sucursales'].unique()

    def obtener_lineas_necesarias(self, sucursal):
        return self.listado_reposicion[self.listado_reposicion['Sucursales'] == sucursal].shape[0]
    
    def start_hilo_paquetes(self):
        threading.Thread(target=self.crear_y_completar_paquetes).start()

if __name__ == "__main__":
    root = tk.Tk()
    app = PaqueteRepoApp(root)
    root.mainloop()

Disculpa ese no es el problema el problema es que la hora del ordenador te situa que estas en Hora Inicio y Hora Fin del corte 5 y al passar coger el numero del siguiente corte va la celda F4 y cuando estas en esta situación tienes que volver a la celda A4 porque en vez de ser el Corte siguiente pasa a ser el Corte uno es igual que cuando no encuentras un intervalo donde situar la hora entonces trabajas el Corte 1 donde los minutos son A4 por ultimo antes en el boton Modificar Estaciones se te abrie el menu con dos botones Modificar Confirmar se han borrado y quiero que sigan esas funciones activadas si puedes recuperalas y dame el codigo nuevo entero corregido