from core.buddy_service import BuddyService
from core.chat_blob import ChatBlob
from core.command_alias_service import CommandAliasService
from core.db import DB
from core.decorators import instance, command
from core.logger import Logger
from core.lookup.pork_service import PorkService
from core.text import Text
from core.igncore import IgnCore
from core.util import Util
from modules.core.accounting.services.access_service import AccessService
from core.command_param_types import Const, Any


# noinspection DuplicatedCode
@instance()
class OrgAliasController:
    prefix_cache = {}

    def inject(self, registry):
        self.logger = Logger(__name__)
        self.bot: IgnCore = registry.get_instance("bot")
        self.db: DB = registry.get_instance("db")
        self.text: Text = registry.get_instance("text")
        self.util: Util = registry.get_instance("util")
        self.pork: PorkService = registry.get_instance("pork_service")
        self.org_pork: PorkService = registry.get_instance("org_pork_service")
        self.command_alias_service: CommandAliasService = registry.get_instance("command_alias_service")
        self.buddy_service: BuddyService = registry.get_instance("buddy_service")
        self.access_service: AccessService = registry.get_instance("access_service")

    def start(self):
        self.db.exec("CREATE TABLE IF NOT EXISTS org_alias(org_id int primary key not null, org_alias VARCHAR(255))")
        for entry in self.db.query("SELECT * from org_alias"):
            self.prefix_cache[entry.org_id] = entry.org_alias

    def get_alias(self, org_id):
        return self.prefix_cache.get(org_id, "-UKN-")

    @command(command="orgs", params=[Const("alias"), Const("list", is_optional=True)], access_level="member",
             description="View the currently registered org aliases", sub_command="alias_info")
    def cmd_alias_list(self, request, _, _1):
        alias_list = self.db.query("SELECT ao.org_id, ao.org_name, a.org_alias, (!ISNULL(o.org_id)) as member FROM org_alias a LEFT JOIN all_orgs ao on a.org_id = ao.org_id "
                                   "LEFT JOIN orgs o on a.org_id = o.org_id "
                                   "ORDER BY ISNULL(o.org_id), LOWER(ao.org_name)")
        blob = []
        last = -1
        for alias in alias_list:
            if last != alias.member:
                if alias.member == 1:
                    blob.append("<header>Members:</header>")
                elif alias.member == 0:
                    blob.append("\n<header>Other Aliases:</header>")
                last = alias.member
            blob.append(f" [<highlight>{alias.org_alias}</highlight>] - <highlight>{alias.org_name}</highlight> ({alias.org_id})")
        return ChatBlob("Aliases currently in use", "\n".join(blob))

    @command(command="orgs", params=[Const("alias"), Const("set"), Any("alias"), Any("org")], access_level="moderator",
             description="Set the alias for an Org",
             sub_command="alias_moderate")
    def cmd_alias_add(self, sender, _,  _1, alias, search):
        orgs = self.org_pork.find_org(search)
        if len(orgs) == 1:
            orgs = orgs[0]
            if self.db.exec("REPLACE INTO org_alias(org_id, org_alias) VALUES (?, ?)", [orgs.org_id, alias]):
                self.prefix_cache[orgs.org_id] = alias
                return f"Alias for <highlight>{orgs.org_name}<end> has been set to [<highlight>{alias}</highlight>]."

            else:
                return f"There's already an alias for <highlight>{orgs.org_name}<end>.. its [<highlight>{self.get_alias(orgs.org_id)}</highlight>]"
        elif len(orgs) == 0:
            return f"No org with the name <highlight>{search}<end> was found on PoRK."
        else:
            blob = "Your search had multiple results; please pick an org:<br>"
            for org in orgs:
                blob += f'[{self.text.make_chatcmd("Set Alias", f"/tell <myname> orgs alias set {alias} {org.org_id}")}]' \
                        f'[{self.text.make_chatcmd("More", f"/tell <myname> orgs info {org.org_id}")}]' \
                        f' <highlight>{org.org_name}<end> (<highlight>{org.org_id}<end>) ' \
                        f'<{org.faction.lower()}>{org.faction}<end> [<highlight>{org.member_count}<end> members]' \
                        f'<br><pagebreak>'
            return ChatBlob("Pick an Org", blob)

    @command(command="orgs", params=[Const("alias"), Const("rem"), Any("org")], access_level="moderator",
             description="remove an Org alias",
             sub_command="alias_moderate")
    def cmd_alias_del(self, sender, _,  _1, search):
        orgs = self.org_pork.find_org(search)
        if len(orgs) == 1:
            orgs = orgs[0]
            if self.db.exec("DELETE FROM org_alias where org_id=?", [orgs.org_id]) == 1:
                self.prefix_cache.pop(orgs.org_id)
                return f"Alias for <highlight>{orgs.org_name}<end> has been removed."
            else:
                return f"There's no alias for <highlight>{orgs.org_name}<end>.."
        elif len(orgs) == 0:
            return f"No org with the name <highlight>{search}<end> was found on PoRK."
        else:
            blob = "Your search had multiple results; please pick an org:<br>"
            for org in orgs:
                blob += f'[{self.text.make_chatcmd("Set Alias", f"/tell <myname> orgs alias rem {org.org_id}")}]' \
                        f'[{self.text.make_chatcmd("More", f"/tell <myname> orgs info {org.org_id}")}]' \
                        f' <highlight>{org.org_name}<end> (<highlight>{org.org_id}<end>) ' \
                        f'<{org.faction.lower()}>{org.faction}<end> [<highlight>{org.member_count}<end> members]' \
                        f'<br><pagebreak>'
            return ChatBlob("Pick an Org", blob)
