from datetime import datetime

from mower.solvers.fight.mixin import FightMixin
from mower.utils.graph import SceneGraphSolver
from mower.utils.log import logger
from mower.utils.scene import Scene
from mower.utils.tile_pos import Calc, find_level

from .sss_drop import SSSDROPSolver
from .utils import translate1


class SSSFightSolver(SceneGraphSolver, FightMixin):
    def run(
        self,
        level_name: str,
        opers: list,
        strategies: list,
        draw_as_possible: bool,
        actions: list,
        drops: list,
        retry_times: int,
        groups: list = [],
        deadline: datetime = None,
        blacklist: list = [],
    ):
        """
        Args:
            level_name: 关卡名
            opers: 干员列表
            strategies: 策略列表
            draw_as_possible: 调配干员好了就点
            actions: 行动列表
            drops: 增调顺序
            retry_times: 重试次数，超过返回，结束保全
            groups: 干员组列表
            deadline: 截止时间
            blacklist: 增调干员黑名单
        """
        logger.info(f"Start: 自动保全战斗：{level_name}")
        logger.info("地图坐标计算：https://github.com/yuanyan3060/Arknights-Tile-Pos")
        level = find_level(None, level_name)
        self.calc = Calc(1920, 1080, level)
        self.level_name = level_name
        self.strategies_copy = strategies  # 策略列表备份
        self.actions_copy = actions  # 行动列表备份
        self.draw_as_possible = draw_as_possible  # 调配干员好了就点
        self.opers: list[dict] = opers  # 干员列表
        self.drops = drops  # 增调顺序
        self.retry_times = retry_times  # 重试次数，超过返回
        self.groups = groups  # 干员组
        self.deadline = deadline  # 截止时间
        self.blacklist = blacklist  # 增调干员黑名单
        self.success = False
        super().run()
        return self.success

    def kills(self) -> int:
        "获取击杀数"
        return super().kills(((935, 30), (1085, 60)))

    def check_tool_men_complete(self, tool_men: dict):
        "检查策略中的工具人是否部署完成"
        for _, num in tool_men.items():
            if num > 0:
                return False
        return True

    def travel_strategies(self):
        "遍历策略"
        if len(self.strategies) == 0:
            return
        self.update_operators()
        continue_loc = set()

        for i in range(0, len(self.strategies) - 1):
            strategy = self.strategies[i]
            x, y = strategy["location"]
            if (x, y) in continue_loc:
                continue
            logger.info(strategy)
            if cis := ("core" in strategy):
                continue_loc.add((x, y))
            if not self.check_tool_men_complete(strategy["tool_men"]):
                deploy_name = None
                cost = 999
                for name, num in strategy["tool_men"].items():
                    if num > 0:
                        E_name = name
                        name = translate1[name]
                        if (
                            name in self.operators
                            and self.operators[name]["cost"] < cost
                        ):
                            deploy_name = name
                            cost = self.operators[name]["cost"]
                if deploy_name:
                    if self.deploy(deploy_name, x, y, strategy["direction"]):
                        strategy["tool_men"][E_name] -= 1
                        if strategy["tool_men"][E_name] == 0 and not cis:
                            del self.strategies[i]
                    return
                else:
                    continue
            if not cis:
                del self.strategies[i]
                return

            if strategy["core"] in self.operators:
                if self.deploy(strategy["core"], x, y, strategy["direction"]):
                    del self.strategies[i]
                return

    def transition(self):
        if (scene := self.scene()) == Scene.OPERATOR_FIGHT:
            if self.loading:
                self.fight_init()
                return
            if self.draw_as_possible and self.find("sss/add_agent"):
                self.tap((1805, 684), interval=0.4)
                self.operators = {}
                return
            elif self.find("sss/start_directly"):
                self.tap_element("sss/start_directly")
                return

            self.travel_watching_skills()
            self.execute_action()
            self.travel_strategies()

        elif scene == Scene.OPERATOR_FAILED:
            logger.warning(f"{self.level_name}作战失败，请检查干员/练度")
            self.tap((960, 540))
            self.retry_times -= 1

        elif scene == Scene.SSS_OPERATION_COMPLETE:
            logger.info(f"{self.level_name}作战胜利")
            self.tap((960, 540))
            self.success = True

        elif scene in self.waiting_scene:
            self.waiting_solver()
        elif scene in [Scene.SSS_DEPLOY, Scene.SSS_REDEPLOY]:
            if self.deadline and self.deadline < datetime.now():  # 任务打断
                self.success = True
                return True
            if self.success or self.retry_times <= 0:
                return True
            else:
                self.tap((1645, 971))
                self.reset()
        elif scene in [
            Scene.SSS_DROP_AGENT_BEFORE_FIGHT,
            Scene.SSS_DROP_EC_BEFORE_FIGHT,
            Scene.SSS_DROP_IN_FIGHT,
        ]:
            self.sleep(2)
            if not SSSDROPSolver().run(self.drops, self.blacklist):
                self.scene_graph_navigation(Scene.SSS_DEPLOY)
                return True
        elif scene == Scene.SSS_ACTION:
            self.tap((1651, 967))
        elif scene == Scene.SSS_ACCOMPLISHED:
            return True
        else:
            return True
