import time

from core.buddy_service import BuddyService
from core.command_param_types import Character, Int
from core.decorators import event, instance, command
from core.logger import Logger
from core.lookup.character_service import CharacterService
from core.text import Text
from core.translation_service import TranslationService
from core.igncore import IgnCore
from modules.core.accounting.services.account_service import AccountService


@instance()
class NotifyController:

    def __init__(self):
        self.logger = Logger(__name__)

    def inject(self, registry):
        self.bot: IgnCore = registry.get_instance("bot")
        self.db = registry.get_instance("db")
        self.util = registry.get_instance("util")
        self.text: Text = registry.get_instance("text")
        self.alts: AccountService = registry.get_instance("account_service")
        self.buddy_service: BuddyService = registry.get_instance("buddy_service")
        self.character_service: CharacterService = registry.get_instance("character_service")
        self.ts: TranslationService = registry.get_instance("translation_service")
        self.getresp = self.ts.get_response

    def start(self):
        self.db.exec("CREATE TABLE IF NOT EXISTS notify_log (id INT PRIMARY KEY AUTO_INCREMENT, char_id INT NOT NULL, "
                     "status TINYINT NOT NULL, time INT NOT NULL DEFAULT 0)")

    @event(event_type=BuddyService.BUDDY_LOGON_EVENT, description="Record last seen info", is_hidden=True)
    def notify_logon_event(self, event_type, event_data):
        self.update_last_seen(event_data)

    @event(event_type=BuddyService.BUDDY_LOGOFF_EVENT, description="Record last seen info", is_hidden=True)
    def notify_logoff_event(self, event_type, event_data):
        self.update_last_seen(event_data)

    @command(command="lastseen",
             params=[Character("character"), Int("number_of_entries", is_optional=True)],
             access_level="org_member",
             description="View when someone was last online")
    def lastseen_limited_cmd(self, request, char, limit):
        if not char.char_id:
            return f"Character {char.name} does not exist."
        alts = self.alts.get_alts(char.char_id)
        if not alts:
            alts = [self.alts.get_main(char.char_id)]
        logs = self.get_log(alts, limit or 20)
        blob = ""
        if len(logs) == 0:
            return "No data for <highlight>%s<end> recorded." % char.name
        for log in logs:
            blob += f"<grey>[{self.util.format_datetime(log.time)}]</grey> <highlight>{log.name}<end> -> " \
                    f"{'<green>logged on</green>' if log.status == 1 else '<red>logged off</red>'}.\n"
        return f"<highlight>{char.name}<end> was last seen at " \
               f"{self.util.format_date(logs[0].time)}. {self.text.format_page('More', blob)}"

    def get_log(self, char_list, length=16):
        query = "SELECT n.*, p.name as name FROM notify_log n LEFT JOIN player p on n.char_id = p.char_id "
        for toon in char_list:
            if toon == char_list[0]:
                query += f"where n.char_id={toon.char_id:d}"
            else:
                query += f" or n.char_id={toon.char_id:d}"
        query += f" ORDER BY time DESC LIMIT {length:d}"
        return self.db.query(query)

    def update_last_seen(self, packet):
        if self.bot.is_ready():
            types = self.buddy_service.get_buddy(packet.char_id)["types"]
            if "org_member" in types or "track" in types or "member" in types:
                self.db.exec("INSERT INTO notify_log (char_id, status, time) VALUES (?, ?, ?)",
                             [packet.char_id, packet.online, time.time()])
