# SPDX-FileCopyrightText: 2024 Luca Weiss
# SPDX-License-Identifier: GPL-3.0-only

import traceback
from gi.repository import Adw
from gi.repository import GLib
from gi.repository import GObject
from gi.repository import Gdk
from gi.repository import Gtk
from .. import esim
from .. import helpers


@Gtk.Template(resource_path="/eu/lucaweiss/lpa-gtk/pages/esimdetail.ui")
class ESimDetailPage(Gtk.Box):
    __gtype_name__ = "LpaGtkESimDetail"

    enable_button = Gtk.Template.Child()
    disable_button = Gtk.Template.Child()
    delete_button = Gtk.Template.Child()
    name_reset_button = Gtk.Template.Child()
    name_row = Gtk.Template.Child()
    overlay = Gtk.Template.Child()

    spn_copy_button = Gtk.Template.Child()
    iccid_copy_button = Gtk.Template.Child()
    isdp_aid_copy_button = Gtk.Template.Child()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.clipboard = Gdk.Display().get_default().get_clipboard()
        self.enable_button.connect("activated", self._enable_button_clicked)
        self.disable_button.connect("activated", self._disable_button_clicked)
        self.delete_button.connect("activated", self._delete_button_clicked)
        self.name_reset_button.connect("clicked", self._reset_name)
        self.name_row.connect("apply", self._set_name)

        self.spn_copy_button.connect("clicked", lambda _: self._copy_item_data(self._profile.service_provider_name))
        self.iccid_copy_button.connect("clicked", lambda _: self._copy_item_data(self._profile.iccid))
        self.isdp_aid_copy_button.connect("clicked", lambda _: self._copy_item_data(self._profile.isdp_aid))

    def set_manager(self, manager: esim.ESimManager) -> None:
        self._manager = manager

    def set_active_slot(self, slot: int) -> None:
        self._active_slot = slot

    def set_profile(self, profile: esim.ESimProfile) -> None:
        self._profile = profile
        self.notify('iccid')
        self.notify('isdp_aid')
        self.notify('state_enabled')
        self.notify('service_provider_name')
        self.notify('name')
        self.notify('name_modified')

    def _copy_item_data(self, text):
        print(f"Copy text: {text}")
        self.clipboard.set(text)
        helpers.show_toast(self.overlay, _("Copied!"))

    def _refresh_profile(self):
        for profile in self._manager.get_profiles(self._active_slot):
            if profile.iccid == self._profile.iccid:
                self.set_profile(profile)
                return
        raise RuntimeError(f"Could not find profile with ICCID {self._profile.iccid}")

    def _enable_button_clicked(self, _button):
        dialog = Adw.AlertDialog.new(_("Enable?"), _("Do you want to enable this profile?"))
        dialog.set_close_response("cancel")
        dialog.add_response("cancel", _("Cancel"))
        dialog.add_response("continue", _("Enable"))
        dialog.set_response_appearance("continue", Adw.ResponseAppearance.SUGGESTED)
        dialog.connect("response", self._enable_profile_response, dialog.choose_finish)
        dialog.present(self)

    def _enable_profile_response(self, _dialog, response_id, _function):
        if response_id == "cancel":
            return

        self._profile.enable()
        self._refresh_profile()

    def _disable_button_clicked(self, _button):
        dialog = Adw.AlertDialog.new(_("Disable?"), _("Do you want to disable this profile?"))
        dialog.set_close_response("cancel")
        dialog.add_response("cancel", _("Cancel"))
        dialog.add_response("continue", _("Disable"))
        dialog.set_response_appearance("continue", Adw.ResponseAppearance.SUGGESTED)
        dialog.connect("response", self._disable_profile_response, dialog.choose_finish)
        dialog.present(self)

    def _disable_profile_response(self, _dialog, response_id, _function):
        if response_id == "cancel":
            return

        self._profile.disable()
        self._refresh_profile()

    def _delete_button_clicked(self, _button):
        dialog = Adw.AlertDialog.new(_("Delete?"), _("Do you want to delete this profile? You cannot undo this action. Depending on the network operator you also cannot reinstall this profile!"))
        dialog.set_close_response("cancel")
        dialog.add_response("cancel", _("Cancel"))
        dialog.add_response("continue", _("Delete"))
        dialog.set_response_appearance("continue", Adw.ResponseAppearance.DESTRUCTIVE)
        dialog.connect("response", self._delete_profile_response, dialog.choose_finish)
        dialog.present(self)

    def _delete_profile_response(self, _dialog, response_id, _function):
        if response_id == "cancel":
            return

        print("Deleting profile...")
        self._profile.delete()
        # Let the world know that we're done here, so we can leave this page
        self.emit("profile-deleted")

    def _set_name(self, entry_row):
        try:
            self._profile.set_nickname(entry_row.get_text())
            # Don't call _refresh_profile() here since it messes with the EntryRow
            # behavior and won't give us anything new anyways since the new
            # name is already shown in the EntryRow.
            # But tell name_modified that it has changed.
            self.notify('name_modified')
        except esim.ESimError as e:
            self._refresh_profile()
            helpers.show_toast_info(self.overlay, self, _("Failed to set name: ") + str(e),
                                    f"<tt>{GLib.markup_escape_text(traceback.format_exc())}</tt>", markup=True)
            print(traceback.format_exc())

    def _reset_name(self, entry_row):
        try:
            self._profile.set_nickname("")
            self._refresh_profile()
        except esim.ESimError as e:
            self._refresh_profile()
            helpers.show_toast_info(self.overlay, self, _("Failed to set name: ") + str(e),
                                    f"<tt>{GLib.markup_escape_text(traceback.format_exc())}</tt>", markup=True)
            print(traceback.format_exc())

    @GObject.Signal
    def profile_deleted(self):
        pass

    @GObject.property(type=str, default="")
    def iccid(self) -> str:
        return self._profile.iccid

    @GObject.property(type=str, default="")
    def isdp_aid(self) -> str:
        return self._profile.isdp_aid

    @GObject.property(type=bool, default=False)
    def state_enabled(self) -> bool:
        return self._profile.state == esim.ESimProfileState.DISABLED

    @GObject.property(type=str, default="")
    def name(self):
        return self._profile.nickname or self._profile.name

    @GObject.property(type=bool, default=False)
    def name_modified(self):
        return bool(self._profile.nickname)

    @GObject.property(type=str, default="")
    def service_provider_name(self):
        return self._profile.service_provider_name
