from datetime import datetime, timedelta

from mower.utils import config
from mower.utils.email import send_message
from mower.utils.graph import SceneGraphSolver
from mower.utils.log import logger
from mower.utils.recognize import Scene
from mower.utils.tile_pos import LEVELS

from .sss_choose import SSSChooseSolver
from .sss_fight import SSSFightSolver
from .sss_navi import SSSNaviSolver
from .sss_ope import SSSOpeSolver
from .utils import is_full


class SSSSolver(SceneGraphSolver):
    solver_name = "保全作战"

    def run(self) -> bool:
        config.load_works()
        self.copilot_stages = [
            stage.model_dump(exclude_none=True) for stage in config.works["sss"].stages
        ]
        self.stages = {}  # 每个关卡对应的作业信息
        self.stage_num_to_name = {}  # 关卡序号对应的关卡名
        if self.scheduler_stop_time:
            self.deadline = self.scheduler_stop_time - timedelta(minutes=1)
        else:
            self.deadline = None
        self.full = False  # 打满
        self.change_stages()
        self.detect_stage()
        super().run()
        config.conf.maa_rg_enable = 0 if self.full else 1
        config.save_conf()
        return self.full

    def change_stages(self):
        for stage in self.copilot_stages:
            stage_name = stage["stage_name"]
            del stage["stage_name"]
            self.stages[stage_name] = stage

    def detect_stage(self):
        for level in LEVELS:
            if level.code.startswith("LT-") and level.name in self.stages:
                self.stage_num_to_name[level.code[-1]] = level.name

    def transition(self):
        if self.deadline and self.deadline < datetime.now():
            logger.info("任务打断保全")
            return True

        if (scene := self.scene()) in [Scene.SSS_DEPLOY, Scene.SSS_REDEPLOY]:
            stage = self.stage_num_to_name[
                config.recog.num.number(
                    "secret_front",
                    ((140, 410), (175, 460)),
                    38,
                    target_range=range(1, 7),
                )
            ]
            if SSSFightSolver().run(
                stage,
                self.stages[stage]["strategies"],
                self.stages[stage]["draw_as_possible"],
                self.stages[stage]["actions"],
                self.stages[stage]["retry_times"],
                deadline=self.deadline,
            ):
                return
            self.tap("sss/settlement_commission")

        elif (
            scene == Scene.SSS_MAIN and config.conf.sss.finish_while_full and is_full()
        ):
            send_message("保全模组条与仪已刷满", level="WARNING")
            self.full = True
            return True
        elif (
            scene == Scene.SSS_START
            and config.conf.sss.finish_while_full
            and self.find("sss/ope/prts")
        ):
            self.full = SSSOpeSolver().run()
            return self.full
        elif scene == Scene.SSS_DROP_AGENT_BEFORE_FIGHT:
            self.scene_graph_step(Scene.SSS_DEPLOY)

        elif scene == Scene.SSS_EXIT_CONFIRM:
            self.scene_graph_step(Scene.SSS_TERMINATED)

        elif scene == Scene.SSS_TERMINATED:
            self.scene_graph_navigation(Scene.SSS_MAIN)

        elif scene == Scene.SSS_ACCOMPLISHED:
            logger.info("保全作战通关或终止")
            self.scene_graph_step(Scene.SSS_TERMINATED)

        elif scene == Scene.SSS_SQUAD:
            if config.conf.sss.choose_agent:
                SSSChooseSolver().run()
            self.tap("sss/squad")

        elif scene in self.waiting_scene:
            self.waiting_solver()
        else:
            SSSNaviSolver().run()
