import customtkinter as ctk
from tkinter import filedialog
from tkinter import messagebox
import json

ctk.set_appearance_mode("System")
ctk.set_default_color_theme("blue")

class ConfigEditor:
    def __init__(self, root):
        self.root = root
        self.root.title("Config File Editor")
        self.config_data = {}
        
        self.open_button = ctk.CTkButton(self.root, text="Open Config File", command=self.open_file)
        self.open_button.pack(pady=20)
        
    def open_file(self):
        file_path = filedialog.askopenfilename(filetypes=[("Config Files", "*.txt"), ("All Files", "*.*")])
        if file_path:
            try:
                with open(file_path, 'r') as file:
                    self.config_data = self.parse_config(file.read())
                    self.display_config()
            except Exception as e:
                messagebox.showerror("Error", f"Failed to read config file: {e}")

    def parse_config(self, filename):
        result = subprocess.run(["./parser-cli", filename], capture_output=True, text=True)
        output = result.stdout
        data = {}
        lines = output.splitlines()

        for line in lines:
            match = re.match(r" > (\w+) '([\w.]+)' = (.*)", line)
            if match:
                var_type, full_name, value = match.groups()
                keys = full_name.split('.')
                d = data
                for key in keys[:-1]:
                    if key not in d:
                        d[key] = {}
                    d = d[key]
                d[keys[-1]] = value.strip()

        return data
    
    def parse_config(self, content):
        data = {}
        lines = content.split("\n")
        print(lines)
        current_namespace = data
        namespace_stack = []
        
        for line in lines:
            line = line.split("#")[0].strip()  # Remove comments
            if not line:
                continue
            if line.endswith("{"):
                namespace_name = line[:-1].strip()
                namespace_stack.append(current_namespace)
                if namespace_name not in current_namespace:
                    current_namespace[namespace_name] = {}
                current_namespace = current_namespace[namespace_name]
            elif line.endswith("}"):
                current_namespace = namespace_stack.pop()
            else:
                if "=" in line:
                    key, value = [x.strip() for x in line.split("=", 1)]
                    current_namespace[key] = value.strip(";").strip()
        
        return data
    
    def display_config(self):
        for widget in self.root.winfo_children():
            if isinstance(widget, ctk.CTkFrame):
                widget.destroy()
        
        self.tabview = ctk.CTkTabview(self.root)
        self.tabview.pack(expand=1, fill="both")
        
        self.create_tabs(self.tabview, self.config_data)
        
    def create_tabs(self, parent, data, tab_name="Main"):
        tab = parent.add(tab_name)
        
        row = 0
        for key, value in data.items():
            if isinstance(value, dict):
                sub_tabview = ctk.CTkTabview(tab)
                sub_tabview.pack(expand=1, fill="both", pady=10)
                self.create_tabs(sub_tabview, value, key)
            else:
                self.create_widget(tab, key, value, row)
                row += 1
    
    def create_widget(self, parent, key, value, row):
        ctk.CTkLabel(parent, text=key).grid(row=row, column=0, padx=10, pady=5)
        
        if value.lower() in ("true", "false"):
            var = ctk.BooleanVar(value=value.lower() == "true")
            ctk.CTkSwitch(parent, variable=var, text="").grid(row=row, column=1, padx=10, pady=5)
        elif value.replace(".", "", 1).isdigit():
            var = ctk.DoubleVar(value=value)
            ctk.CTkEntry(parent, textvariable=var).grid(row=row, column=1, padx=10, pady=5)
        elif "||" in value:
            options = [opt.strip().strip('"') for opt in value.split("||")]
            var = ctk.StringVar(value=options[0])
            ctk.CTkOptionMenu(parent, variable=var, values=options).grid(row=row, column=1, padx=10, pady=5)
        else:
            var = ctk.StringVar(value=value)
            ctk.CTkEntry(parent, textvariable=var).grid(row=row, column=1, padx=10, pady=5)
        
        ctk.CTkButton(parent, text="...", command=lambda: self.file_dialog(var)).grid(row=row, column=2, padx=10, pady=5)
        
    def file_dialog(self, var):
        file_path = filedialog.askopenfilename()
        if file_path:
            var.set(file_path)

if __name__ == "__main__":
    root = ctk.CTk()
    app = ConfigEditor(root)
    root.mainloop()