Use code a as inspiration for how to do the layout of the gui where the header is above the spacer-frame but not the sidebar. I want the same layout in code 2. I am only interested in the layout nothing else. Code 1: import sys
import sqlite3
from pathlib import Path
import tkinter as tk
from tkinter import ttk, messagebox, font

MEDIA_DB = Path(__file__).parent / 'media.db'

if sys.platform.startswith('win'):
    try:
        import ctypes
        ctypes.windll.shcore.SetProcessDpiAwareness(1)
    except Exception as e:
        print("Error setting DPI awareness:", e)

def run_query(query: str, parameters: tuple = ()) -> list:
    """Execute a SQL query and return the results if it's a SELECT statement."""
    with sqlite3.connect(MEDIA_DB) as conn:
        cursor = conn.cursor()
        result = cursor.execute(query, parameters)
        if query.strip().lower().startswith("select"):
            return result.fetchall()
        conn.commit()

def create_tables() -> None:
    """Create the movies and series tables in the database if they do not exist."""
    run_query('''
    CREATE TABLE IF NOT EXISTS movies (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        movie TEXT,
        year TEXT,
        present BOOLEAN,
        watched BOOLEAN,
        notes TEXT
    );
    ''')
    run_query('''
    CREATE TABLE IF NOT EXISTS series (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        series TEXT,
        seasons TEXT,
        year TEXT,
        present BOOLEAN,
        seasons_present TEXT,
        complete BOOLEAN,
        watched BOOLEAN,
        seasons_seen TEXT,
        notes TEXT
    );
    ''')

class MediaTracker(tk.Tk):
    """A Tkinter application to track movies and series."""

    BOOLEAN_COLUMNS = {
        'movies': ['Present', 'Watched'],
        'series': ['Present', 'Complete', 'Watched']
    }

    def __init__(self):
        super().__init__()
        self.configure(bg='white')
        self.title(" Database")
        self.geometry("1200x600")
        self.custom_font = self._get_custom_font()
        self.current_table = None
        self.current_row_id = None
        self.tree = None
        self.scrollbar = None

        self._configure_style()
        self._configure_scrollbar_style()
        self._configure_grid()
        self._create_widgets()
        self.show_movies()

    def _get_custom_font(self) -> font.Font:
        """Retrieve the custom font, defaulting to Arial if Literata is unavailable."""
        try:
            return font.Font(family='Literata', size=12)
        except:
            return font.Font(family='Arial', size=12)

    def _configure_style(self) -> None:
        """Configure the styles for Treeview and buttons."""
        font_line_space = self.custom_font.metrics('linespace')
        row_height = font_line_space + 4

        style = ttk.Style()
        style.theme_use("default")

        style.layout(
            'Custom.Treeview',
            [('Custom.Treeview.treearea', {'sticky': 'nsew'})]
        )
        style.configure(
            "Custom.Treeview",
            font=self.custom_font,
            rowheight=row_height,
            borderwidth=0,
            relief='flat',
            highlightthickness=0,
            background='white',
            fieldbackground='white'
        )
        style.configure(
            "Custom.Treeview.Heading",
            font=(self.custom_font.cget("family"), self.custom_font.cget("size"), "bold"),
            background='#F7F8FC',
            relief='solid',
            borderwidth=0,
            anchor='center'
        )
        style.map(
            "Custom.Treeview.Heading",
            background=[('active', 'white')],
            relief=[('active', 'solid')]
        )
        style.configure("Custom.TButton", font=self.custom_font)

    def _configure_scrollbar_style(self) -> None:
        """Configure the style for Scrollbars."""
        style = ttk.Style()
        style.theme_use("default")
        
        style.configure("Custom.Vertical.TScrollbar", 
                        troughcolor='white', 
                        background='#c6c6c6', 
                        bordercolor='white',
                        arrowcolor='white',
                        borderwidth=0,
                        relief='flat')

        style.map("Custom.Vertical.TScrollbar",
                  background=[('active', '#9b9b9b'), ('pressed', '#8b8b8bff')])

        style.layout('Custom.Vertical.TScrollbar',
                     [('Vertical.Scrollbar.trough',
                       {'children': [('Vertical.Scrollbar.thumb', {'expand': '1',
                                                                   'sticky': 'nswe'})],
                        'sticky': 'ns'})])

    def _configure_grid(self) -> None:
        """Configure the grid layout for the main window."""
        self.grid_rowconfigure(1, weight=1)
        self.grid_columnconfigure(2, weight=1)

    def _create_widgets(self) -> None:
        """Create and layout all the widgets in the application."""
        self.header_canvas = tk.Canvas(self, bg='white', highlightthickness=0, height=100)
        self.header_canvas.grid(row=0, column=1, columnspan=3, sticky='ew')
        self.header_canvas.grid_propagate(False)
        self.update_header("Movies")

        sidebar = tk.Frame(self, width=150, bg='#F7F8FC')
        sidebar.grid(row=0, column=0, rowspan=2, sticky='ns')
        sidebar.grid_propagate(False)
        self.sidebar = sidebar

        spacer = tk.Frame(self, width=100, bg='white')
        spacer.grid(row=1, column=1, sticky='ns')
        spacer.grid_propagate(False)
        self.spacer = spacer

        content = tk.Frame(self, bg='white')
        content.grid(row=1, column=2, sticky='nsew')
        self.content = content

        self._create_buttons()
        self._create_sidebar_labels()

    def update_header(self, text: str) -> None:
        """Update the header with the given text."""
        self.header_canvas.delete("all")
        
        small_font = font.Font(family=self.custom_font.actual('family'), size=10)

        self.header_canvas.create_text(
            10, 10,
            anchor='nw',
            text="Data >",
            fill='#999999',
            font=small_font
        )

        self.header_canvas.create_text(
            80, 10,
            anchor='nw',
            text=text,
            fill='black',
            font=small_font
        )

    def _create_sidebar_labels(self) -> None:
        """Create labels for the sidebar to switch between Movies and Series."""
        self.create_sidebar_label("▤ Movies", self.show_movies, pady=100)
        self.create_sidebar_label("▤ Series", self.show_series, pady=0)

    def create_sidebar_label(self, text: str, command, pady=0) -> None:
        """Create a clickable label in the sidebar."""
        label = tk.Label(
            self.sidebar,
            text=text,
            bg='#F7F8FC',
            font=self.custom_font,
            cursor="hand2",
            anchor='w',
            padx=50,
            pady=0
        )
        label.pack(pady=(pady, 1), fill='x')
        label.bind("<Enter>", lambda e: label.config(bg='#EAEDEF'))
        label.bind("<Leave>", lambda e: label.config(bg='#F7F8FC'))
        label.bind("<Button-1>", lambda e: command())

    def _create_buttons(self) -> None:
        """Create add and delete buttons within the spacer."""
        style = ttk.Style()
        style.configure("Square.TButton",
                        font=('Arial', 14),
                        padding=(1, 1),
                        width=2,
                        background='white',
                        borderwidth=0,
                        relief='flat')
        style.map("Square.TButton",
                  background=[('active', '#EAEDEF')])

        self.add_button = ttk.Button(
            self.spacer,
            text="+",
            command=self.add_entry,
            style="Square.TButton"
        )
      
        self.delete_button = ttk.Button(
            self.spacer,
            text="-",
            command=self.delete_entry,
            style="Square.TButton"
        )

    def clear_content(self) -> None:
        """Clear the content frame by destroying the tree and scrollbar if they exist."""
        for widget in [self.tree, self.scrollbar]:
            if widget:
                widget.destroy()
        self.tree = None
        self.scrollbar = None

    def setup_treeview(self, columns: list, headings: list) -> None:
        """Set up the Treeview widget with specified columns and headings."""
        self.tree = ttk.Treeview(
            self.content,
            columns=columns,
            show='headings',
            selectmode='browse',
            style="Custom.Treeview"
        )
        for col, head in zip(columns, headings):
            self.tree.heading(col, text=head, anchor='center')
            anchor = 'w' if head.lower() == 'notes' else 'center'
            width = 300 if head.lower() == 'notes' else 100 if head in self.BOOLEAN_COLUMNS.get(self.current_table, []) else 150
            self.tree.column(col, width=width, anchor=anchor)

        self.scrollbar = ttk.Scrollbar(
            self.content,
            orient="vertical",
            command=self.tree.yview,
            style="Custom.Vertical.TScrollbar"
        )
        self.tree.configure(yscrollcommand=self.scrollbar.set)
        self.scrollbar.pack(side='right', fill='y')
        self.tree.pack(fill='both', expand=True)

        self.tree.bind('<<TreeviewSelect>>', self.on_row_select)
        self.tree.bind('<Button-1>', self.on_single_click)
        self.tree.bind("<Double-Button-1>", self.on_double_click)
        self.tree.bind("<Motion>", self.treeview_click_cursor)

    def load_movie_data(self) -> None:
        """Load and display movie data in the Treeview."""
        self.clear_content()
        columns = ["Movie", "Year", "Present", "Watched", "Notes"]
        self.setup_treeview(columns, columns)
        self.current_table = 'movies'
        self.update_header("Movies")
        for row in run_query('SELECT * FROM movies'):
            record_id, movie, year, present, watched, notes = row
            display_row = [
                movie,
                year,
                self.bool_to_checkbox(present),
                self.bool_to_checkbox(watched),
                notes
            ]
            self.tree.insert('', 'end', iid=str(record_id), values=display_row)

    def load_series_data(self) -> None:
        """Load and display series data in the Treeview."""
        self.clear_content()
        columns = ["Series", "Seasons", "Year", "Present",
                   "Seasons Present", "Complete", "Watched",
                   "Seasons Seen", "Notes"]
        self.setup_treeview(columns, columns)
        self.current_table = 'series'
        self.update_header("Series")
        for row in run_query('SELECT * FROM series'):
            (record_id, series, seasons, year, present, seasons_present,
             complete, watched, seasons_seen, notes) = row
            display_row = [
                series,
                seasons,
                year,
                self.bool_to_checkbox(present),
                seasons_present,
                self.bool_to_checkbox(complete),
                self.bool_to_checkbox(watched),
                seasons_seen,
                notes
            ]
            self.tree.insert('', 'end', iid=str(record_id), values=display_row)

    def show_movies(self) -> None:
        """Display the movies table."""
        self.load_movie_data()

    def show_series(self) -> None:
        """Display the series table."""
        self.load_series_data()

    def add_entry(self) -> None:
        """Add a new entry to the current table."""
        if self.current_table == 'movies':
            run_query(
                "INSERT INTO movies (movie, year, present, watched, notes) VALUES (?, ?, ?, ?, ?)",
                ('', '', False, False, '')
            )
            self.load_movie_data()
        elif self.current_table == 'series':
            run_query(
                """INSERT INTO series
                (series, seasons, year, present, seasons_present, complete, watched, seasons_seen, notes)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)""",
                ('', '', '', False, '', False, False, '', '')
            )
            self.load_series_data()

    def delete_entry(self) -> None:
        """Delete the selected entry from the current table with confirmation."""
        selected_item = self.tree.selection()
        if not selected_item:
            messagebox.showwarning("No selection", "Please select a row to delete.")
            return
    
        confirm = messagebox.askokcancel(
            "Delete Row",
            "Are you sure you want to delete this row?\nThis action cannot be undone.",
            icon='warning'
        )
    
        if confirm:
            row_id = selected_item[0]
            run_query(f"DELETE FROM {self.current_table} WHERE id = ?", (row_id,))
            if self.current_table == 'movies':
                self.load_movie_data()
            elif self.current_table == 'series':
                self.load_series_data()
            
    def on_row_select(self, event) -> None:
        """Handle the selection of a row in the Treeview."""
        selected_item = self.tree.selection()
        self.current_row_id = selected_item[0] if selected_item else None
    
        if selected_item:
            x, y, width, height = self.tree.bbox(self.current_row_id)
            y_offset = y + height // 2
    
            self.delete_button.place(x=45, y=y_offset, anchor='center')
            self.add_button.place(x=80, y=y_offset, anchor='center')
        else:
            self.delete_button.place_forget()
            self.add_button.place_forget()

    def on_single_click(self, event) -> None:
        """Handle single click events for toggling boolean fields."""
        region = self.tree.identify("region", event.x, event.y)
        if region != "cell":
            return

        row_id = self.tree.identify_row(event.y)
        column = self.tree.identify_column(event.x)
        if not row_id or not column:
            return

        try:
            col_index = int(column.replace('#', '')) - 1
            column_name = self.tree['columns'][col_index]
        except (IndexError, ValueError):
            return

        if column_name in self.BOOLEAN_COLUMNS.get(self.current_table, []):
            current_value = self.tree.set(row_id, column_name)
            new_value = not self.checkbox_to_bool(current_value)
            self.tree.set(row_id, column_name, self.bool_to_checkbox(new_value))
            row_values = self.tree.item(row_id)['values']
            self.update_database(row_values)

    def on_double_click(self, event) -> None:
        """Open an entry widget to edit the item on double-click."""
        region = self.tree.identify("region", event.x, event.y)
        if region != "cell":
            return

        column = self.tree.identify_column(event.x)
        row_id = self.tree.identify_row(event.y)
        if not row_id or not column:
            return

        col_index = int(column.replace('#', '')) - 1
        column_name = self.tree['columns'][col_index]

        x, y, width, height = self.tree.bbox(row_id, column)
        current_value = self.tree.set(row_id, column_name)

        entry = tk.Entry(self.content, font=self.custom_font, relief='flat', borderwidth=0)
        entry.place(x=x, y=y, width=width, height=height)
        entry.insert(0, current_value)
        entry.focus()

        def on_focus_out(event):
            new_value = entry.get()
            self.tree.set(row_id, column_name, new_value)
            entry.destroy()
            self.update_database_from_treeview()

        entry.bind("<FocusOut>", on_focus_out)
        entry.bind("<Return>", lambda event: on_focus_out(event))

    def update_database(self, row_values: list) -> None:
        """Update the database with the modified row values."""
        if self.current_table == 'movies':
            query = """
                UPDATE movies 
                SET movie = ?, year = ?, present = ?, watched = ?, notes = ? 
                WHERE id = ?
            """
            parameters = (
                row_values[0],
                row_values[1],
                self.checkbox_to_bool(row_values[2]),
                self.checkbox_to_bool(row_values[3]),
                row_values[4],
                self.current_row_id
            )
        elif self.current_table == 'series':
            query = """
                UPDATE series 
                SET series = ?, seasons = ?, year = ?, present = ?, seasons_present = ?, 
                    complete = ?, watched = ?, seasons_seen = ?, notes = ? 
                WHERE id = ?
            """
            parameters = (
                row_values[0],
                row_values[1],
                row_values[2],
                self.checkbox_to_bool(row_values[3]),
                row_values[4],
                self.checkbox_to_bool(row_values[5]),
                self.checkbox_to_bool(row_values[6]),
                row_values[7],
                row_values[8],
                self.current_row_id
            )
        run_query(query, parameters)

    def update_database_from_treeview(self):
        """Update database with values from the Treeview."""
        for row_id in self.tree.get_children():
            row_values = self.tree.item(row_id)['values']
            self.current_row_id = row_id
            self.update_database(row_values)

    def treeview_click_cursor(self, event) -> None:
        """Change the cursor to a hand when hovering over boolean columns."""
        region = self.tree.identify("region", event.x, event.y)
        if region == "cell":
            column = self.tree.identify_column(event.x)
            try:
                col_index = int(column.replace('#', '')) - 1
                column_name = self.tree['columns'][col_index]
                cursor = "hand2" if column_name in self.BOOLEAN_COLUMNS.get(self.current_table, []) else ""
                self.tree.configure(cursor=cursor)
            except (IndexError, ValueError):
                self.tree.configure(cursor="")
        else:
            self.tree.configure(cursor="")

    @staticmethod
    def bool_to_checkbox(value: bool) -> str:
        """Convert a boolean value to a checkbox symbol."""
        return '☑' if value else '☐'

    @staticmethod
    def checkbox_to_bool(value: str) -> bool:
        """Convert a checkbox symbol to a boolean value."""
        return value == '☑'

if __name__ == "__main__":
    create_tables()
    app = MediaTracker()
    app.mainloop()
Code 2: import ctypes
import csv
import json
import tkinter as tk
from tkinter import filedialog, messagebox, simpledialog, ttk
from pathlib import Path
from tksheet import Sheet

from typing import Optional

def set_dpi_awareness():
    """Enable DPI awareness for high DPI settings."""
    try:
        ctypes.windll.shcore.SetProcessDpiAwareness(1)
    except Exception as e:
        print(f"Error setting DPI awareness: {e}")


class TableApp:
    """Table Editor with sidebar and table management."""

    def __init__(self, root: tk.Tk):
        """Initialize the TableApp."""
        self.root = root
        self.config_dimensions()
        self.config_fonts()
        self.config_colors()
        self.initialize_data()
        self.setup_ui()
        self.load_tables()

    def config_dimensions(self):
        """Configure app dimensions."""
        self.root.title("Database")
        self.root.geometry("1920x1080")
        self.root.minsize(1435, 910)
        self.sidebar_width = 400
        self.static_frame_width = 100
        self.header_height = 190

    def config_fonts(self):
        """Configure app fonts."""
        font_name, font_size, font_style = "Literata", 12, "normal"
        self.default_font = (font_name, font_size, font_style)
        self.root.option_add("*Font", f"{font_name} {font_size}")

    def config_colors(self):
        """Configure app colors."""
        self.text_color = "#333333"
        self.background_color = "#FFFFFF"
        self.sidebar_color = "#F7F8FC"
        self.button_color = "#F7F8FC"
        self.button_color_selected = "#EAEDEF"

    def setup_ui(self):
        """Set up the user interface."""
        self.create_sidebar()
        self.create_main_frame()
        self.create_header_frame()
        self.create_table_frame()

    def create_sidebar(self):
        """Create the sidebar with functional and spacer frames."""
        functional_sidebar = self._create_frame(
            parent=self.root,
            width=self.sidebar_width,
            bg=self.sidebar_color,
            side='left',
            anchor='nw',
            fill='y'
        )
        spacer_frame = self._create_frame(
            parent=self.root,
            width=self.static_frame_width,
            bg=self.background_color,
            side='left',
            anchor='nw',
            fill='y'
        )

        functional_sidebar.pack_propagate(False)
        self._add_normal_buttons(functional_sidebar)
        self._add_scrollable_canvas(functional_sidebar)
        self._add_delete_table_section(functional_sidebar)

    def _create_frame(
        self,
        parent: tk.Widget,
        width: Optional[int],
        bg: str,
        side: str,
        anchor: str,
        fill: str,
        expand: bool = False
    ) -> tk.Frame:
        """Create and pack a frame."""
        frame = tk.Frame(parent, width=width, bg=bg, bd=0, relief='flat')
        frame.pack(side=side, anchor=anchor, fill=fill, expand=expand)
        return frame

    def _add_normal_buttons(self, sidebar: tk.Frame):
        """Add buttons to the sidebar."""
        normal_buttons_frame = self._create_frame(
            parent=sidebar,
            width=None,
            bg=self.sidebar_color,
            side='top',
            anchor='nw',
            fill='x'
        )
        create_table_label = self._create_clickable_label(
            parent=normal_buttons_frame,
            text="Create New Table",
            command=self.create_new_table,
            anchor='center'
        )
        create_table_label.pack(pady=10, anchor='center')
        self.add_custom_hover(create_table_label)
        self._add_separator(normal_buttons_frame)

    def _add_scrollable_canvas(self, sidebar: tk.Frame):
        """Add scrollable canvas for table labels."""
        scrollbar_frame = self._create_frame(
            parent=sidebar,
            width=None,
            bg=self.sidebar_color,
            side='top',
            anchor='nw',
            fill='both',
            expand=True
        )

        canvas = tk.Canvas(
            scrollbar_frame,
            bg=self.sidebar_color,
            highlightthickness=0,
            width=self.sidebar_width - 15
        )
        canvas.pack(side="left", fill="both", expand=True)

        self.config_scrollbar_style()

        scrollbar = ttk.Scrollbar(
            scrollbar_frame,
            orient="vertical",
            command=canvas.yview,
            style="Custom.Vertical.TScrollbar"
        )
        scrollbar.pack(side="right", fill="y")
        canvas.configure(yscrollcommand=scrollbar.set)

        self.table_labels_frame = tk.Frame(canvas, bg=self.sidebar_color)
        canvas.create_window((0, 0), window=self.table_labels_frame, anchor="nw")

        canvas.bind_all("<MouseWheel>", lambda event: canvas.yview_scroll(int(-1 * (event.delta / 120)), "units"))

        self._bind_scrollbar_events(canvas, scrollbar, scrollbar_frame)

    def _bind_scrollbar_events(self, canvas: tk.Canvas, scrollbar: ttk.Scrollbar, scrollbar_frame: tk.Frame):
        """Manage scrollbar visibility based on content size."""
        def configure_scrollbar(event: Optional[tk.Event] = None):
            canvas.update_idletasks()
            canvas_height = scrollbar_frame.winfo_height()
            content_height = self.table_labels_frame.winfo_reqheight()

            if content_height > canvas_height:
                scrollbar.pack(side="right", fill="y")
                canvas.bind_all("<MouseWheel>", lambda event: canvas.yview_scroll(int(-1 * (event.delta / 120)), "units"))
            else:
                scrollbar.pack_forget()
                canvas.unbind_all("<MouseWheel>")

            canvas.configure(scrollregion=canvas.bbox("all"))

        self.table_labels_frame.bind("<Configure>", configure_scrollbar)
        scrollbar_frame.bind("<Configure>", configure_scrollbar)

    def _add_delete_table_section(self, sidebar: tk.Frame):
        """Add delete table option to the sidebar."""
        self._add_separator(sidebar)
        delete_table_label = self._create_clickable_label(
            parent=sidebar,
            text="🗑 Delete Selected Table",
            command=self.delete_table,
            anchor='center'
        )
        delete_table_label.pack(side='bottom', anchor='center', pady=10)
        self.add_custom_hover(delete_table_label)

    def _add_separator(self, parent: tk.Widget):
        """Add a horizontal separator."""
        ttk.Separator(parent, orient='horizontal').pack(fill='x')

    def _create_clickable_label(
        self,
        parent: tk.Widget,
        text: str,
        command,
        allow_rename: bool = False,
        anchor: str = 'w'
    ) -> tk.Label:
        """Create a clickable label with optional rename functionality."""
        cursor = "arrow" if allow_rename else "hand2"
        label = tk.Label(
            parent,
            text=text,
            bg=self.button_color,
            fg=self.text_color,
            cursor=cursor,
            anchor=anchor
        )
        label.bind("<Button-1>", lambda _: command())
        if allow_rename:
            label.bind("<Double-1>", lambda _: self.begin_rename(text))
        return label

    def create_main_frame(self):
        """Create the main frame."""
        self.main_frame = tk.Frame(self.root)
        self.main_frame.pack(expand=True, fill='both', side='right')

    def create_header_frame(self):
        """Create the header with filter and settings options."""
        header_frame = self._create_frame(
            parent=self.main_frame,
            width=None,
            bg=self.background_color,
            side='top',
            anchor='nw',
            fill='x'
        )
        header_frame.config(height=self.header_height)
        header_frame.pack_propagate(False)

        tk.Label(
            header_frame,
            text="Filter:",
            bg=self.background_color,
            fg=self.text_color
        ).pack(side='left')

        self.filter_entry = tk.Entry(
            header_frame,
            fg=self.text_color
        )
        self.filter_entry.pack(side='left', padx=(0, 10))
        self.filter_entry.bind("<KeyRelease>", lambda _: self.apply_filter())

        settings_label = tk.Label(
            header_frame,
            text="...",
            bg=self.background_color,
            fg=self.text_color,
            cursor="hand2",
            anchor='e'
        )
        settings_label.place(relx=1.0, rely=0.0, anchor='ne', x=-40, y=20)

        settings_menu = tk.Menu(settings_label, tearoff=0)
        settings_menu.add_command(label="Export Table", command=self.export_table)
        settings_menu.add_command(label="Import Table", command=self.import_file)
        settings_menu.add_command(label="Rename Headers", command=self.rename_headers)

        settings_label.bind("<Button-1>", lambda e: settings_menu.post(e.x_root, e.y_root))
        settings_label.bind("<Enter>", lambda _: settings_label.config(bg=self.button_color_selected))
        settings_label.bind("<Leave>", lambda _: settings_label.config(bg=self.background_color))

    def create_table_frame(self):
        """Create the table frame."""
        self.table_frame = tk.Frame(
            self.main_frame,
            bg=self.background_color
        )
        self.table_frame.pack(expand=True, fill='both')

    def initialize_data(self):
        """Initialize data structures."""
        self.save_file_path = Path(__file__).parent / "Data.json"
        self.tables_data: dict[str, dict] = {}
        self.current_sheet: Sheet | None = None
        self.headers: dict[str, list[str]] = {}
        self.current_table_name: str | None = None
        self.rename_entry: tk.Entry | None = None
        self.selected_table_label: tk.Label | None = None
        self.table_labels: dict[str, tk.Label] = {}

    def create_new_table(self):
        """Create a new table."""
        existing_numbers = [int(name.split(" ")[1]) for name in self.tables_data if name.startswith("Table ") and name.split(" ")[1].isdigit()]
        next_number = max(existing_numbers, default=0) + 1
        table_name = f"Table {next_number}"
        self.add_table(table_name)
        self.load_selected_table(table_name)

    def import_file(self):
        """Import table from file."""
        file_path = filedialog.askopenfilename(title="Import File", filetypes=[("JSON files", "*.json"), ("CSV files", "*.csv")])
        if not file_path:
            return
        try:
            if file_path.endswith('.csv'):
                with open(file_path, newline='', encoding='utf-8') as csvfile:
                    data = list(csv.reader(csvfile))
            elif file_path.endswith('.json'):
                with open(file_path, 'r', encoding='utf-8') as jsonfile:
                    data = json.load(jsonfile)
            else:
                raise ValueError("Unsupported file format.")
            if not data or not isinstance(data, list) or not all(isinstance(row, list) for row in data):
                raise ValueError("Invalid data format in the file.")
            headers, table_data = data[0], data[1:]
            self.add_table_from_data(file_path, headers, table_data)
        except Exception as e:
            messagebox.showerror("File Import Error", str(e))

    def add_table_from_data(self, file_path: str, headers: list[str], table_data: list[list[str]]):
        """Add a table from file data."""
        table_name = Path(file_path).stem
        table_name = self.ensure_unique_table_name(table_name)
        self.add_table(table_name, table_data)
        self.headers[table_name] = headers
        self.load_selected_table(table_name)
        self.save_data()

    def ensure_unique_table_name(self, table_name: str) -> str:
        """Ensure table name is unique."""
        original_name = table_name
        counter = 1
        while table_name in self.tables_data:
            table_name = f"{original_name} (New {counter})"
            counter += 1
        return table_name

    def save_table_data(self, file_path: str, data: list[list[str]], format: str):
        """Save table data in specified format."""
        match format:
            case 'csv':
                with open(file_path, 'w', newline='', encoding='utf-8') as file:
                    csv.writer(file).writerows(data)
            case 'json':
                with open(file_path, 'w', encoding='utf-8') as file:
                    json.dump(data, file, indent=4)
            case _:
                raise ValueError("Unsupported file format.")

    def export_table(self):
        """Export current table to file."""
        if not self.current_table_name or self.current_table_name not in self.tables_data:
            messagebox.showwarning("No Table Selected", "Please select a table to export.")
            return
        file_path = filedialog.asksaveasfilename(title="Export File", defaultextension=".json", filetypes=[("JSON files", "*.json"), ("CSV files", "*.csv")], initialfile=self.current_table_name)
        if not file_path:
            return
        try:
            data = [self.headers[self.current_table_name]] + self.tables_data[self.current_table_name]["data"]
            if file_path.endswith('.csv'):
                self.save_table_data(file_path, data, 'csv')
            elif file_path.endswith('.json'):
                with open(file_path, 'w', encoding='utf-8') as file:
                    json.dump(data, file, indent=4)
            else:
                raise ValueError("Unsupported file format.")
            self.save_data()
            messagebox.showinfo("Export Successful", f"Table '{self.current_table_name}' has been exported successfully.")
        except Exception as e:
            messagebox.showerror("Export Failed", f"An error occurred during export: {e}")

    def add_table(self, table_name: str, data: list[list[str]] | None = None):
        """Add a new table."""
        default_data = [["" for _ in range(5)] for _ in range(10)]
        self.tables_data[table_name] = {"headers": self.headers.get(table_name, [""] * 5), "data": data or default_data}
        self.create_table_label(table_name)
        self.save_data()

    def create_table_label(self, table_name: str):
        """Create label for table."""
        label = self._create_clickable_label(self.table_labels_frame, table_name, lambda: self.load_selected_table(table_name), True)
        label.pack(fill='x', padx=20, pady=5)
        self.table_labels[table_name] = label
        self.add_custom_hover(label)

    def delete_table(self):
        """Delete selected table."""
        if not self.current_table_name or self.current_table_name not in self.tables_data:
            messagebox.showwarning("No Table Selected", "Please select a valid table to delete.")
            return
        if messagebox.askyesno("Delete Table", f"Are you sure you want to delete the table '{self.current_table_name}'?"):
            self.remove_table(self.current_table_name)

    def remove_table(self, table_name: str):
        """Remove a table."""
        if self.current_table_name == table_name and self.current_sheet:
            self.current_sheet.destroy()
            self.current_sheet = None
        label = self.table_labels.get(table_name)
        if label:
            label.destroy()
        if table_name in self.tables_data:
            del self.tables_data[table_name]
        if table_name in self.headers:
            del self.headers[table_name]
        if table_name in self.table_labels:
            del self.table_labels[table_name]
        self.current_table_name = None
        self.selected_table_label = None
        self.save_data()

    def load_tables(self):
        """Load tables from file."""
        if not self.save_file_path.exists():
            return
        try:
            with self.save_file_path.open('r', encoding='utf-8') as file:
                all_data = json.load(file)
        except Exception as e:
            messagebox.showerror("Load Error", f"Failed to load tables: {e}")
            return
        for table_name, data in all_data.items():
            if not isinstance(data, list) or not data:
                continue
            headers, table_data = data[0], data[1:]
            self.tables_data[table_name] = {"headers": headers, "data": table_data}
            self.headers[table_name] = headers
            self.create_table_label(table_name)

    def load_selected_table(self, table_name: str):
        """Display selected table."""
        if self.current_sheet:
            self.current_sheet.pack_forget()
            self.current_sheet.destroy()
            self.current_sheet = None
        if self.selected_table_label:
            try:
                self.selected_table_label.config(bg=self.button_color)
            except tk.TclError:
                self.selected_table_label = None
        if table_name not in self.tables_data:
            messagebox.showerror("Error", f"Table '{table_name}' does not exist.")
            self.current_table_name = None
            self.selected_table_label = None
            return
        table_info = self.tables_data[table_name]
        headers = table_info["headers"]
        data = table_info["data"]
        try:
            sheet = Sheet(self.table_frame, data=data, show_table=True, headers=headers, font=self.default_font, header_font=self.default_font, auto_resize_columns=True)
            sheet.set_options(table_fg=self.text_color, header_fg=self.text_color)
            sheet.enable_bindings()
            sheet.extra_bindings([("end_edit_cell", self.on_cell_edit)])
            sheet.pack(expand=True, fill='both')
            self.current_sheet = sheet
            self.current_table_name = table_name
            label = self.table_labels.get(table_name)
            if label:
                self.selected_table_label = label
                try:
                    self.selected_table_label.config(bg=self.button_color_selected)
                except tk.TclError:
                    self.selected_table_label = None
                    messagebox.showerror("Error", f"Failed to update the label for '{table_name}'.")
            else:
                self.selected_table_label = None
                messagebox.showerror("Error", f"Label for '{table_name}' not found.")
            self.apply_filter()
        except Exception as e:
            messagebox.showerror("Sheet Error", f"Failed to load table '{table_name}': {e}")
            self.current_table_name = None
            self.selected_table_label = None

    def on_cell_edit(self, event=None):
        """Handle cell edits."""
        if self.current_table_name and self.current_sheet:
            self.tables_data[self.current_table_name]["data"] = self.current_sheet.get_sheet_data()
            self.save_data()

    def save_data(self):
        """Save all tables data."""
        all_data = {}
        for table_name, table_info in self.tables_data.items():
            all_data[table_name] = [table_info["headers"]] + table_info["data"]
        try:
            with self.save_file_path.open('w', encoding='utf-8') as file:
                json.dump(all_data, file, indent=4)
        except Exception as e:
            print(f"Error saving data: {e}")

    def apply_filter(self):
        """Apply filter to table data."""
        if not self.current_table_name or not self.current_sheet:
            return
        term = self.filter_entry.get().lower()
        original_data = self.tables_data[self.current_table_name]["data"]
        if term:
            filtered_data = [row for row in original_data if any(term in str(cell).lower() for cell in row)]
        else:
            filtered_data = original_data
        try:
            self.current_sheet.set_sheet_data(filtered_data)
        except tk.TclError as e:
            print(f"Error applying filter: {e}")

    def rename_headers(self):
        """Rename table headers."""
        if not self.current_table_name:
            messagebox.showwarning("No Table Selected", "Please select a table to rename headers.")
            return
        current_headers = self.headers[self.current_table_name]
        new_headers = simpledialog.askstring("Rename Headers", "Enter new headers (comma-separated):", initialvalue=", ".join(current_headers))
        if new_headers:
            header_list = [header.strip() for header in new_headers.split(',')]
            if not header_list:
                messagebox.showerror("Invalid Headers", "Header list cannot be empty.")
                return
            self.headers[self.current_table_name] = header_list
            if self.current_sheet:
                try:
                    self.current_sheet.headers(header_list)
                except tk.TclError as e:
                    messagebox.showerror("Error", f"Failed to rename headers: {e}")
            self.save_data()

    def begin_rename(self, table_name: str):
        """Start renaming a table."""
        if table_name not in self.table_labels:
            messagebox.showerror("Error", f"Table '{table_name}' not found.")
            return
        label = self.table_labels[table_name]
        self.cancel_rename()
        self.rename_entry = tk.Entry(self.table_labels_frame, bg=label.cget("bg"), fg=self.text_color, relief='flat')
        self.rename_entry.insert(0, table_name)
        self.rename_entry.place(x=label.winfo_x(), y=label.winfo_y(), width=label.winfo_width(), height=label.winfo_height())
        self.rename_entry.focus()
        self.rename_entry.select_range(0, tk.END)
        self.rename_entry.bind('<Return>', lambda event: self.end_rename(table_name))
        self.rename_entry.bind('<FocusOut>', lambda event: self.cancel_rename())

    def end_rename(self, old_name: str):
        """Finalize table renaming."""
        new_name = self.rename_entry.get().strip()
        if not new_name:
            messagebox.showerror("Invalid Name", "Table name cannot be empty.")
            self.rename_entry.focus_set()
            return
        if new_name in self.tables_data and new_name != old_name:
            messagebox.showerror("Duplicate Name", f"A table named '{new_name}' already exists.")
            self.rename_entry.focus_set()
            return
        if new_name != old_name:
            self.update_table_name(old_name, new_name)
            self.load_selected_table(new_name)
        self.cancel_rename()

    def update_table_name(self, old_name: str, new_name: str):
        """Update table name and resources."""
        self.tables_data[new_name] = self.tables_data.pop(old_name)
        self.headers[new_name] = self.headers.pop(old_name)
        label = self.table_labels.pop(old_name)
        label.config(text=new_name)
        label.bind("<Button-1>", lambda event: self.load_selected_table(new_name))
        label.bind("<Double-1>", lambda event: self.begin_rename(new_name))
        self.table_labels[new_name] = label
        if self.selected_table_label == label:
            try:
                label.config(bg=self.button_color_selected)
            except tk.TclError:
                pass
        self.save_data()

    def cancel_rename(self):
        """Cancel rename operation."""
        if self.rename_entry:
            self.rename_entry.destroy()
            self.rename_entry = None

    def add_custom_hover(self, label: tk.Label):
        """Add hover effects to label."""
        def on_enter(event):
            if label != self.selected_table_label:
                try:
                    label.config(bg=self.button_color_selected)
                except tk.TclError:
                    pass

        def on_leave(event):
            if label != self.selected_table_label:
                try:
                    label.config(bg=self.button_color)
                except tk.TclError:
                    pass

        label.bind("<Enter>", on_enter)
        label.bind("<Leave>", on_leave)

    def config_scrollbar_style(self):
        """Configure scrollbar style."""
        self.style = ttk.Style()
        self.style.theme_use("default")
        self.style.configure("Custom.Vertical.TScrollbar", troughcolor=self.sidebar_color, background="#c0c1c4", borderwidth=0, arrowcolor=self.text_color)
        self.style.map("Custom.Vertical.TScrollbar", background=[('active', '#878789')])
        self.style.layout("Custom.Vertical.TScrollbar", [('Vertical.Scrollbar.trough', {'children': [('Vertical.Scrollbar.thumb', {'expand': '1', 'sticky': 'ns'})], 'sticky': 'ns'})])


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