import math

from core.aochat.BaseModule import BaseModule
from core.chat_blob import ChatBlob
from core.command_param_types import Int, NamedParameters
from core.db import DB
from core.decorators import instance, command
from core.igncore import IgnCore
from core.text import Text


# noinspection DuplicatedCode
@instance()
class ContractController(BaseModule):
    PAGE_SIZE = 40

    # noinspection DuplicatedCode
    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")

    @command(command="contracts",
             params=[Int('mininum', is_optional=True), NamedParameters(['page'])],
             access_level="member",
             description="Shows contracts")
    def cotracts(self, _, min_ql, named_params):
        if not min_ql:
            min_ql = 200
        data = self.db.query("SELECT e.*, CAST(SUM(ql)*2 AS INTEGER) AS contracts, COUNT(*) AS sites FROM towers a "
                             "LEFT JOIN all_orgs e on a.org_id = e.org_id WHERE close_time IS NOT NULL "
                             "GROUP BY org_name ORDER BY contracts desc", [])
        page = int(named_params.page or "1")
        offset = (page - 1) * self.PAGE_SIZE
        data = [x for x in data if x.contracts and x.contracts > min_ql]
        return self.format_pagination(data, offset, page, f"Tower Contracts ({len(data)})",
                                      f"There are no orgs with more than "
                                      f"<highlight>{min_ql}</highlight> contract points.",
                                      f'contracts {min_ql}')

    def format_pagination(self, data, offset, page, title, nullmsg, cmd):
        selected = data[offset:offset + self.PAGE_SIZE]
        count = len(selected)
        pages = ""
        if page > 1:
            pages += "Pages:   " + self.text.make_tellcmd(f"«« Page {page - 1:d}", f'{cmd} --page={page - 1}')
        if offset + self.PAGE_SIZE < len(data):
            pages += f"   Page {page}/{math.ceil(len(data) / self.PAGE_SIZE)}"
            pages += "   " + self.text.make_tellcmd(f"Page {page + 1:d} »»", f'{cmd} --page={page + 1}')
        pages += "\n"
        if count == 0:
            return nullmsg
        else:
            blob = ""
            blob += "" + pages + "\n"
            index = offset
            for entry in selected:
                index += 1
                blob += self.row_formatter(entry, index, data)
            blob += "\n" + pages
            blob += "</font>"
            return ChatBlob(title, blob)

    def row_formatter(self, entry, index, data):
        return f"{self.text.zfill(index, len(data))}. " \
               f"<white>{self.text.zfill(entry.contracts, data[0].contracts)}</white> " \
               f"<{entry.faction.lower()}>{entry.org_name}</{entry.faction.lower()}>\n"
