import math

import numpy as np

from mower.solvers.fight.battle_choose.battle_filter import BattleFilterSolver
from mower.utils import config
from mower.utils.character_recognize import operator_team_select
from mower.utils.graph.utils import SceneGraphSolver
from mower.utils.image import cmatch, cropimg
from mower.utils.log import logger
from mower.utils.scene import Scene
from mower.utils.vector import va


# 按需填充干员
class BattleFillChooseSolver(SceneGraphSolver):
    def __init__(self) -> None:
        self.labels = [
            "获取时间",
            "信赖值",
            "生命上限",
            "攻击",
            "防御",
            "法术抗性",
            "再部署",
            "部署费用",
            "阻挡数",
            "攻击速度",
            "等级",
            "稀有度",
        ]

        self.profession = [
            "PIONEER",
            "WARRIOR",
            "TANK",
            "SNIPER",
            "CASTER",
            "MEDIC",
            "SUPPORT",
            "SPECIAL",
        ]

    def run(self, label: str, number: int, black_list: list = []):
        self.mode = None
        # 0是非职业的筛选，如信赖值或等级
        if label in self.labels:
            self.mode = 0
        # 1是干员职业的筛选
        elif label in self.profession:
            self.mode = 1
        else:
            raise KeyError(f"BattleAgentChooseSolver：填充干员标签错误{label}")
        self.label = label
        self.filter_done = False
        self.resort = False
        self.number = number
        self.choosed = []
        self.black_list = black_list
        self.tmp_data = {}

        self.template = np.zeros((1, 1, 3), dtype=np.uint8)
        self.template[:] = [120, 190, 220]
        self.wait_choose = None
        super().run()

        return self.choosed

    def tag_choosed(self, profession: str = "ALL"):
        str = "choose_agent/profession/" + profession
        if pos := self.find(str):
            if arrow := self.find("choose_agent/profession/choose_arrow"):
                if (
                    math.sqrt(
                        math.pow(pos[0][0] - arrow[0][0], 2)
                        + math.pow(pos[0][1] - arrow[0][1], 2)
                    )
                    < 100
                ):
                    return False
                else:
                    self.tap(pos[0], interval=0.2)
                    return True
            else:
                self.tap(pos[0], interval=0.2)
                return True

    def filter(self):
        if pos := self.find("choose_agent/open_profession"):
            self.tap(pos, interval=0.1)
            return

        if self.mode == 1:
            return self.tag_choosed(self.label) and BattleFilterSolver().run(
                "等级", False
            )
        elif self.mode == 0:
            if BattleFilterSolver().run(self.label):
                # 选全部干员
                if self.find("choose_agent/foldup"):
                    return True
                else:
                    return self.tag_choosed()
        return

    def fill_agent(self):
        if self.wait_choose is None:
            agents = dict(operator_team_select(config.recog.img))

            for i in agents:
                segment = [va(agents[i][0], (0, -95)), va(agents[i][1], (0, -190))]
                img = cropimg(config.recog.img, segment)

                if cmatch(img, self.template, thresh=70) or i in self.black_list:
                    continue

                logger.debug(f"选{i}, {agents[i]}")
                self.wait_choose = [i, agents[i]]
                return
            if len(self.choosed) < self.number:
                if set(agents.keys()).issubset(self.tmp_data.keys()):
                    self.swipe_time = self.swipe_time + 1
                    if self.swipe_time > 1:
                        raise ValueError("填充干员失败 滑动次数过多")
                else:
                    self.swipe_time = 0

            self.swipe_noinertia((1000, 540), (-1900, 0))
            self.tmp_data = agents
        else:
            if self.wait_choose[1][0][0] > 1700:
                self.swipe_noinertia((1000, 540), (-500, 0))
                return
            segment = [
                va(self.wait_choose[1][0], (0, -95)),
                va(self.wait_choose[1][1], (0, -190)),
            ]
            img = cropimg(config.recog.img, segment)
            if cmatch(img, self.template, thresh=70):
                self.choosed.append(self.wait_choose[0])
                self.wait_choose = None
                logger.debug(f"{self.choosed} ")
                if len(self.choosed) == self.number:
                    logger.info(f"填充：{self.choosed}")
                    return True
            else:
                self.ctap(self.wait_choose[1], interval=0.1)

    def transition(self) -> bool:
        if self.scene() == Scene.OPERATOR_AGENT_SELECT:
            if self.filter_done is False:
                # if pos := self.find("choose_agent/open_profession"):
                #     self.tap(pos, interval=0.1)
                #     return

                # if self.mode == 0:
                #     if self.resort is False:
                #         if pos := self.find("choose_agent/foldup"):
                #             self.tag_choosed("PIONEER")

                #         else:
                #             if self.tag_choosed() is not False:
                #                 self.resort = True
                #         return

                if self.filter():
                    self.filter_done = True
                    return

            return self.fill_agent()
        else:
            return False
