from copy import deepcopy
from datetime import datetime

from mower.data import agent_list
from mower.solvers.infra.base_mixin import BaseMixin
from mower.solvers.infra.enter_room import EnterRoomSolver
from mower.solvers.infra.filter import RIIC_Filter
from mower.solvers.infra.riic_tag_choose import RIICTagChoose
from mower.utils import config
from mower.utils.character_recognize import operator_room_select
from mower.utils.graph.utils import SceneGraphSolver
from mower.utils.image import cropimg
from mower.utils.log import logger
from mower.utils.scene import Scene


class RIIC_ChooseSolver(SceneGraphSolver, BaseMixin):
    solver_name = "基建选人"

    def run(self, room: str, agents: list, wait_time: float = 0) -> bool:
        """
        Args:
            room (str): 房间
            agents (list): 选人名单
            wait_time (float, optional): 选人完成到按确定的时间
        """
        logger.info(f"待选名单{agents}")
        self.agents = agents
        self.room = room
        self.wait_time = wait_time

        self.success = False
        self.agents_copy = deepcopy(agents)
        self.clean = False
        self.filter = False
        self.agent = None
        self.tmp_left = None

        self.start_time = datetime.now()
        self.tap_time = datetime.now()
        self.tmp_swipe = None

        self.before_recog_agents = None
        self.swipe_duration = 300
        self.choosed = []

        super().run()  # 不一定选完，但一定结束流程了
        logger.info(f"选完{self.choosed}")
        return len(self.choosed) == self.agents

    def choose_agents(self):
        if self.agent is None:
            if len(self.agents_copy) > 0:
                """
                self.agent =[干员名,是否左滑过]
                """
                self.agent = [self.agents_copy.pop(0), False]
                logger.info(f"开始选择干员：{self.agent[0]}")
            else:
                if self.wait_time > 0:
                    self.sleep(self.check_wait_time())
                self.success = True
                if pos := self.find("confirm_blue"):
                    self.tap(pos)
                return
        recog_agents = operator_room_select(config.recog.img)
        recog_agents_dict = dict(recog_agents)

        if self.before_recog_agents is not None and self.animation():
            if (
                self.agent[0] in recog_agents_dict.keys()
                or recog_agents[-1][0] != self.before_recog_agents[-1][0]
            ):
                return

            if self.swipe_duration == 300:
                logger.info(f"{recog_agents}{self.before_recog_agents}")
                # 帧数低会有只拖动一点点的情况
                logger.debug("增大duration再试一次")
                self.swipe_duration = 800
                self.before_recog_agents = None
                return
            logger.info(f"缺少：{self.agent[0]}")
            return True

        agent_name = self.agent[0]
        if len(self.agents) > 1:
            for i in recog_agents_dict:
                if (
                    self.is_choosed(recog_agents_dict[i])
                    and recog_agents_dict[i][0][0] < 1600
                ):
                    if i not in self.agents and i not in self.choosed:
                        logger.info(f"存在错选 {i}")
                        self.tap("choose_agent/clear")
                        self.agents_copy = deepcopy(self.agents)
                        self.choosed = []
                        self.agent = None
                        return
        if agent_name in recog_agents_dict.keys():
            is_choosed = self.is_choosed(recog_agents_dict[agent_name])
            if is_choosed:
                logger.info(f"{agent_name}选择完成")
                recog_agents_dict = None
                self.choosed.append(agent_name)
                self.agent = None
                self.before_recog_agents = None
            else:
                if recog_agents_dict[agent_name][0][0] > 1650:
                    logger.debug(f"滑动调整位置 {recog_agents_dict[agent_name]}")

                    self.recog_agents = self.swipe_update(
                        [(1200, 970), (900, 970)],
                        [self.swipe_duration],
                        up_wait=self.swipe_duration,
                        interval=0,
                        func=operator_room_select,
                    )
                    return

                logger.debug(f"tap {agent_name} ")
                self.ctap(recog_agents_dict[agent_name], 5, agent_name)
            return

        logger.debug(f"选tag和左滑 {self.agent}")
        tag = agent_list[agent_name]["profession"]
        if agent_name == "阿米娅":
            tag = "ALL"
        if RIICTagChoose().get_now_tag() != tag:
            self.recog_agents = None
            self.before_recog_agents = None
            RIICTagChoose().run(tag)
            return
        if self.agent[1] is False:
            recog_agents = self.swipe_update(
                [(900, 970), (1800, 970)],
                [500],
                up_wait=400,
                interval=0,
                func=operator_room_select,
            )
            if recog_agents[0][0] == list(recog_agents_dict.keys())[0]:
                self.agent[1] = True
                self.before_recog_agents = None
                self.swipe_duration = 300
                return
        self.before_recog_agents = recog_agents
        # 右滑
        self.swipe_ext(
            [(1600, 770), (500, 770)],
            [self.swipe_duration],
            up_wait=400,
            interval=0,
        )

    def is_choosed(self, scope) -> bool:
        up_pt = cropimg(
            config.recog.img,
            [
                [scope[0][0] + 0, scope[0][1] - 128],
                [scope[0][0] + 1, scope[0][1] - 127],
            ],
        )[0][0][0]

        down_pt = cropimg(
            config.recog.img,
            [
                [scope[0][0] + 0, scope[1][1] + 212],
                [scope[0][0] + 1, scope[1][1] + 213],
            ],
        )[0][0][0]

        if up_pt < 50 and down_pt < 50:
            return True
        return False

    def check_wait_time(self) -> float:
        return max(
            self.wait_time - (datetime.now() - self.start_time).total_seconds(), 0
        )

    def transition(self) -> bool:
        if (datetime.now() - self.tap_time).total_seconds() > 300:
            EnterRoomSolver().run(self.room)
            return True
        if (scene := self.scene()) == Scene.RIIC_OPERATOR_SELECT:
            if pos := self.find("choose_agent/open_profession"):
                self.ctap(pos)
                return
            if self.filter is False:
                if RIIC_Filter().run("技能", ascending=True):
                    if RIICTagChoose().run("ALL"):
                        self.filter = True
                    return
            if self.clean is False and len(self.agents) > 1:
                if self.animation():
                    return
                agents_dict = operator_room_select(config.recog.img)
                for name, scope in agents_dict:
                    if self.is_choosed(scope):
                        logger.debug(f"开始选人前先清空干员 {name}")
                        self.tap("choose_agent/clear")
                        return

                self.clean = True

            return self.choose_agents()

        elif self.find("room_detail") and self.detect_room() == self.room:
            if self.success:
                return True
            else:
                self.ctap((1400, 200))
        elif (
            scene in [Scene.ORDER_LIST, Scene.FACTORY_ROOMS]
            and self.detect_room_inside() == self.room
        ):
            if self.success:
                return True
            else:
                self.tap((500, 970))
        elif scene == Scene.INFRA_ARRANGE_ORDER:
            self.scene_graph_step(Scene.RIIC_OPERATOR_SELECT)
        elif scene == Scene.INFRA_ARRANGE_CONFIRM:
            self.scene_graph_step(Scene.RIIC_OPERATOR_SELECT)
        elif scene in self.waiting_scene:
            self.waiting_solver()
        else:
            EnterRoomSolver().run(self.room)
