import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
import json
import matplotlib.pyplot as plt
from matplotlib.backend_bases import PickEvent, Event, MouseEvent, KeyEvent
from datatypes import ExpenseEarningFrequencies
from  decimal import Decimal

class ExpensesPlot:
    def __init__(self, root: tk.Frame, expneses: list[ExpenseEarningFrequencies]) -> None:

        self.expenses = expneses
        self.categories = [item.name for item in self.expenses]
        self.amounts = [item.amount for item in self.expenses]

        self.figure = Figure(figsize=(8, 6), dpi=100)
        self.ax = self.figure.add_subplot(111)
        self.canvas = FigureCanvasTkAgg(self.figure, master=root)
        self.canvas.draw()
        self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.toolbar = NavigationToolbar2Tk(self.canvas, root)

        self.toolbar.update()
        self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.__plot_piechart(self.categories, self.amounts)
        self.canvas.mpl_connect('pick_event', self.__on_click)
        self.canvas.mpl_connect('key_press_event', self.on_key_press)

        self.toolbar.pack_forget() # hide the toolbar
        self.last_toolbar_cmd = None

        import api
        self.canvas_reference = self.canvas._tkcanvas
        self.api_endpoint = api.expenses

        self.legend_frame = tk.Frame(root, background='#F0F0F0')
        self.legend_frame.pack(side=tk.LEFT, fill=tk.Y, expand=0, padx=10, pady=10)
        self.create_legend()

    def create_legend(self) -> None:
        # Clear the legend frame
        for widget in self.legend_frame.winfo_children():
            widget.destroy()

        # Create labels for each category
        for i in range(len(self.categories)):
            # Create category frame
            category_frame = tk.Frame(self.legend_frame, background='#F0F0F0')
            category_frame.pack(fill='x', padx=5, pady=5)

            # Create category name label
            cat_label = tk.Label(
                category_frame, 
                text=self.categories[i],
                background='#F0F0F0',
                foreground='#333333',
                font=('Arial', 10, 'bold')
            )
            cat_label.pack(side='left')

            # Create amount label
            amount_label = tk.Label(
                category_frame,
                text=f'  Amount: {self.amounts[i]:.2f}',
                background='#F0F0F0',
                foreground='#666666',
                font=('Arial', 10)
            )
            amount_label.pack(side='left', padx=10)

            # Create percentage label
            percent_label = tk.Label(
                category_frame,
                text=f'  Percentage: {self.amounts[i]/sum(self.amounts)*100:.1f}%',
                background='#F0F0F0',
                foreground='#666666',
                font=('Arial', 10)
            )
            percent_label.pack(side='left', padx=10)

        # Update the frame
        self.legend_frame.update_idletasks()

    def update_from_api(self, expenses: list[ExpenseEarningFrequencies]) -> None:
        self.expenses = expenses
        self.categories = [item.name for item in expenses]
        self.amounts = [item.amount for item in expenses]
        self.__plot_piechart(self.categories, self.amounts)
        self.create_legend()

    def on_key_press(self, event: KeyEvent) -> None:
        if event.key == 'a':
            if self.last_toolbar_cmd:
                self.last_toolbar_cmd()
                self.last_toolbar_cmd = None
        elif event.key == 'm' or event.key == 'p':
            self.toolbar.pan()
            self.last_toolbar_cmd = self.toolbar.pan
        elif event.key == 'z':
            self.toolbar.zoom()
            self.last_toolbar_cmd = self.toolbar.zoom

    def __plot_piechart(self, categories: list[str], amounts: list[Decimal]) -> None:
        self.ax.clear()
        self.wedges, texts, autotexts = self.ax.pie(amounts, labels=categories, autopct='%1.1f%%', startangle=90, textprops={'size': 'x-small', 'color': '#333333'}, radius=1.2) # type: ignore
        for wedge in self.wedges:
            wedge.set_picker(True)
            wedge.set_facecolor('#CCCCCC')
            wedge.set_edgecolor('#666666')
        # self.ax.set_title("Expenses by Category",  fontsize=18, color='#333333')
        self.ax.set_aspect('equal')
        self.ax.set_facecolor('#F0F0F0')
        self.ax.spines['bottom'].set_color('#666666')
        self.ax.spines['top'].set_color('#666666')
        self.ax.spines['right'].set_color('#666666')
        self.ax.spines['left'].set_color('#666666')
        self.canvas.draw()

    def __on_click(self, event: PickEvent) -> None:
        def display_all() -> None:
            # if no subcategories are found, go back to the main categories
            self.categories = [item.name for item in self.expenses]
            self.amounts = [item.amount for item in self.expenses]
            self.__plot_piechart(self.categories, self.amounts)

        def display_subcategories() -> bool:
            category_index = self.wedges.index(event.artist) # type: ignore
            category_name = self.categories[category_index]

            for item in self.expenses:
                if item.name == category_name:
                    subcategories = [subitem.name for subitem in item.subcategories]
                    subamounts = [subitem.amount for subitem in item.subcategories]
                    if subcategories:
                        self.categories = subcategories
                        self.amounts = subamounts
                        self.__plot_piechart(self.categories, self.amounts)
                        return True
            return False

        if event.mouseevent and event.mouseevent.button == 3:  # Right click
            display_all()

        elif event.artist and event.mouseevent and event.mouseevent.button == 1: # left click
            if not display_subcategories():
                display_all()

if __name__ == '__main__':
    # Load the JSON data
    with open('expenses.json') as f:
        data = json.load(f)

    # Create the tkinter app
    root = tk.Tk()
    root.title("Expenses Plot")
    root.configure(background='#F0F0F0')

    # Create the expenses plot
    expenses_plot = ExpensesPlot(root, data['result']) # type: ignore

    # Start the tkinter app
    root.mainloop()


why is the legend never visible?