import math

import cv2
import numpy as np

from mower.utils import config
from mower.utils.graph.utils import SceneGraphSolver
from mower.utils.image import cropimg
from mower.utils.scene import Scene


class BattleFilterSolver(SceneGraphSolver):
    def __init__(self) -> None:
        self.labels = [
            "获取时间",
            "信赖值",
            "生命上限",
            "攻击",
            "防御",
            "法术抗性",
            "再部署",
            "部署费用",
            "阻挡数",
            "攻击速度",
        ]
        self.orders = [
            "等级",
            "稀有度",
            "自定义",
        ]

    def run(self, tag: str, ascending: bool = True) -> None:
        if tag not in self.labels and tag not in self.orders:
            raise KeyError

        self.tag = tag
        self.ascending = ascending
        self.label = "自定义"
        self.tag_choose_done = False

        if self.tag in self.orders:
            self.tag_choose_done = True
            self.in_label = False
            self.label = self.tag

        super().run()

        return True

    def get_now_filter(self):
        image = cropimg(config.recog.img, [(1500, 90), (1900, 1080)])
        hsv_image = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
        mask = cv2.inRange(hsv_image, (0, 200, 100), (140, 255, 255))
        contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        for contour in contours:
            _, y, _, h = cv2.boundingRect(contour)
            return f"{self.labels[ int((y + h / 2) / 90) ]}"

    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 detect_arrange_order(self):
        x_list = (1280, 1430, 1575)
        y = 64
        hsv = cv2.cvtColor(config.recog.img, cv2.COLOR_RGB2HSV)
        mask = cv2.inRange(hsv, (99, 200, 0), (100, 255, 255))
        for idx, x in enumerate(x_list):
            if np.count_nonzero(mask[y : y + 3, x : x + 5]):
                return (self.orders[idx], True)
            if np.count_nonzero(mask[y + 10 : y + 13, x : x + 5]):
                return (self.orders[idx], False)

    def switch_arrange_order(self, name, ascending=False):
        name_x = {"等级": 1280, "稀有度": 1430, "自定义": 1575}
        if isinstance(name, int):
            name = list(name_x.keys())[name - 1]
        if isinstance(ascending, str):
            ascending = ascending == "true"
        name_y = 60
        self.tap((name_x[name], name_y), interval=0.5)

    def choose_tag(self):
        if self.tag_choose_done:
            if self.find("choose_agent/battle_filter_close"):
                self.tap((1750, 60), interval=0.1)
                return
            n, s = self.detect_arrange_order()
            if n != self.label or s != self.ascending:
                self.switch_arrange_order(self.label, self.ascending)
                return

            return True

        if not self.find("choose_agent/battle_filter_close"):
            self.tap_element("choose_agent/battle_filter")
            return

        self.tap((1750, (self.labels.index(self.tag)) * 90 + 135), interval=0.1)

        config.recog.update()
        if str := self.get_now_filter():
            if str == self.tag:
                self.tag_choose_done = True

        return

    def transition(self) -> bool:
        if self.scene() == Scene.OPERATOR_AGENT_SELECT:
            return self.choose_tag()
        else:
            return False
