import time

from core.decorators import instance, event
from core.igncore import IgnCore
from core.logger import Logger
from core.message_hub_service import MessageHubService
from core.text import Text, MLStripper
from core.util import Util
from modules.standard.helpbot.playfield_controller import PlayfieldController
from modules.standard.tower.tower_attack_controller import TowerAttackController
from modules.standard.tower.tower_controller import TowerController
from modules.standard.tower.tower_events import TowerEventController


@instance()
class TowerSpamController:
    SOURCE = "TowerInfo"

    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.text: Text = registry.get_instance("text")
        self.util: Util = registry.get_instance("util")
        self.tac: TowerAttackController = registry.get_instance("tower_attack_controller")
        self.msg_hub: MessageHubService = registry.get_instance("message_hub_service")

    def pre_start(self):
        self.msg_hub.register_message_source(self.SOURCE)

    @event(event_type=TowerEventController.TOWER_ATTACK_EVENT, description="NW Warnings, for attacks")
    def tower_attack_event(self, _, event_data):
        t = int(time.time())
        site_number = self.tac.find_closest_site_number(event_data.location.playfield.id, event_data.location.x_coord,
                                                        event_data.location.y_coord)

        # self.logger.info("ATTK ")
        # self.logger.info(event_data)
        # self.logger.info(" site: ")
        # [11.11.2021 04:35:58] INFO :: modules.standard.tower.tower_spam_controller -> ATTK                                                                                          |
        # [11.11.2021 04:35:58] INFO :: modules.standard.tower.tower_spam_controller -> {'attacker': {'char_id': 984112, 'name': 'Flexiblex', 'first_name': '', 'last_name': '', 'leve|
        # l': 117, 'breed': 'Opifex', 'gender': 'Female', 'faction': 'Omni', 'profession': 'Meta-Physicist', 'profession_title': 'ArchPriest', 'ai_rank': 'Adept', 'ai_level': 13, 'or|
        # g_id': 9655, 'org_name': 'Northern Star', 'org_rank_name': 'Unit Leader', 'org_rank_id': 4, 'dimension': 5, 'head_id': 40240, 'pvp_rating': 1503, 'pvp_title': 'Rookie', 'so|
        # urce': 'people.anarchy-online.com', 'last_updated': 1636601503, 'cache_age': 3855}, 'defender': {'faction': 'Omni', 'org_name': 'Weyland Yutani'}, 'location': {'playfield':|
        #  {'id': 795, 'long_name': 'The Longest Road', 'short_name': 'TLR', 'dungeon': 0}, 'x_coord': 526, 'y_coord': 538}}                                                          |
        # [11.11.2021 04:35:58] INFO :: modules.standard.tower.tower_spam_controller ->  site:                                                                                        |
        # [11.11.2021 04:35:58] INFO :: modules.standard.tower.tower_spam_controller -> 7
        # self.logger.info(site_number)
        self.send_nw(
            f"[<cyan>NW</cyan>] {self.text.get_formatted_faction(event_data.attacker.faction, event_data.attacker.org_name)} "
            f"[{self.text.get_formatted_faction(event_data.attacker.faction, event_data.attacker.name)} ({event_data.attacker.level}/{event_data.attacker.ai_level})"
            f" -> {self.util.get_profession(event_data.attacker.profession)}] "
            f"attacked {self.text.get_formatted_faction(event_data.defender.faction, event_data.defender.org_name)} "
            f"at {event_data.location.playfield.short_name} x{site_number}")

    @event(event_type=TowerEventController.TOWER_VICTORY_EVENT, description="Send NW warnings")
    def tower_victory_event(self, _, event_data):
        t = int(time.time())
        row = None
        if event_data.type == "attack":
            row = self.tac.get_last_attack(event_data.winner.faction, event_data.winner.org_name,
                                           event_data.loser.faction,
                                           event_data.loser.org_name, event_data.location.playfield.id, t)
            # self.logger.info("ATTK_VICT ")
            # self.logger.info(event_data)
            # self.logger.info("ATTK_VICT ")
            # self.logger.info(row)

            self.send_nw(
                f"[<cyan>NW</cyan>] {self.text.get_formatted_faction(event_data.winner.faction, event_data.winner.org_name)} "
                f"won against {self.text.get_formatted_faction(event_data.loser.faction, event_data.loser.org_name)} at {event_data.location.playfield.short_name} x{row.site}")
        elif event_data.type == "terminated":
            row = self.tac.find_similar_attacks(event_data.loser.faction, event_data.loser.org_name,
                                                event_data.location.playfield.id, t)
            # VICTORY {'type': 'terminated', 'winner': {'faction': '', 'org_name': ''}, 'loser': {'faction': 'Omni', 'org_name': 'Do you smell the scared boxes'}, 'location': {'playfield
            # ': {'id': 795, 'long_name': 'The Longest Road', 'short_name': 'TLR', 'dungeon': 0}}}
            if row:
                # self.logger.info("ATTK_TERM ")
                # self.logger.info(event_data)
                # self.logger.info("TERMINATED ")
                # self.logger.info(row)

                self.send_nw(f"[<cyan>NW</cyan>] Site terminated in {event_data.location.playfield.long_name}: "
                             f"{self.text.get_formatted_faction(event_data.loser.faction, event_data.loser.org_name)} at {event_data.location.playfield.short_name} x{row.site}")
        else:
            raise Exception("Unknown victory event type: '%s'" % event_data.type)

    def send_nw(self, message):
        stripper = MLStripper()
        stripper.feed(message)
        clean = stripper.get_data()
        self.msg_hub.send_message(self.SOURCE, None, clean, message)
