from core.chat_blob import ChatBlob
from core.command_alias_service import CommandAliasService
from core.command_param_types import Any, Int, Const
from core.db import DB
from core.decorators import command, instance
from core.lookup.character_service import CharacterService
from core.setting_service import SettingService
from core.text import Text
from core.igncore import IgnCore
from core.util import Util
from modules.core.accounting.services.account_service import AccountService


@instance()
class PresetController:
    def __init__(self):
        pass

    def inject(self, registry):
        self.bot: IgnCore = registry.get_instance("bot")
        self.db: DB = registry.get_instance("db")
        self.text: Text = registry.get_instance("text")
        self.character_service: CharacterService = registry.get_instance("character_service")
        self.util: Util = registry.get_instance("util")
        self.setting_service: SettingService = registry.get_instance("setting_service")
        self.command_alias_service: CommandAliasService = registry.get_instance("command_alias_service")
        self.account_service: AccountService = registry.get_instance("account_service")

    def start(self):
        self.command_alias_service.add_alias("startauc", "auction start")
        self.command_alias_service.add_alias("bid", "auction bid")
        if self.db.query_single("SELECT COUNT(*) AS count FROM points_presets").count < 1:
            # Populate with pre-made presets if empty
            sql = "INSERT INTO points_presets (name, points) VALUES " \
                  "('Killed Sideboss', 1), " \
                  "('Killed TNH', 2), " \
                  "('Killed Beast', 3), " \
                  "('Alien Playfield', 3), " \
                  "('Wipe: Clan', 1), " \
                  "('Wipe: Omni', 1), " \
                  "('Bonus', 1), " \
                  "('Tara', 2), " \
                  "('S42/Boss', 2), " \
                  "('S42/Endboss', 4)"
            self.db.exec(sql, [])

    @command(command="presets", params=[Const("add"), Any("name"), Int("points")], access_level="superadmin",
             description="Add new points preset", sub_command="mod")
    def presets_add_cmd(self, _1, _2, name: str, points: int):
        count = self.db.query_single("SELECT COUNT(*) AS count FROM points_presets WHERE name = ?", [name]).count

        if count > 0:
            return "A preset already exists with the name <highlight>%s<end>." % name

        sql = "INSERT INTO points_presets (name, points) VALUES (?,?)"
        if self.db.exec(sql, [name, points]) > 0:
            return f"A preset with the name <highlight>{name}<end> was added, worth <green>{points:d}<end> points."

        return "Failed to insert new preset in DB."

    @command(command="presets", params=[Const("rem"), Int("preset_id")], access_level="superadmin",
             description="Delete preset", sub_command="mod")
    def presets_rem_cmd(self, _1, _2, preset_id: int):
        if self.db.exec("DELETE FROM points_presets WHERE preset_id = ?", [preset_id]) > 0:
            return "Successfully removed preset with ID <highlight>%d<end>." % preset_id

        return "No preset with given ID <highlight>%d<end>." % preset_id

    @command(command="presets",
             params=[Const("alter"), Int("preset_id"), Int("new_points")],
             access_level="superadmin",
             description="Alter the points dished out by given preset", sub_command="mod")
    def presets_alter_cmd(self, _1, _2, preset_id: int, new_points: int):
        preset = self.db.query_single("SELECT * FROM points_presets WHERE preset_id = ?", [preset_id])

        if preset:
            if self.db.exec("UPDATE points_presets SET points = ? WHERE preset_id = ?", [new_points, preset_id]) > 0:
                return f"Successfully updated the preset, <highlight>{preset.name}<end>, " \
                       f"to dish out <green>{new_points:d}<end> points instead of <red>{preset.points:d}<end>."

            return "Failed to update preset with ID <highlight>%d<end>." % preset_id

    @command(command="presets", params=[], access_level="admin",
             description="See list of points presets")
    def presets_cmd(self, _):
        return ChatBlob("Points presets", self.build_preset_list)

    @property
    def build_preset_list(self):
        presets = self.db.query("SELECT * FROM points_presets ORDER BY name, points DESC")

        if presets:
            blob = ""

            for preset in presets:
                add_points_link = self.text.make_chatcmd("Add pts", f"/tell <myname> raid addpts {preset.name}")
                delete_link = self.text.make_chatcmd("Delete", f"/tell <myname> presets rem {preset.preset_id:d}")
                blob += f"<highlight>{preset.name}<end> worth <green>{preset.points:d}<end> points " \
                        f"[id: {preset.preset_id:d}]\n | [{add_points_link}] [{delete_link}]\n\n"

            return blob

        return "No presets available. " \
               "To add new presets use <highlight><symbol>presets add preset_name preset_points<end>."
