"""
Panorama weather: weather app for GNU/Linux desktops.
Copyright 2026, roundabout-host.com <vlad@roundabout-host.com>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public Licence as published by
the Free Software Foundation, either version 3 of the Licence, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public Licence for more details.

You should have received a copy of the GNU General Public Licence
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""

import os
import sys
import json

import gi

from pathlib import Path

gi.require_version("Gtk", "4.0")

from gi.repository import Gtk, Gio, GLib, Gdk


module_directory = Path(__file__).resolve().parent


custom_css = """
.panorama-weather-current-temperature {
    font-weight: 100;
    font-size: 5rem;
}
"""
css_provider = Gtk.CssProvider()
css_provider.load_from_data(custom_css)
Gtk.StyleContext.add_provider_for_display(
    Gdk.Display.get_default(),
    css_provider,
    100
)


@Gtk.Template(filename=str(module_directory / "panorama-weather-report.ui"))
class WeatherReport(Gtk.Box):
    __gtype_name__ = "WeatherReport"

    current_details: Gtk.Label = Gtk.Template.Child()
    current_temperature: Gtk.Label = Gtk.Template.Child()
    current_weather_icon: Gtk.Image = Gtk.Template.Child()
    
    def __init__(self, data, **kwargs):
        super().__init__(**kwargs)

        self.current_weather_icon.set_from_icon_name(data["icon_name"])
        self.current_temperature.set_text(data["temp"])


@Gtk.Template(filename=str(module_directory / "panorama-weather.ui"))
class WeatherWindow(Gtk.Window):
    __gtype_name__ = "WeatherWindow"

    sidebar_revealer: Gtk.Revealer = Gtk.Template.Child()
    sidebar: Gtk.Box = Gtk.Template.Child()
    inner_sidebar: Gtk.Box = Gtk.Template.Child()
    drag_handle: Gtk.Separator = Gtk.Template.Child()
    weather_stack: Gtk.Stack = Gtk.Template.Child()

    def sidebar_revealer_change(self, action, state):
        action.set_state(state)
        self.sidebar_revealer.set_reveal_child(state.get_boolean())

    def begin_drag(self, gesture, start_x, start_y):
        x_win, y_win = self.drag_handle.translate_coordinates(self, start_x, start_y)
        gesture.widget_to_update.start_w = gesture.widget_to_update.get_width()
        gesture.widget_to_update.start_x = x_win
        gesture.start_x = start_x

    def update_drag(self, gesture, dx, dy):
        x_win, y_win = self.drag_handle.translate_coordinates(self, dx + gesture.start_x, 0)
        gesture.widget_to_update.set_size_request(gesture.widget_to_update.start_w + x_win - gesture.widget_to_update.start_x, -1)

    def set_window_title(self, stack, *args):
        self.set_title(stack.get_page(stack.get_visible_child()).get_title())

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.sidebar_revealer.set_hexpand(False)
        self.weather_stack.set_hexpand(True)
        self.weather_stack.set_halign(Gtk.Align.FILL)
        self.weather_stack.connect("notify::visible-child", self.set_window_title)

        self.action_group = Gio.SimpleActionGroup()
        self.sidebar_action = Gio.SimpleAction.new_stateful("reveal-sidebar", None, GLib.Variant.new_boolean(True))
        self.sidebar_action.connect("change-state", self.sidebar_revealer_change)
        self.action_group.add_action(self.sidebar_action)
        self.insert_action_group("win", self.action_group)

        drag_controller = Gtk.GestureDrag()
        drag_controller.widget_to_update = self.sidebar
        drag_controller.connect("drag-begin", self.begin_drag)
        drag_controller.connect("drag-update", self.update_drag)
        self.drag_handle.add_controller(drag_controller)
        self.drag_handle.set_cursor(Gdk.Cursor.new_from_name("ew-resize"))

    def read_all(self):
        application: PanoramaWeather = self.get_application()
        # Read the weather files
        for file in application.data_directory.iterdir():
            with open(file, "r") as f:
                data = json.load(f)
                self.weather_stack.add_titled(WeatherReport(data), None, data["location"]["name"])


class PanoramaWeather(Gtk.Application):
    def __init__(self):
        super().__init__(
                application_id="com.roundabout_host.roundabout.PanoramaWeather"
        )
        self.data_directory = Path(os.environ.get("XDG_DATA_HOME", "~/.local/share")).expanduser() / "weather" / "data" / "locations"

    def do_startup(self):
        Gtk.Application.do_startup(self)

    def do_shutdown(self):
        Gtk.Application.do_shutdown(self)

    def do_activate(self):
        Gtk.Application.do_activate(self)

        window = WeatherWindow()
        self.add_window(window)
        window.present()
        window.read_all()


if __name__ == "__main__":
    app = PanoramaWeather()
    app.run(sys.argv)
