import json
from datetime import datetime, timedelta
from typing import Optional

import cv2

from mower.utils import config
from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg
from mower.utils.log import logger
from mower.utils.path import get_path
from mower.utils.recognize import Scene

from .sss_fight import SSSFightSolver
from .sss_navi import SSSNaviSolver
from .utils import generate_image


class SSSSolver(SceneGraphSolver):
    def run(
        self,
        duration: Optional[timedelta] = None,
    ) -> bool:
        logger.info("Start: 保全作战")

        with get_path("@app/sss.json").open("r", encoding="utf-8") as f:
            self.copilot = json.load(f)
        self.opers = self.copilot["opers"]
        self.groups = self.copilot["groups"] if "groups" in self.copilot else []
        self.drops = self.copilot["drops"]
        self.stages = {}
        self.deadline = datetime.now() + duration if duration else None
        self.blacklist = (
            self.copilot["blacklist"] if "blacklist" in self.copilot else []
        )
        self.change_stages()
        super().run()

    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 stage in self.stages:
            stage_name_size = 40 if len(stage) < 6 else 34
            res = generate_image(stage, stage_name_size)
            img = cropimg(config.recog.gray, ((180, 400), (420, 480)))
            result = cv2.matchTemplate(img, res, cv2.TM_CCOEFF_NORMED)
            min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
            logger.debug(f"stage:{stage},max_val:{max_val}")
            if max_val > 0.85:
                return stage
        return None

    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.detect_stage()
            if SSSFightSolver().run(
                stage,
                self.opers,
                self.stages[stage]["strategies"],
                self.stages[stage]["draw_as_possible"],
                self.stages[stage]["actions"],
                self.drops,
                self.stages[stage]["retry_times"],
                self.groups,
                deadline=self.deadline,
                blacklist=self.blacklist,
            ):
                return
            self.tap_element("sss/settlement_commission")

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

        elif scene == Scene.SSS_TERMINATED:
            logger.info("保全作战结束")
            return True

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

        elif scene in self.waiting_scene:
            self.waiting_solver()
        else:
            SSSNaviSolver().run(
                self.copilot["stage_name"],
                self.copilot["buff"],
                self.copilot["equipment"],
            )
