from core.command_service import CommandService
from core.decorators import instance, command
from modules.core.accounting.preference_controller import PreferenceController
from modules.core.accounting.services.account_service import AccountService


@instance(name="account_service", override=True)
class AccountServiceOnlineBot(AccountService):
    registered = []

    def inject(self, registry):
        super().inject(registry)
        self.preference_controller: PreferenceController = registry.get_instance("preference_controller")

    def pre_start(self):
        super().pre_start()
        self.db.exec("CREATE TABLE IF NOT EXISTS registered (char_id int primary key)")
        self.registered = [x.char_id for x in self.db.query("SELECT * from registered")]
        self.access_service.register_access_level("unregistered", 95, self.check_unregistered)

    @command(command="opt-in", params=[],
             description="Register yourself in the bot",
             access_level="unregistered")
    def cmd_opt_in(self, request):
        player = self.pork.get_character_info(request.sender.name)
        if player.org_id in self.get_orgs():
            if self.is_registered((main := self.get_main(request.sender.char_id)).char_id):
                return "You're already registered."
            self.db.exec("INSERT IGNORE INTO registered VALUES (?)", [main.char_id])
            pref_autoinvite = int(self.setting_service.get_value("pref_autoinvite"))
            pref_raidinvite = int(self.setting_service.get_value("pref_raidinvite"))
            pref_raidspam = int(self.setting_service.get_value("pref_raidspam"))
            pref_newsspam = int(self.setting_service.get_value("pref_newsspam"))
            self.registered.append(main.char_id)

            self.preference_controller.set_pref(main.char_id, "news", pref_newsspam)
            self.preference_controller.set_pref(main.char_id, "raidspam", pref_raidspam)
            self.preference_controller.set_pref(main.char_id, "autoinvite", pref_autoinvite)

            # This one is of no use in Onlinebots,
            # as the command taking advantage of it
            # is only implemented in the raidbot modules.
            # raidspam is used instead.
            self.preference_controller.set_pref(main.char_id, "raidinvite", pref_raidinvite)

            return "You've been registered successfully, and your preferences have been set to the defaults."

    @command(command="opt-out", params=[],
             description="Unregister yourself from the bot",
             access_level="member")
    def cmd_opt_out(self, request):
        main = self.get_main(request.sender.char_id)
        if self.is_registered(main.char_id):
            self.db.exec("DELETE FROM registered where char_id = ?", [main.char_id])
            self.registered.remove(main.char_id)
            self.db.exec("UPDATE account SET disabled=1 where char_id=?", [main.char_id])
            return "You've been unregistered successfully. For re-registering, " \
                   "you may need to contact an Administrator, " \
                   "as you may only register once as a spam protection. " \
                   "Further tells will get ignored."
        else:
            return "You're not registered, and thus cannot unregister yourself."

    def is_registered(self, char_id):
        return char_id in self.registered

    def simple_checks(self, account):
        main = account.get("main", -1)
        if main and main in self.registered:
            return super().simple_checks(account)
        return False

    def check_unregistered(self, char_id) -> bool:
        account = self.get_account(char_id) or {}
        return super().simple_checks(account)

    def check_member(self, char_id) -> bool:
        account = self.get_account(char_id) or {}
        if self.simple_checks(account):
            return True
        return False


@instance(name="command_service", override=True)
class AccountServiceOnlineBot(CommandService):
    def access_denied_response(self, message, sender, cmd_config, reply):
        self.relay_hub_service.send_message("access_denied_logger", sender, f"[DENIED] {sender.name}: {message}",
                                            f"[DENIED] {sender.name}:  {message}")

        if sender.access_level["label"] != "all":
            if sender.access_level['label'] == "unregistered":
                self.bot.send_mass_message(sender.char_id,
                                           "You are not registered yet. To gain access to my commands, you'll need to use <highlight><symbol>opt-in</highlight>")
                return
            self.bot.send_mass_message(sender.char_id, self.getresp("global", "access_denied"))
