# preferences_dialog.py
#
# Copyright 2025 Pavel Baksy
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, 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 License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
#
# SPDX-License-Identifier: GPL-3.0-or-later

import logging
from gi.repository import Adw, Gtk, Gio, GObject

logger = logging.getLogger(__name__)


@Gtk.Template(resource_path='/cz/bugsy/roster/preferences-dialog.ui')
class PreferencesDialog(Adw.PreferencesWindow):
    __gtype_name__ = 'PreferencesDialog'

    tls_verification_row = Gtk.Template.Child()
    timeout_row = Gtk.Template.Child()
    clear_history_button = Gtk.Template.Child()
    data_folder_row = Gtk.Template.Child()
    open_folder_button = Gtk.Template.Child()
    backup_folder_row = Gtk.Template.Child()
    choose_backup_folder_button = Gtk.Template.Child()
    auto_backup_row = Gtk.Template.Child()
    backup_now_button = Gtk.Template.Child()

    __gsignals__ = {
        'history-cleared': (GObject.SIGNAL_RUN_FIRST, None, ())
    }

    def __init__(self, history_manager=None, project_manager=None, **kwargs):
        super().__init__(**kwargs)

        self.history_manager = history_manager
        self.project_manager = project_manager

        self.settings = Gio.Settings.new('cz.bugsy.roster')

        self.settings.bind(
            'force-tls-verification',
            self.tls_verification_row,
            'active',
            Gio.SettingsBindFlags.DEFAULT
        )
        self.settings.bind(
            'request-timeout',
            self.timeout_row,
            'value',
            Gio.SettingsBindFlags.DEFAULT
        )
        self.settings.bind(
            'backup-auto-export',
            self.auto_backup_row,
            'active',
            Gio.SettingsBindFlags.DEFAULT
        )

        # Populate data folder path
        if project_manager is not None:
            self.data_folder_row.set_subtitle(str(project_manager.data_dir))

        # Populate backup folder path
        self._update_backup_folder_subtitle()
        self.settings.connect('changed::backup-folder', lambda *_: self._update_backup_folder_subtitle())

        # Disable backup buttons when no backup folder is set
        self._update_backup_button_sensitivity()
        self.settings.connect('changed::backup-folder', lambda *_: self._update_backup_button_sensitivity())

    def _update_backup_folder_subtitle(self):
        folder = self.settings.get_string('backup-folder')
        self.backup_folder_row.set_subtitle(folder if folder else 'Not set')

    def _update_backup_button_sensitivity(self):
        has_folder = bool(self.settings.get_string('backup-folder'))
        self.backup_now_button.set_sensitive(has_folder)
        self.auto_backup_row.set_sensitive(has_folder)

    @Gtk.Template.Callback()
    def on_clear_history_clicked(self, button):
        if not self.history_manager:
            return

        dialog = Adw.AlertDialog.new(
            "Clear All History?",
            "This will permanently delete all saved request and response history. This action cannot be undone."
        )
        dialog.add_response("cancel", "Cancel")
        dialog.add_response("clear", "Clear History")
        dialog.set_response_appearance("clear", Adw.ResponseAppearance.DESTRUCTIVE)
        dialog.set_default_response("cancel")
        dialog.set_close_response("cancel")

        def on_response(dialog, response):
            if response == "clear":
                self.history_manager.clear_history()
                self.emit('history-cleared')

        dialog.connect("response", on_response)
        dialog.present(self)

    @Gtk.Template.Callback()
    def on_open_folder_clicked(self, button):
        if self.project_manager is None:
            return
        Gio.AppInfo.launch_default_for_uri(
            f"file://{self.project_manager.data_dir}", None
        )

    @Gtk.Template.Callback()
    def on_choose_backup_folder_clicked(self, button):
        chooser = Gtk.FileChooserNative.new(
            "Choose Backup Folder",
            self,
            Gtk.FileChooserAction.SELECT_FOLDER,
            "Select",
            "Cancel"
        )

        current = self.settings.get_string('backup-folder')
        if current:
            try:
                chooser.set_current_folder(Gio.File.new_for_path(current))
            except Exception:
                pass

        def on_response(chooser, response):
            if response == Gtk.ResponseType.ACCEPT:
                folder = chooser.get_file()
                if folder:
                    self.settings.set_string('backup-folder', folder.get_path())

        chooser.connect('response', on_response)
        chooser.show()

    @Gtk.Template.Callback()
    def on_backup_now_clicked(self, button):
        if self.project_manager is None:
            return
        folder = self.settings.get_string('backup-folder')
        if not folder:
            return

        try:
            self.project_manager.export_to_folder(folder)
            toast = Adw.Toast.new("Backup completed")
            self.add_toast(toast)
        except Exception as e:
            logger.error("Backup failed: %s", e)
            toast = Adw.Toast.new("Backup failed")
            self.add_toast(toast)
