package com.sencorsta.rabs.obj.ai.api;

import cn.hutool.core.thread.ThreadUtil;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.type.TypeReference;
import com.sencorsta.rabs.obj.ai.AiManage;
import com.sencorsta.rabs.obj.ai.scene.SceneMain;
import com.sencorsta.rabs.obj.ai.status.fight.BaseStatus;
import com.sencorsta.rabs.ui.robot.RobotUtil;
import com.sencorsta.rabs.util.ResettableData;
import com.sencorsta.utils.object.Jsons;
import lombok.Getter;
import lombok.Setter;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.awt.*;
import java.awt.event.InputEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BooleanSupplier;
import java.util.stream.Collectors;

/**
 * 通用场景逻辑
 */
public class BaseScene {
    @JsonIgnore
    public float getPriority() {
        return 1.0f;
    }

    @Getter
    protected boolean isTempDone = false;
    @Getter
    @JsonIgnore
    protected List<Scene> children = new ArrayList<>();

    @Getter
    ResettableData<BaseStatus> record = new ResettableData<>(getType(), BaseStatus::new);

    @Getter
    @Setter
    @JsonIgnore
    protected Scene parent;


    public String getParentName() {
        if (parent != null) {
            return parent.getClass().getSimpleName();
        }
        return "";
    }

    public List<String> getChildrenName() {
        return children.stream().map(o -> o.getClass().getSimpleName()).collect(Collectors.toList());
    }

    protected void randomToClick() {
        Robot robot = AiManage.getInstance().getRobot();
        java.awt.Point currentMouseLocation = MouseInfo.getPointerInfo().getLocation();
        int currentMouseX = currentMouseLocation.x;
        int currentMouseY = currentMouseLocation.y;
        // 将鼠标移动到匹配区域的左上角坐标
        java.awt.Point location = AiManage.getInstance().getLastClickPoint().getLocation();
        if (location != null) {
            robot.mouseMove(location.x, location.y);
        } else {
            Rectangle rectangle = RobotUtil.getRectangle(AiManage.getInstance().getWindowName());
            robot.mouseMove(rectangle.x + 200, rectangle.y + 200);
        }

        // 执行鼠标左键单击操作
        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
        robot.mouseMove(currentMouseX, currentMouseY);
    }



    protected void moveToClick(String filename, double similarityThreshold) throws AWTException {
        moveToClick(filename, similarityThreshold, new Point(0, 0));
    }

    protected void moveToClick(String filename, double similarityThreshold, Point fixPoint) throws AWTException {
        Rectangle rectangle = RobotUtil.getRectangle(AiManage.getInstance().getWindowName());
        Mat windowMat = RobotUtil.getWindowMat(rectangle);
        Mat template = Imgcodecs.imread(filename);
        Mat result = new Mat();
        Imgproc.matchTemplate(windowMat, template, result, Imgproc.TM_CCOEFF_NORMED);
        Core.MinMaxLocResult mmr = Core.minMaxLoc(result);
        double maxCorrelation = mmr.maxVal;
        Point matchLoc = mmr.maxLoc; // 获取匹配区域的左上角坐标
        // 根据需要设置相似度的阈值
//        System.out.println("maxCorrelation = " + maxCorrelation);
        System.out.println("moveToClick ==> filename = " + filename + " similarityThreshold = " + similarityThreshold + " maxCorrelation = " + maxCorrelation);
        if (maxCorrelation >= similarityThreshold) {
//            System.out.println("图像包含相似内容。" + filename);
//            System.out.println("匹配区域左上角坐标: (" + matchLoc.x + ", " + matchLoc.y + ")");
            // 创建 Robot 对象
            Robot robot = AiManage.getInstance().getRobot();
            java.awt.Point currentMouseLocation = MouseInfo.getPointerInfo().getLocation();
            int currentMouseX = currentMouseLocation.x;
            int currentMouseY = currentMouseLocation.y;
            // 将鼠标移动到匹配区域的左上角坐标
            int x = rectangle.x + (int) matchLoc.x + template.cols() / 2 + (int) fixPoint.x;
            int y = rectangle.y + (int) matchLoc.y + template.rows() / 2 + (int) fixPoint.y;
            AiManage.getInstance().getLastClickPoint().setLocation(x, y);
            robot.mouseMove(x, y);

            // 执行鼠标左键单击操作
            robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
            robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
            robot.mouseMove(currentMouseX, currentMouseY);
        } else {
            System.out.println("图像不包含相似内容 ==> filename = " + filename + " similarityThreshold = " + similarityThreshold + " maxCorrelation = " + maxCorrelation);
        }
    }

    protected void moveToDrop(String filename, double similarityThreshold, Point fixPoint, Point tagetPoint) throws AWTException {
        Rectangle rectangle = RobotUtil.getRectangle(AiManage.getInstance().getWindowName());
        Mat windowMat = RobotUtil.getWindowMat(rectangle);
        Mat template = Imgcodecs.imread(filename);
        Mat result = new Mat();
        Imgproc.matchTemplate(windowMat, template, result, Imgproc.TM_CCOEFF_NORMED);
        Core.MinMaxLocResult mmr = Core.minMaxLoc(result);
        double maxCorrelation = mmr.maxVal;
        Point matchLoc = mmr.maxLoc; // 获取匹配区域的左上角坐标
        // 根据需要设置相似度的阈值
        System.out.println("moveToDrop ==> filename = " + filename + " similarityThreshold = " + similarityThreshold + " maxCorrelation = " + maxCorrelation);
        if (maxCorrelation >= similarityThreshold) {
            // 创建 Robot 对象
            Robot robot = AiManage.getInstance().getRobot();
            java.awt.Point currentMouseLocation = MouseInfo.getPointerInfo().getLocation();
            int currentMouseX = currentMouseLocation.x;
            int currentMouseY = currentMouseLocation.y;
            // 将鼠标移动到匹配区域的左上角坐标
            int x1 = rectangle.x + (int) matchLoc.x + template.cols() / 2 + (int) fixPoint.x;
            int y1 = rectangle.y + (int) matchLoc.y + template.rows() / 2 + (int) fixPoint.y;
            int x2 = rectangle.x + (int) matchLoc.x + template.cols() / 2 + (int) tagetPoint.x;
            int y2 = rectangle.y + (int) matchLoc.y + template.rows() / 2 + (int) tagetPoint.y;
            AiManage.getInstance().getLastClickPoint().setLocation(x2, y2);
            // 拖动操作
            robot.mouseMove(x1, y1);
            robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);

            double distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
            double angle = Math.atan2(y2 - y1, x2 - x1);
            for (double t = 0; t <= distance; t += 2) {
                int newX = (int) (x1 + t * Math.cos(angle));
                int newY = (int) (y1 + t * Math.sin(angle));
                robot.mouseMove(newX, newY);
                ThreadUtil.sleep(4); // 为了模拟拖动的连续性，可以调整线程休眠时间
            }
            robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
            robot.mouseMove(currentMouseX, currentMouseY);
        } else {
            System.out.println("图像不包含相似内容 ==> filename = " + filename + " similarityThreshold = " + similarityThreshold + " maxCorrelation = " + maxCorrelation);
        }
    }

    protected void moveToHold(String filename, double similarityThreshold, Point fixPoint, long time) throws AWTException {
        Rectangle rectangle = RobotUtil.getRectangle(AiManage.getInstance().getWindowName());
        Mat windowMat = RobotUtil.getWindowMat(rectangle);
        Mat template = Imgcodecs.imread(filename);
        Mat result = new Mat();
        Imgproc.matchTemplate(windowMat, template, result, Imgproc.TM_CCOEFF_NORMED);
        Core.MinMaxLocResult mmr = Core.minMaxLoc(result);
        double maxCorrelation = mmr.maxVal;
        Point matchLoc = mmr.maxLoc; // 获取匹配区域的左上角坐标
        // 根据需要设置相似度的阈值
        System.out.println("moveToHold ==> filename = " + filename + " similarityThreshold = " + similarityThreshold + " maxCorrelation = " + maxCorrelation);
        if (maxCorrelation >= similarityThreshold) {
            // 创建 Robot 对象
            Robot robot = AiManage.getInstance().getRobot();
            java.awt.Point currentMouseLocation = MouseInfo.getPointerInfo().getLocation();
            int currentMouseX = currentMouseLocation.x;
            int currentMouseY = currentMouseLocation.y;
            // 将鼠标移动到匹配区域的左上角坐标
            int x1 = rectangle.x + (int) matchLoc.x + template.cols() / 2 + (int) fixPoint.x;
            int y1 = rectangle.y + (int) matchLoc.y + template.rows() / 2 + (int) fixPoint.y;
            AiManage.getInstance().getLastClickPoint().setLocation(x1, y1);
            // 拖动操作
            robot.mouseMove(x1, y1);
            robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
            ThreadUtil.sleep(time); // 为了模拟拖动的连续性，可以调整线程休眠时间
            robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
            robot.mouseMove(currentMouseX, currentMouseY);
        } else {
            System.out.println("图像不包含相似内容 ==> filename = " + filename + " similarityThreshold = " + similarityThreshold + " maxCorrelation = " + maxCorrelation);
        }
    }

    protected boolean checkHas(String filename, double similarityThreshold) throws AWTException {
        return checkHas(filename, similarityThreshold, null);
    }

    protected boolean checkHas(String filename, double similarityThreshold, Mat windowMat) throws AWTException {
        if (windowMat == null) {
            Rectangle rectangle = RobotUtil.getRectangle(AiManage.getInstance().getWindowName());
            windowMat = RobotUtil.getWindowMat(rectangle);
        }
        Mat template = Imgcodecs.imread(filename);
        Mat result = new Mat();
        Imgproc.matchTemplate(windowMat, template, result, Imgproc.TM_CCOEFF_NORMED);
        Core.MinMaxLocResult mmr = Core.minMaxLoc(result);
        double maxCorrelation = mmr.maxVal;
        System.out.println("checkHas ==> filename = " + filename + " similarityThreshold = " + similarityThreshold + " maxCorrelation = " + maxCorrelation);
        if (maxCorrelation >= similarityThreshold) {
            return true;
        } else {
            return false;
        }
    }

    protected boolean hasChildDone() {
        return getChildren().stream().filter(Scene::isOpen).allMatch(Scene::isDone);
    }

    /**
     * 返回持久化数据
     *
     * @return 数据
     */
    public String getData() {
        return Jsons.toJsonString(record);
    }

    /**
     * 是否开启
     */
    public boolean isOpen() {
        return true;
    }

    /**
     * 加载持久化数据
     *
     * @return
     */
    public void loadData(String dataJson) {
        ResettableData.ResetType newResetType = record.getResetType();
        record = Jsons.fromJsonString(dataJson, new TypeReference<ResettableData<BaseStatus>>() {
        });
        if (!record.getResetType().equals(newResetType)){
            record.setResetType(newResetType);
        }
        record.maybeReset();
    }

    public void checkBeforeEnter() throws AWTException {
        while (true){
            System.out.println("开始检查活动广告页....");
            if (checkHas(SceneMain.getPathIp1(), AiManage.getInstance().getCheckPoint())) {
                moveToClick(SceneMain.getPathIp1(),AiManage.getInstance().getCheckPoint());
                ThreadUtil.sleep(2000);
                continue;
            }
            if (checkHas(SceneMain.getPathIp2(), AiManage.getInstance().getCheckPoint())) {
                moveToClick(SceneMain.getPathIp2(),AiManage.getInstance().getCheckPoint());
                ThreadUtil.sleep(2000);
                continue;
            }
            if (checkHas(SceneMain.getPathIp3(), AiManage.getInstance().getCheckPoint())) {
                moveToClick(SceneMain.getPathIp3(),AiManage.getInstance().getCheckPoint());
                ThreadUtil.sleep(2000);
                continue;
            }
            if (checkHas(SceneMain.getPathIp4Check(), AiManage.getInstance().getCheckPoint())) {
                moveToClick(SceneMain.getPathIp4(),AiManage.getInstance().getCheckPoint());
                ThreadUtil.sleep(2000);
                continue;
            }
            break;
        }
    }

    //TODO ice 文字识别封装成一个方法 实现指定任意区域查找英文或者中文
//    public static void main(String[] args) {
//        System.load(System.getProperty("user.dir") + "\\opencv\\x64\\opencv_java490.dll");
//        //识别图中的文字
//        Mat windowMat = Imgcodecs.imread(System.getProperty("user.dir") + "\\opencv\\testText.png");
//        // 将图像转换为灰度
//        Mat gray = new Mat();
//        Imgproc.cvtColor(windowMat, gray, Imgproc.COLOR_BGR2GRAY);
//
//        // 应用阈值化处理来突出文字
//        Mat thresh = new Mat();
//        Imgproc.threshold(gray, thresh, 0, 255, Imgproc.THRESH_BINARY_INV + Imgproc.THRESH_OTSU);
//
//        // 将处理后的图像写到临时文件进行OCR
//        String tempFilename = "temp_image.png";
//        Imgcodecs.imwrite(tempFilename, thresh);
//
//        File imageFile = new File(tempFilename);
//        ITesseract instance = new Tesseract();
//        instance.setDatapath(System.getProperty("user.dir") + "\\opencv\\tessdata"); // 替换为你的tessdata实际路径
////        instance.setLanguage("chi_sim");
//
//        try {
//            String result = instance.doOCR(imageFile);
//            System.out.println(result);
//        } catch (TesseractException e) {
//            System.err.println(e.getMessage());
//        } finally {
//            // 删除临时文件
//            imageFile.delete();
//        }
//    }


    /**
     * 重置
     */
    public ResettableData.ResetType getType(){
        return ResettableData.ResetType.DAILY;
    }


    public void forcePass() {
        getRecord().getData().setDone(true);
        getRecord().getData().setCount(99);
        getChildren().forEach(Scene::forcePass);
    }
}
