from datetime import datetime, timedelta

import cv2

from mower.models import Digtal
from mower.solvers.infra.enter_room import EnterRoomSolver
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.email import send_message
from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cmatch, cropimg, loadres, thres2
from mower.utils.log import logger
from mower.utils.recognize import Scene

production_index = {
    "经验": [0, 1],
    "赤金": [1, 0],
    "源石碎片": [3, 0],
    "先锋双芯片": [2, 0],
    "狙击双芯片": [2, 5],
    "医疗双芯片": [2, 6],
    "术师双芯片": [2, 2],
    "近卫双芯片": [2, 4],
    "重装双芯片": [2, 1],
    "辅助双芯片": [2, 3],
    "特种双芯片": [2, 7],
}
first_pos = [((180, 215 + 140 * i), (190, 225 + 140 * i)) for i in range(4)]

second_pos = [(500 + 742 * j, 200 + 270 * i) for j in range(2) for i in range(4)]


class ChooseProductSolver(SceneGraphSolver):
    def run(self, room, tar_product) -> bool:
        self.room = room
        self.tar_product = tar_product
        self.first_pos = first_pos[production_index[self.tar_product][0]]
        self.second_pos = second_pos[production_index[self.tar_product][1]]
        self.success = False
        self.num_flag = False
        self.wait_start()
        super().run()
        return self.success

    def be_choosen(self) -> bool:
        img = cropimg(config.recog.img, self.first_pos)
        res = loadres("product_be_choosen")
        return cmatch(img, res, 60)

    def timeout(self) -> bool:
        return datetime.now() > self.start_time + timedelta(seconds=10)

    def wait_start(self):
        self.start_time = datetime.now()

    def number(self, scope: tp.Scope, height: int, thres: int) -> int:
        "数字识别"
        img = cropimg(config.recog.gray, scope)
        default_height = 25
        if height != default_height:
            scale = 25 / height
            img = cv2.resize(img, None, None, scale, scale)
        img = thres2(img, thres)
        contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        rect = [cv2.boundingRect(c) for c in contours]
        rect.sort(key=lambda c: c[0])

        value = 0

        for x, y, w, h in rect:
            digit = cropimg(img, ((x, y), (x + w, y + h)))
            digit = cv2.copyMakeBorder(
                digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
            )
            score = []
            for i in range(10):
                im = Digtal().riic_base_digits[i]
                result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
                min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
                score.append(min_val)
            value = value * 10 + score.index(min(score))

        return value

    def transition(self) -> bool:
        if (scene := self.scene()) == Scene.INFRA_DETAILS:
            self.ctap((200, 1000), 1, config.screenshot_avg / 1000)
        elif scene == Scene.FACTORY_ROOMS:
            if self.success:
                return True
            elif self.find("reload_check"):
                if self.num_flag:
                    self.ctap((1400, 850), 1, config.screenshot_avg / 1000)
                elif self.timeout():
                    logger.warning("切换成功,剩余材料不足1")
                    send_message(f"切换成功,剩余材料不足1:{self.room}", level="WARNING")
                    self.num_flag = True
                else:
                    self.tap((1450, 300))
                    if self.number(((1306, 462), (1391, 521)), 50, 200) != 1:
                        self.num_flag = True
            else:
                self.tap((1750, 400))
        elif scene == Scene.CHOOSE_PRODUCT:
            if self.find("icon_notification_black"):
                logger.warning("切换产物材料不足")
                send_message(f"切换产物材料不足:{self.room}", level="WARNING")
                return True
            elif not self.be_choosen():
                self.tap(self.first_pos)
            else:
                self.tap(self.second_pos)
        elif scene == Scene.PRODUCT_SWITCHING_CONFIRM:
            self.tap_element("double_confirm/main", x_rate=1)
            self.success = True
        elif scene in self.waiting_scene:
            self.waiting_solver()
        else:
            EnterRoomSolver().run(self.room, detail=False)
