# Copyright 2021 Vincent Texier <vit@free.fr>
#
# This software 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 software 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 <http://www.gnu.org/licenses/>.

from typing import Callable

from PyQt5.QtCore import QObject, pyqtSignal

from tikka.domains.entities.account import Account
from tikka.domains.entities.category import Category
from tikka.domains.entities.identity import Identity


class EventBus(QObject):
    """
    EventBus class
    """

    # singleton pattern
    _instance = None

    #########################################
    # SIGNALS ###############################
    #########################################

    # main window
    main_window_shown = pyqtSignal()
    repository_data_updated = pyqtSignal()
    user_data_restored = pyqtSignal()

    # categories
    category_added = pyqtSignal(Category)
    category_deleted = pyqtSignal(Category)

    # accounts
    account_added = pyqtSignal(Account)
    account_forgotten = pyqtSignal(Account)
    account_renamed = pyqtSignal(Account)
    account_wallet_updated = pyqtSignal(Account)
    account_selected = pyqtSignal(Account)
    account_balances_updated = pyqtSignal(list)
    account_identities_updated = pyqtSignal(list)
    account_profiles_updated = pyqtSignal(list)

    # transfers
    transfer_sent = pyqtSignal(list)

    # identities
    identity_created = pyqtSignal(Identity, Identity)
    identity_confirmed = pyqtSignal(Identity)
    identity_certified = pyqtSignal(Identity, Identity)
    identity_account_changed = pyqtSignal(Account, Account)
    identities_updated = pyqtSignal(list)

    # profile cesium+
    profile_account_changed = pyqtSignal(Account, Account)

    # currency
    currency_changed = pyqtSignal(str, str)
    currency_closed = pyqtSignal(str)
    currency_opened = pyqtSignal(str)

    # servers
    node_connected = pyqtSignal()
    indexer_connected = pyqtSignal()
    datapod_connected = pyqtSignal()
    node_disconnected = pyqtSignal()
    indexer_disconnected = pyqtSignal()
    datapod_disconnected = pyqtSignal()

    @classmethod
    def instance(cls, parent=None):
        """
        Initialize Singleton instance

        :param parent: QObject instance
        :return:
        """
        if cls._instance is None:
            cls._instance = cls(parent)
        return cls._instance

    def __init__(self, parent=None):
        """
        Initialize EventBus instance

        :param parent: QObject instance
        """
        super().__init__(parent)

    def connect(self, signal: pyqtSignal, slot: Callable):
        """
        Debug connect

        :param signal: pyqtSignal instance
        :param slot: Callable
        :return:
        """
        print(f"DEBUG: Connection {signal} -> {slot}")
        result = signal.connect(slot)  # type: ignore
        return result

    def emit(self, signal, *args):
        """
        Debug emit

        :param signal: pyqtSignal instance
        :param args: Arguments
        :return:
        """
        print(f"DEBUG: Emit signal {signal} with args: {args}")
        print(f"DEBUG: Receivers: {signal.receivers()}")
        signal.emit(*args)
