# Copyright 2026, Jiri Eischmann <jiri@eischmann.cz> and the meshy contributors
# SPDX-License-Identifier: GPL-3.0-or-later

import gi

gi.require_version("Gtk", "4.0")
gi.require_version("Gdk", "4.0")
gi.require_version("Adw", "1")
from gi.repository import Adw, Gdk, Gtk
from meshy.theme_manager import THEMES, ThemeManager


@Gtk.Template(resource_path="/page/codeberg/sesivany/Meshy/ui/theme-chooser-dialog.ui")
class ThemeChooserDialog(Adw.Dialog):
    __gtype_name__ = "MeshyThemeChooserDialog"

    flow_box = Gtk.Template.Child()

    def __init__(self, settings, on_theme_changed_cb, **kwargs):
        super().__init__(**kwargs)

        self._settings = settings
        self._on_theme_changed_cb = on_theme_changed_cb

        current = settings.get_string("custom-theme")
        self._buttons = {}
        self._tile_provider = Gtk.CssProvider()
        Gtk.StyleContext.add_provider_for_display(
            Gdk.Display.get_default(),
            self._tile_provider,
            Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
        )

        css_parts = []
        for theme_id, theme in THEMES.items():
            btn = self._create_tile(theme_id, theme, theme_id == current)
            self.flow_box.append(btn)
            self._buttons[theme_id] = btn
            css_parts.append(self._tile_css(theme_id, theme))

        self._tile_provider.load_from_string("\n".join(css_parts))

    def _create_tile(self, theme_id, theme, selected):
        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)

        color_box = Gtk.Box(hexpand=True, vexpand=True)
        color_box.set_size_request(100, 50)
        color_box.add_css_class(f"theme-preview-{theme_id}")
        color_box.add_css_class("theme-tile")

        if theme.get("accent"):
            accent_bar = Gtk.Box(hexpand=True, height_request=6)
            accent_bar.add_css_class(f"theme-accent-{theme_id}")
            accent_bar.set_valign(Gtk.Align.END)
            overlay = Gtk.Overlay()
            overlay.set_child(color_box)
            overlay.add_overlay(accent_bar)
            box.append(overlay)
        else:
            box.append(color_box)

        label = Gtk.Label(label=theme["name"])
        label.add_css_class("caption")
        box.append(label)

        btn = Gtk.ToggleButton()
        btn.set_child(box)
        btn.add_css_class("flat")
        btn.set_active(selected)
        btn.connect("toggled", self._on_toggled, theme_id)

        return btn

    def _on_toggled(self, button, theme_id):
        if not button.get_active():
            return
        for tid, btn in self._buttons.items():
            if tid != theme_id:
                btn.set_active(False)
        ThemeManager.get_default().set_custom_theme(theme_id)
        if self._on_theme_changed_cb:
            self._on_theme_changed_cb()

    @staticmethod
    def _tile_css(theme_id, theme):
        if theme.get("background"):
            r, g, b = theme["background"][:3]
            bg = f"rgb({int(r*255)},{int(g*255)},{int(b*255)})"
        else:
            bg = "@window_bg_color"

        if theme.get("foreground"):
            r, g, b = theme["foreground"][:3]
            fg = f"rgb({int(r*255)},{int(g*255)},{int(b*255)})"
        else:
            fg = "@window_fg_color"

        parts = [f".theme-preview-{theme_id} {{ background-color: {bg}; color: {fg}; }}"]

        if theme.get("accent"):
            r, g, b = theme["accent"][:3]
            accent = f"rgb({int(r*255)},{int(g*255)},{int(b*255)})"
            parts.append(
                f".theme-accent-{theme_id} {{ background-color: {accent}; border-radius: 0 0 12px 12px; }}"
            )

        return "\n".join(parts)
