package com.yutou.qqbot.utlis;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.data.jianr.AndroidDevice;
import com.yutou.qqbot.data.jianr.JianRScriptData;
import com.yutou.qqbot.data.jianr.JianRScriptV2Data;
import com.yutou.qqbot.data.jianr.Vector2D;
import com.yutou.qqbot.interfaces.ObjectInterface;
import lombok.SneakyThrows;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Random;
import java.util.TreeMap;

public class JianRTaskManager {
    public static final String Redis_Script = "jianrScript_Script";
    public static final String Redis_Device = "jianrScript_Devices";
    public static final String Redis_RunIndex = "jianrScript_RunIndex";
    private static JianRTaskManager instance;
    private JianRScriptV2Data task;
    private AndroidDevice device;
    private boolean running = false;
    private boolean runStatus = false;
    private int runIndex = 0;
    private String log;
    private int modelId;

    public static JianRTaskManager getInstance() {
        if (instance == null) {
            instance = new JianRTaskManager();
        }
        return instance;
    }

    private JianRTaskManager() {

    }

    public void setModelId(int modelId) {
        this.modelId = modelId;
    }

    public void setTask(JianRScriptV2Data data, AndroidDevice device) {
        task = data;
        this.device = device;
        runIndex = 0;
        String s = RedisTools.getHashMap(Redis_RunIndex, data.getTitle());
        if (s != null) {
            runIndex = Integer.parseInt(s);
        }
    }

    public void start() {
        if (running || runStatus) {
            return;
        }
        runStatus = true;
        running = true;
        new Thread(new Runnable() {

            @Override
            public void run() {
                while (running) {
                    try {
                        log("已运行: " + runIndex + " 次");
                        for (JianRScriptV2Data.Script script : task.getScript()) {
                            if (!running) {
                                log("任务已停止");
                                break;
                            }
                            log(script.getTitle());
                            JianRTaskManager.this.run(device, modelId, script);
                           /* try {
                                Thread.sleep((long) getRandom(0, script.getRandomNextWaitTime() * 1000, script.getNextWaitTime() * 1000));
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }*/
                            while (true){
                                if(waitGame(device,modelId,script)){
                                    System.out.println("next");
                                    break;
                                }
                            }
                        }
                        runIndex++;
                        RedisTools.setHashMap(Redis_RunIndex, task.getTitle(), runIndex + "");
                        log("循环一次任务");
                    } catch (Exception e) {
                        running = false;
                    }

                }
                runStatus = false;
                log("终止任务");
            }
        }).start();
    }

    Vector2D nowVector2D = null;

    private void run(AndroidDevice device, int modelId, JianRScriptV2Data.Script script) {
        AndroidDevice.GameDisplay gameDisplay = device.getDeviceDisplay().get(modelId);
        switch (script.getActivity()) {
            case JianRScriptV2Data.ScriptModel.MAP:
                nowVector2D = getMapCoords(device, gameDisplay);
                break;
            case JianRScriptV2Data.ScriptModel.attack:
                nowVector2D = getAttackCoords(device, gameDisplay);
                break;
            case JianRScriptV2Data.ScriptModel.dialog_go:
                nowVector2D = getDialogCoords(device, gameDisplay, false);
                break;
            case JianRScriptV2Data.ScriptModel.dialog_back:
                nowVector2D = getDialogCoords(device, gameDisplay, true);
                break;
            case JianRScriptV2Data.ScriptModel.dialog_assets:
                nowVector2D = getDialogAssetsCoords(device, gameDisplay);
                break;
            case JianRScriptV2Data.ScriptModel.none:
                nowVector2D = getNoneCoords(device, gameDisplay);
                break;
            default:
                if (script.getActivity().startsWith(JianRScriptV2Data.ScriptModel.formationType)) {
                    nowVector2D = getNextFormationCoords(device, gameDisplay, Integer.parseInt(script.getActivity().split("#")[1]));
                }
        }
        if (nowVector2D != null) {
            adb(device, nowVector2D);
        }
    }
    private boolean isAttack=false;
    private boolean isFormation=false;
    private boolean waitGame(AndroidDevice device, int modelId,JianRScriptV2Data.Script script) {
        AndroidDevice.GameDisplay gameDisplay = device.getDeviceDisplay().get(modelId);
        String ocr;
        switch (script.getActivity()) {
            case JianRScriptV2Data.ScriptModel.MAP:
                ocr=screen(gameDisplay,getAttackCoords(device,gameDisplay));
                System.out.println("ocr = " + ocr);
                if(ocr.trim().contains("开始出征")){
                    return true;
                }
                break;
            case JianRScriptV2Data.ScriptModel.attack:
                ocr=screen(gameDisplay,getAttackCoords(device,gameDisplay));
                System.out.println("ocr = " + ocr);
                if(ocr.trim().contains("开始战斗")){
                    isAttack=true;
                }
                if(isAttack){
                    run(device, modelId, script);
                    isFormation= true;
                }
                if(isFormation){
                    ocr=screen(gameDisplay,getDialogCoords(device,gameDisplay,true));
                    String tmp=screen(gameDisplay,getContinueCoords(device,gameDisplay));
                    if(ocr.contains("放弃")||tmp.contains("继续")){

                    }
                }
                break;
            case JianRScriptV2Data.ScriptModel.dialog_go:
                break;
            case JianRScriptV2Data.ScriptModel.dialog_back:
                break;
            case JianRScriptV2Data.ScriptModel.dialog_assets:
                break;
            case JianRScriptV2Data.ScriptModel.none:
                break;
            default:
        }
        return false;
    }

    public void stop() {
        task = null;
        running = false;
    }

    public int getRunIndex() {
        return runIndex;
    }

    public boolean isRunning() {
        return runStatus;
    }

    /**
     * 老版本脚本执行命令
     */
    @Deprecated
    private void adbTap(String deviceId, JianRScriptData.Script script) {
        String exec = String.format("adb -s %s shell input tap %f %f",
                deviceId,
                getRandom(script.getRx(), script.getX()),
                getRandom(script.getRy(), script.getY()));
        AppTools.exec(exec
                , null, false, false);
    }

    private void log(String log) {
        this.log = String.format("[%s]%s",
                AppTools.getToDayNowTimeToString(),
                log);
        System.out.println(this.log);
    }

    private float getRandom(int origin, int randomNum, int x) {
        Random random = new Random();
        return x + random.nextFloat(origin, randomNum);
    }

    private float getRandom(int randomNum, int x) {
        return getRandom(-randomNum, randomNum, x);
    }

    public String getTaskName() {
        if (task != null) {
            return task.getTitle();
        }
        return "没有任务在运行";
    }

    public String getLog() {
        return log;
    }

    public void connect(String deviceId) {
        String exec = String.format("adb connect %s",
                deviceId);
        System.out.println(exec);
        AppTools.exec(exec
                , null, false, false);
    }

    /**
     * 获取出击坐标
     *
     * @param device 设备信息
     * @return 坐标
     */
    private Vector2D getAttackCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay) {
        Vector2D v2d = new Vector2D();
        v2d.setX(gameDisplay.getWidth() * 0.8725 + gameDisplay.getStart().getX());
        v2d.setY(gameDisplay.getHeight() * 0.9161 + gameDisplay.getStart().getY());
        return v2d;
    }

    private Vector2D getContinueCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay) {
        Vector2D v2d = new Vector2D();
        v2d.setX(gameDisplay.getWidth() * 0.8725 + gameDisplay.getStart().getX());
        v2d.setY(gameDisplay.getHeight() * 0.9 + gameDisplay.getStart().getY());
        return v2d;
    }

    /**
     * 获取地图点击坐标
     *
     * @param device 设备信息
     * @return 坐标
     */
    private Vector2D getMapCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay) {
        Vector2D v2d = new Vector2D();
        v2d.setX(gameDisplay.getWidth() * 0.5 + gameDisplay.getStart().getX());
        v2d.setY(gameDisplay.getHeight() * 0.5 + gameDisplay.getStart().getY());
        return v2d;
    }

    /**
     * 获取阵型点击坐标
     *
     * @param device 设备信息
     * @param type   阵型。0~4
     * @return 坐标
     */
    private Vector2D getNextFormationCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay, int type) {
        Vector2D v2d = new Vector2D();
        v2d.setX(gameDisplay.getWidth() * 0.75 + gameDisplay.getStart().getX());
        v2d.setY(gameDisplay.getHeight() * 0.24835 + gameDisplay.getStart().getY());

        for (int i = 0; i < type; i++) {
            v2d.setY(v2d.getY() + (gameDisplay.getHeight() * 0.1461));
        }
        return v2d;
    }

    public Vector2D getBottomLeft(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay) {
        Vector2D v2d = new Vector2D();
        v2d.setX(gameDisplay.getStart().getX());
        v2d.setY(gameDisplay.getEnd().getY());
        return v2d;
    }

    /**
     * 获取出击坐标
     *
     * @param device 设备信息
     * @return 坐标
     */
    private Vector2D getDialogCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay, boolean isBack) {
        Vector2D v2d = new Vector2D();
        v2d.setY(gameDisplay.getHeight() * 0.61722 + gameDisplay.getStart().getY());
        if (isBack) {
            v2d.setX(gameDisplay.getWidth() * 0.6575 + gameDisplay.getStart().getX());
        } else {
            v2d.setX(gameDisplay.getWidth() * 0.344642857143 + gameDisplay.getStart().getX());
        }
        return v2d;
    }

    /**
     * 获取资源对抗确定坐标
     *
     * @return 坐标
     */
    private Vector2D getDialogAssetsCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay) {
        Vector2D v2d = new Vector2D();
        v2d.setX(gameDisplay.getWidth() * 0.5 + gameDisplay.getStart().getX());
        v2d.setY(gameDisplay.getHeight() * 0.5433 + gameDisplay.getStart().getY());
        return v2d;
    }

    private Vector2D getNoneCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay) {
        Vector2D v2d = new Vector2D();
        v2d.setX(gameDisplay.getWidth() * 0.1 + gameDisplay.getStart().getX());
        v2d.setY(gameDisplay.getHeight() * 0.1 + gameDisplay.getStart().getY());
        return v2d;
    }

    @SneakyThrows
    public static void main(String[] args) {
        JSONObject json = new JSONObject();
        String data = RedisTools.getHashMap(JianRTaskManager.Redis_Script, "7-1刷A点");
        String deviceJsonString = RedisTools.getHashMap(JianRTaskManager.Redis_Device, "三星平板");
        if (data == null || deviceJsonString == null) {
            json.put("code", -1);
            json.put("msg", "没有找到该方案或设备错误，请配置");
        } else {
            JianRScriptV2Data script = JSON.parseObject(data, JianRScriptV2Data.class);
            AndroidDevice androidDevice = JSON.parseObject(deviceJsonString, AndroidDevice.class);
            JianRTaskManager manager = JianRTaskManager.getInstance();
            if (manager.isRunning()) {
                manager.stop();
            }
            for (int i = 0; i < androidDevice.getDeviceDisplay().size(); i++) {
                if (androidDevice.getDeviceDisplay().get(i).getTitle().equals("全屏模式")) {
                    manager.setModelId(i);
                    break;
                }
            }
            manager.setTask(script, androidDevice);
            manager.start();
        }
    }

    public File cut(Vector2D v2d) {
        try {
            System.out.println("v2d = " + v2d);
            int x = (int) v2d.getNotRandomX() - 150;
            int y = (int) v2d.getNotRandomY() - 50;
            if (y + 150 > device.getAndroidDevice().getHeight()) {
                y -= 100;
            }
            if (y < 0) {
                y = 0;
            }
            if (x + 450 > device.getAndroidDevice().getWidth()) {
                x -= 300;
            }
            if (x < 0) {
                x = 0;
            }
            System.out.println("x = " + x);
            System.out.println("y = " + y);
            BufferedImage bufImage = ImageIO.read(new File("1.png"));
            BufferedImage bufferedImage = bufImage.getSubimage(x, y, 400, 100);
            File imgCutFile = new File("tmp.png");
            ImageIO.write(bufferedImage, "PNG", imgCutFile);
            return imgCutFile;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static String ocr(File file) {
        String exec = "\"C:\\Program Files\\Tesseract-OCR\\tesseract.exe\" " + file.getAbsolutePath() + " - -l chi_sim --psm 6";
        return AppTools.exec(exec, null, false, true).replace("\r", "").replace("\n", "");
    }

    private String screen(AndroidDevice.GameDisplay gameDisplay, Vector2D v2d) {
        AppTools.exec("adb exec-out screencap -p > 1.png", null, false, false);
        gameDisplay.setEnabledRandom(false);
        File file = cut(v2d);
        return ocr(file);
    }

    public void test() {
        String data = RedisTools.getHashMap(JianRTaskManager.Redis_Script, "7-1刷A点");
        String deviceJsonString = RedisTools.getHashMap(JianRTaskManager.Redis_Device, "三星平板");
        JianRScriptV2Data script = JSON.parseObject(data, JianRScriptV2Data.class);
        AndroidDevice androidDevice = JSON.parseObject(deviceJsonString, AndroidDevice.class);
        this.device = androidDevice;
        this.task = script;
        this.modelId = 1;
        System.out.println("download image");
        AppTools.exec("adb exec-out screencap -p > 1.png", new ObjectInterface() {
            @Override
            public void out(String data) {
                super.out(data);
                AndroidDevice dev = device;
                AndroidDevice.GameDisplay gameDisplay = device.getDeviceDisplay().get(modelId);
                gameDisplay.setEnabledRandom(false);
                Vector2D v2d;
                v2d = getBottomLeft(device, gameDisplay);
                v2d = getNextFormationCoords(device, gameDisplay, 4);
                v2d = getAttackCoords(device, gameDisplay);
                v2d = getDialogCoords(device, device.getDeviceDisplay().get(modelId), true);
                v2d = getContinueCoords(device, gameDisplay);
                File file = cut(v2d);
                String ocr = ocr(file);
                System.out.println(ocr.trim());
            }
        }, false, true);
    }

    private void adb(AndroidDevice device, Vector2D v2d) {
        String exec = String.format("adb -s %s shell input tap %f %f",
                device.getDeviceId(),
                v2d.getX(),
                v2d.getY());
        System.out.println(exec);
        AppTools.exec(exec
                , null, false, false);
    }


}
