from pathlib import Path
import copy
import importlib.util
import tkinter as tk
from tkinter import colorchooser


ROOT = Path(__file__).resolve().parents[2]
APP = Path(__file__).resolve().parent
GENERATED = APP / 'generated'
AUTOSAVE = APP / 'autosave.racecore.json'
LIVE_CONFIG = APP / 'live-link-ui.json'
V14_PATH = ROOT / 'outputs' / 'RaceCore_Studio_v1.4' / 'racecore_studio_v14.py'
V14_AUTOSAVE = V14_PATH.parent / 'autosave.racecore.json'

spec = importlib.util.spec_from_file_location('racecore_v14', V14_PATH)
v14 = importlib.util.module_from_spec(spec)
spec.loader.exec_module(v14)

for module in (v14, v14.v13, v14.v13.v12, v14.v13.v12.v11):
    module.APP = APP
    module.GENERATED = GENERATED
    module.AUTOSAVE = AUTOSAVE
    module.LIVE_CONFIG = LIVE_CONFIG

COLORS = v14.COLORS
TEMPLATE_INFO = {
    'Clean GT': 'Rustige, professionele basis met een herkenbaar zijpaneel en dunne dubbele lijn.',
    'Factory Racing': 'Groot kleurvlak met scherpe dubbele race-lijnen op beide zijkanten.',
    'Bold Diagonal': 'Schuine kleurblokken en diagonale lijnen voor een agressieve moderne look.',
    'Center Focus': 'Sterke centrale vorm op motorkap en dak, met rustige zijkanten.',
    'Volledig blanco': 'Alle vormen en strepen verwijderen en vanaf een lege basiskleur beginnen.',
}


def template_layers(name, accent, detail):
    shapes = []
    stripes = []

    def shape(title, colour, width, height, x, y, rotation=0, paired=False,
              kind='Afgerond vlak', opacity=100, roundness=35):
        shapes.append({
            'id': f'template-shape-{len(shapes) + 1}', 'name': title,
            'shape': kind, 'colour': colour, 'width': width, 'height': height,
            'centerX': x, 'centerY': y, 'rotation': rotation,
            'paired': paired, 'opacity': opacity, 'roundness': roundness,
            'visible': True, 'locked': False,
        })

    def stripe(title, colour, length, width, x, y, rotation=0, paired=False,
               kind='Rechte lijn', gap=45, opacity=100):
        stripes.append({
            'id': f'template-stripe-{len(stripes) + 1}', 'name': title,
            'shape': kind, 'colour': colour, 'length': length, 'width': width,
            'centerX': x, 'centerY': y, 'rotation': rotation,
            'paired': paired, 'gap': gap, 'opacity': opacity,
            'visible': True, 'locked': False,
        })

    if name == 'Clean GT':
        shape('Zijpaneel accent', accent, 1180, 500, 2050, 1220, paired=True,
              opacity=88, roundness=55)
        stripe('Dunne dubbele lijn', detail, 1080, 34, 2050, 1220,
               paired=True, kind='Dubbele lijn', gap=36)
    elif name == 'Factory Racing':
        shape('Factory zijvlak', accent, 1320, 600, 2050, 1220, paired=True,
              opacity=100, roundness=28)
        stripe('Factory dubbele lijn', detail, 1180, 62, 2050, 1220,
               paired=True, kind='Dubbele lijn', gap=54)
        shape('Motorkap badge', accent, 720, 330, 3310, 2470, rotation=90,
              opacity=92, roundness=45)
    elif name == 'Bold Diagonal':
        shape('Diagonaal zijvlak', accent, 1320, 560, 2050, 1220,
              rotation=26, paired=True, kind='Rechthoek', opacity=95)
        stripe('Diagonaal contrast', detail, 1250, 64, 2050, 1220,
               rotation=26, paired=True, kind='Dubbele lijn', gap=52)
        shape('Motorkap ruit', accent, 720, 520, 3310, 2470,
              rotation=15, kind='Ruit', opacity=92)
    elif name == 'Center Focus':
        shape('Motorkap centrum', accent, 820, 440, 3310, 2470,
              rotation=90, opacity=95, roundness=55)
        stripe('Motorkap detail', detail, 760, 42, 3310, 2470,
               rotation=90, kind='Dubbele lijn', gap=42)
        shape('Rustig zijaccent', accent, 1020, 360, 2050, 1220,
              paired=True, opacity=65, roundness=70)

    return shapes, stripes


class StudioV15(v14.StudioV14):
    def __init__(self):
        migrate = not AUTOSAVE.exists() and V14_AUTOSAVE.exists()
        super().__init__()
        self.title('RaceCore Livery Studio v1.5 - Quick Start')
        if migrate:
            self.load_path(V14_AUTOSAVE, record=False)
            self.autosave()

    def build_layout(self):
        super().build_layout()
        header = self.winfo_children()[0]
        for child in header.winfo_children():
            if isinstance(child, tk.Label) and 'Livery Studio' in child.cget('text'):
                child.configure(text='Livery Studio  v1.5')
        toolbar = self.winfo_children()[1]
        tk.Button(
            toolbar, text='Startontwerp', command=self.template_wizard,
            font=('Segoe UI', 9, 'bold'), fg=COLORS.NAVY, bg='#C4B5FD',
            activebackground='#DDD6FE', relief='flat', padx=14,
        ).pack(side='left', padx=(0, 8), pady=6)

    def template_wizard(self):
        win = tk.Toplevel(self)
        win.title('RaceCore Startontwerp')
        win.geometry('760x590')
        win.minsize(700, 550)
        win.configure(bg=COLORS.PANEL)
        win.transient(self)
        win.grab_set()

        tk.Label(
            win, text='KIES EEN STARTONTWERP', font=('Segoe UI', 16, 'bold'),
            fg=COLORS.CYAN, bg=COLORS.PANEL,
        ).pack(anchor='w', padx=24, pady=(20, 3))
        tk.Label(
            win,
            text='RaceCore bouwt een complete bewerkbare basis. Daarna kun je elk vlak, elke streep en elk logo aanpassen.',
            font=('Segoe UI', 9), fg=COLORS.MUTED, bg=COLORS.PANEL,
            wraplength=700, justify='left',
        ).pack(anchor='w', padx=24, pady=(0, 12))

        content = tk.Frame(win, bg=COLORS.PANEL)
        content.pack(fill='both', expand=True, padx=24)
        left = tk.Frame(content, bg=COLORS.PANEL)
        left.pack(side='left', fill='both', expand=True, padx=(0, 14))
        right = tk.Frame(content, bg='#101F3C', width=280)
        right.pack(side='right', fill='y')
        right.pack_propagate(False)

        selected = tk.StringVar(value='Clean GT')
        description = tk.StringVar(value=TEMPLATE_INFO['Clean GT'])
        template_list = tk.Listbox(
            left, font=('Segoe UI', 11, 'bold'), bg='#08152C', fg=COLORS.TEXT,
            selectbackground='#7C3AED', relief='flat', activestyle='none',
            exportselection=False, height=8,
        )
        template_list.pack(fill='both', expand=True)
        for name in TEMPLATE_INFO:
            template_list.insert('end', name)
        template_list.selection_set(0)

        tk.Label(
            left, textvariable=description, font=('Segoe UI', 10),
            fg='#C7D2FE', bg=COLORS.PANEL, wraplength=390, justify='left',
        ).pack(anchor='w', pady=(10, 0))

        def select_template(_event=None):
            choice = template_list.curselection()
            if choice:
                name = template_list.get(choice[0])
                selected.set(name)
                description.set(TEMPLATE_INFO[name])

        template_list.bind('<<ListboxSelect>>', select_template)

        base_colour = tk.StringVar(value=self.primary.get())
        accent_colour = tk.StringVar(value='#22D3EE')
        detail_colour = tk.StringVar(value='#FFFFFF')
        keep_logos = tk.BooleanVar(value=True)
        tk.Label(right, text='KLEUREN', font=('Segoe UI', 12, 'bold'),
                 fg=COLORS.CYAN, bg='#101F3C').pack(anchor='w', padx=18, pady=(18, 10))

        colour_buttons = []

        def colour_row(label, variable):
            row = tk.Frame(right, bg='#101F3C')
            row.pack(fill='x', padx=18, pady=5)
            tk.Label(row, text=label, font=('Segoe UI', 9), fg=COLORS.TEXT,
                     bg='#101F3C').pack(side='left')
            button = tk.Button(
                row, textvariable=variable, font=('Consolas', 9, 'bold'),
                width=10, relief='flat',
            )
            button.pack(side='right')
            colour_buttons.append((button, variable))

            def choose():
                value = colorchooser.askcolor(variable.get(), title=label)[1]
                if value:
                    variable.set(value.upper())
                    self.set_colour_button(button, variable.get())

            button.configure(command=choose)
            self.set_colour_button(button, variable.get())

        colour_row('Basiskleur', base_colour)
        colour_row('Hoofddetail', accent_colour)
        colour_row('Contrast', detail_colour)

        tk.Checkbutton(
            right, text='Bestaande logo\'s behouden', variable=keep_logos,
            font=('Segoe UI', 9, 'bold'), fg=COLORS.TEXT, bg='#101F3C',
            selectcolor='#253656', activebackground='#101F3C',
            activeforeground=COLORS.TEXT,
        ).pack(anchor='w', padx=14, pady=(16, 4))
        tk.Label(
            right,
            text='Je kunt na het toepassen alles los bewerken, dupliceren of verwijderen.',
            font=('Segoe UI', 9), fg=COLORS.MUTED, bg='#101F3C',
            wraplength=235, justify='left',
        ).pack(anchor='w', padx=18, pady=5)

        def apply_template():
            shapes, stripes = template_layers(
                selected.get(), accent_colour.get(), detail_colour.get()
            )
            self.loading = True
            self.blank_mode = True
            self.primary.set(base_colour.get())
            self.accent.set(detail_colour.get())
            self.width.set(100)
            self.preset.set('Geen strepen')
            self.shape_layers = [self.normalise_shape(item) for item in shapes]
            self.stripe_layers = [self.normalise_stripe(item) for item in stripes]
            if not keep_logos.get():
                self.logo_layers = []
            self.loading = False
            self.refresh_main_colours()
            if hasattr(self, 'shape_list'):
                self.refresh_shapes()
            if hasattr(self, 'stripe_list'):
                self.refresh_stripes()
            if hasattr(self, 'layer_list'):
                self.refresh_layers()
            win.destroy()
            self.changed()
            self.status.set(f'Startontwerp {selected.get()} toegepast')

        actions = tk.Frame(win, bg=COLORS.PANEL)
        actions.pack(fill='x', padx=24, pady=18)
        tk.Button(
            actions, text='ANNULEREN', command=win.destroy,
            font=('Segoe UI', 9, 'bold'), fg=COLORS.TEXT, bg='#475569',
            relief='flat', pady=10,
        ).pack(side='left', fill='x', expand=True, padx=(0, 5))
        tk.Button(
            actions, text='MAAK MIJN STARTONTWERP', command=apply_template,
            font=('Segoe UI', 10, 'bold'), fg=COLORS.NAVY, bg=COLORS.CYAN,
            relief='flat', pady=10,
        ).pack(side='left', fill='x', expand=True, padx=(5, 0))

    @staticmethod
    def set_colour_button(button, colour):
        r, g, b = v14.v13.v12.v11.v10.v09.v08.base.rgb(colour)
        fg = '#000000' if (r * 299 + g * 587 + b * 114) > 150000 else '#FFFFFF'
        button.configure(bg=colour, fg=fg, activebackground=colour, activeforeground=fg)

    def refresh_main_colours(self):
        wanted = {str(self.primary): self.primary.get(), str(self.accent): self.accent.get()}

        def visit(parent):
            for child in parent.winfo_children():
                if isinstance(child, tk.Button):
                    variable = str(child.cget('textvariable'))
                    if variable in wanted:
                        self.update_swatch(child, wanted[variable])
                visit(child)

        visit(self)


if __name__ == '__main__':
    StudioV15().mainloop()
