package com.yutou.qqbot.models.Animal;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.napcat.event.MessageEvent;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.*;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import java.util.Calendar;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@UseModel
public class TurnipProphet extends Model {
    public static class TurnipData {
        public static final String MODEL = "趋势:";
        public static final String PR = "概率:";
        public static final String MIX = "保底价:";
        public static final String MAX = "最高价:";
        public static final String DAY = "最高日:";

        public static final String MONDAY_UP = "周一上";
        public static final String MONDAY_DOWN = "周一下";
        public static final String TUESDAY_UP = "周二上";
        public static final String TUESDAY_DOWN = "周二下";
        public static final String WEDNESDAY_UP = "周三上";
        public static final String WEDNESDAY_DOWN = "周三下";
        public static final String THURSDAY_UP = "周四上";
        public static final String THURSDAY_DOWN = "周四下";
        public static final String FRIDAY_UP = "周五上";
        public static final String FRIDAY_DOWN = "周五下";
        public static final String SATURDAY_UP = "周六上";
        public static final String SATURDAY_DOWN = "周六下";


    }

    static int nowTime = -1;

    @Override
    public boolean isUserPublic() {
        return true;
    }

    @Override
    public String[] getUsePowers() {
        return new String[]{
                QQFromCommands.TURNIP_PROPHET
        };
    }

    @Override
    public String getModelName() {
        return "大头菜";
    }

    Long user, sendQQ;

    @Override
    public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
        super.onMessage(qq, event, isGroup);
        user = qq;
        sendQQ = qq;
        if (isGroup) {
            if (!event.isAtMe()) {
                return;
            }
            user = event.getSource().getFromId();
        }
        int money = -1;
        try {
            if (isGroup) {
                msg = msg.replace("@2476945931", "").trim();
            }
            money = Integer.parseInt(msg.trim());
        } catch (Exception e) {
            if (msg.equals(QQFromCommands.TURNIP_PROPHET)) {
                showData();
            }
            return;
        }
        setData(money);
    }

    private void showData() {
        String redisKey = user + "_turnip";
        String data = RedisTools.get(redisKey);
        if (StringUtils.isEmpty(data)) {
            QQBotManager.getInstance().sendMessage(sendQQ, getMessage("没有本周数据，无法预测"));
            return;
        }
        JSONObject json = JSON.parseObject(data);
        String prices = json.getString("prices");
        String pattern = null;
        if (json.containsKey("old_pattern")) {
            try {
                pattern = json.getString("old_pattern");
            } catch (Exception ignored) {
            }
        }
        if (pattern != null) {
            switch (pattern) {
                case "波动型" -> pattern = "0";
                case "大幅上涨（三期型）" -> pattern = "1";
                case "递减型" -> pattern = "2";
                case "小幅上涨（四期型）" -> pattern = "3";
            }
        }
        Map<String, String> map = null;
        try {
            map = openTurnip(prices, pattern);
            sendQQ(map, prices, pattern);
        } catch (Exception e) {
            e.printStackTrace();
            showData();
        }

    }

    private void setData(int money) {
        String redisKey = user + "_turnip";
        String data = RedisTools.get(redisKey);
        String pattern = null;
        JSONObject json;
        JSONArray array;
        if (StringUtils.isEmpty(data) || getDay() == 0) {
            array = new JSONArray();
            json = new JSONObject();
            if (getDay() == 0 && !StringUtils.isEmpty(data)) {
                json = JSON.parseObject(data);
            }
            array.add(-1);
            array.add(-1);
            array.add(-1);
            array.add(-1);
            array.add(-1);
            array.add(-1);
            array.add(-1);
            array.add(-1);
            array.add(-1);
            array.add(-1);
            array.add(-1);
            array.add(-1);
            array.add(-1);
        } else {
            json = JSON.parseObject(data);
            array = json.getJSONArray("turnip");
        }
        if (array.getInteger(0) == -1 && getDay() != 0) {
            QQBotManager.getInstance().sendMessage(sendQQ, getMessage("没有周日买入信息，本周不收录 :("));
            return;
        }
        if (json.containsKey("old_pattern")) {
            try {
                pattern = json.getString("old_pattern");
            } catch (Exception ignored) {
            }
        }
        if (getDay() == 0) {
            if (json.containsKey("pattern")) {
                if (!json.containsKey("tmp_pattern")) {
                    json.put("old_pattern", json.getString("pattern"));
                    pattern = json.getString("pattern");
                } else {
                    pattern = json.getString("old_pattern");
                }
                json.put("tmp_pattern", json.getString("pattern"));
            }
            array.set(0, money);
        } else {
            json.remove("tmp_pattern");
            if (getTime() < 12) {
                array.set(getDay() * 2 - 1, money);
            } else {
                array.set(getDay() * 2, money);
            }
        }
        json.put("turnip", array);
        StringBuilder builder = new StringBuilder();
        for (Object o : array) {
            builder.append(o).append(".");
        }
        builder.append(".".repeat(Math.max(0, (12 - array.size()))));
        String prices = builder.toString();
        if (prices.split("\\.").length == 13) {
            prices = prices.substring(0, prices.length() - 1);
        }
        prices = prices.replace("-1", "");
        json.put("prices", prices);
        try {
            if (pattern != null) {
                switch (pattern) {
                    case "波动型" -> pattern = "0";
                    case "大幅上涨（三期型）" -> pattern = "1";
                    case "递减型" -> pattern = "2";
                    case "小幅上涨（四期型）" -> pattern = "3";
                }
            }
            QQBotManager.getInstance().sendMessage(sendQQ, getMessage("已记录，正在预测本周走势..."));

            Map<String, String> map = openTurnip(prices, pattern);
            if (map == null) {
                map = openTurnip(prices, pattern);
            }
            String tmp_pattern = sendQQ(map, prices, pattern);
            if (!StringUtils.isEmpty(tmp_pattern)) {
                json.put("pattern", tmp_pattern);
            }
            RedisTools.set(redisKey, json.toJSONString());

        } catch (Exception e) {
            e.printStackTrace();
            setData(money);
        }


    }

    private String sendQQ(Map<String, String> map, String prices, String pattern) {
        String url = String.format("https://turnipprophet.io?prices=%s%s",
                prices,
                pattern == null ? "" : "&pattern=" + pattern
        );
        if (map == null) {
            QQBotManager.getInstance().sendMessage(sendQQ, getMessage("没有结果，请检查数据是否有误。 \n网页预览：\n" + url));
            return null;
        }

        JSONObject pr = JSON.parseObject(map.get(TurnipData.MODEL));
        JSONArray prArray = pr.getJSONArray(TurnipData.MODEL);
        StringBuilder out = new StringBuilder();
        out.append("预测结果如下:\n");
        out.append(TurnipData.MODEL).append(prArray.getJSONObject(0).getString(TurnipData.MODEL)).append("\n");
        out.append(TurnipData.PR).append(prArray.getJSONObject(0).getString(TurnipData.PR)).append("\n");
        out.append("购入价:").append(prices.split("\\.")[0]).append("\n");
        if (getDay() == 0) {
            out.append("满背包(4行)购入价:").append(4000 * Integer.parseInt(prices.split("\\.")[0])).append("\n");
        }
        out.append(TurnipData.MIX).append(map.get(TurnipData.MIX)).append("\n")
                .append(TurnipData.MAX).append(map.get(TurnipData.MAX)).append("\n")
                .append(TurnipData.DAY).append(map.get(TurnipData.DAY)).append("\n")
                .append("-------------").append("\n")
                .append(TurnipData.MONDAY_UP).append(map.get(TurnipData.MONDAY_UP)).append(" | ")
                .append(TurnipData.MONDAY_DOWN).append(map.get(TurnipData.MONDAY_DOWN)).append("\n")
                .append(TurnipData.TUESDAY_UP).append(map.get(TurnipData.TUESDAY_UP)).append(" | ")
                .append(TurnipData.TUESDAY_DOWN).append(map.get(TurnipData.TUESDAY_DOWN)).append("\n")
                .append(TurnipData.WEDNESDAY_UP).append(map.get(TurnipData.WEDNESDAY_UP)).append(" | ")
                .append(TurnipData.WEDNESDAY_DOWN).append(map.get(TurnipData.WEDNESDAY_DOWN)).append("\n")
                .append(TurnipData.THURSDAY_UP).append(map.get(TurnipData.THURSDAY_UP)).append(" | ")
                .append(TurnipData.THURSDAY_DOWN).append(map.get(TurnipData.THURSDAY_DOWN)).append("\n")
                .append(TurnipData.FRIDAY_UP).append(map.get(TurnipData.FRIDAY_UP)).append(" | ")
                .append(TurnipData.FRIDAY_DOWN).append(map.get(TurnipData.FRIDAY_DOWN)).append("\n")
                .append(TurnipData.SATURDAY_UP).append(map.get(TurnipData.SATURDAY_UP)).append(" | ")
                .append(TurnipData.SATURDAY_DOWN).append(map.get(TurnipData.SATURDAY_DOWN)).append("\n")
        ;
        out.append("------------").append("\n");
        out.append("总概率:").append("\n");

        for (Object o : prArray) {
            JSONObject tmp = (JSONObject) o;
            out.append(tmp.getString(TurnipData.MODEL)).append(":").append(tmp.getString(TurnipData.PR)).append("\n");
        }
        out.append("------------").append("\n");
        out.append("网页版:").append("\n").append(url).append("\n");
        out.append("祝好运 :)");

        if (ConfigTools.load(ConfigTools.CONFIG, ConfigTools.TURNIP_PROPHET_SEND_TMP_GROUP, Boolean.class)) {
            out.append("\n使用者:").append(sendQQ);
            sendQQ = 891655174L;
        }

        Log.i("TurnipProphet", out.toString() + "\n 发送QQ：" + sendQQ);
        QQBotManager.getInstance().sendMessage(sendQQ, getMessage(out.toString()));
        return prArray.getJSONObject(0).getString(TurnipData.MODEL);
    }

    @Override
    public void onTime(Long qq, String time) {
        super.onTime(qq, time);
        nowTime = Integer.parseInt(time.split(":")[0]);
    }

    public int getTime() {
        if (nowTime == -1) {
            nowTime = Integer.parseInt(AppTools.getHours());
        }
        return nowTime;
    }

    private int getDay() {
        return Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 1;
    }

    public static void main(String[] args) throws Exception {
        TurnipProphet prophet = new TurnipProphet();
        String prices = "108.93.89.84.79........";
        String pattern = "0";
        Map<String, String> map = prophet.openTurnip(prices, pattern);
        prophet.sendQQ(map, prices, pattern);

    }


    public Map<String, String> openTurnip(String prices, String pattern) throws Exception {
        String url = String.format("http://%s/?prices=%s%s",
                ConfigTools.load(ConfigTools.CONFIG, ConfigTools.TURNIP_PROPHET_SERVER, String.class),
                prices,
                pattern == null ? "" : "&pattern=" + pattern
        );
        System.out.println("url = " + url);
        LinkedHashMap<String, String> map = new LinkedHashMap<>();
        WebDriver driver = WebClient.getInstance().getWebDriver();

        driver.get(url);
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        Thread.sleep(500);
        WebElement element = driver.findElement(By.id("output"));
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        List<WebElement> list = element.findElements(By.tagName("tr"));
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        JSONObject pr = new JSONObject();
        JSONArray array = new JSONArray();
        if (list.size() == 0) {
            WebClient.getInstance().quit();
            return null;
        }

        for (WebElement webElement : list) {
            String[] tmp;
            try {
                tmp = webElement.getText().replace(" ~ ", "~").split(" ");
            } catch (Exception e) {
                //e.printStackTrace();
                continue;
            }
            if ("所有趋势".equals(tmp[0])) {
                map.put(TurnipProphet.TurnipData.MONDAY_UP, tmp[3]);
                map.put(TurnipProphet.TurnipData.MONDAY_DOWN, tmp[4]);
                map.put(TurnipProphet.TurnipData.TUESDAY_UP, tmp[5]);
                map.put(TurnipProphet.TurnipData.TUESDAY_DOWN, tmp[6]);
                map.put(TurnipProphet.TurnipData.WEDNESDAY_UP, tmp[7]);
                map.put(TurnipProphet.TurnipData.WEDNESDAY_DOWN, tmp[8]);
                map.put(TurnipProphet.TurnipData.THURSDAY_UP, tmp[9]);
                map.put(TurnipProphet.TurnipData.THURSDAY_DOWN, tmp[10]);
                map.put(TurnipProphet.TurnipData.FRIDAY_UP, tmp[11]);
                map.put(TurnipProphet.TurnipData.FRIDAY_DOWN, tmp[12]);
                map.put(TurnipProphet.TurnipData.SATURDAY_UP, tmp[13]);
                map.put(TurnipProphet.TurnipData.SATURDAY_DOWN, tmp[14]);

                map.put(TurnipProphet.TurnipData.MIX, tmp[15]);
                map.put(TurnipProphet.TurnipData.MAX, tmp[16]);
            } else {
                if (!array.toJSONString().contains(tmp[0])) {
                    JSONObject json = new JSONObject();
                    json.put(TurnipProphet.TurnipData.MODEL, tmp[0]);
                    json.put(TurnipProphet.TurnipData.PR, tmp[1]);
                    array.add(json);
                }
            }
        }
        int maxMoney = 0;
        String maxDay = null;
        for (String key : map.keySet()) {
            if (map.get(key).contains("~")) {
                for (String s : map.get(key).split("~")) {
                    if (Integer.parseInt(s) > maxMoney) {
                        maxMoney = Integer.parseInt(s);
                        maxDay = key;
                    }
                }
            } else {
                if (Integer.parseInt(map.get(key)) > maxMoney) {
                    maxMoney = Integer.parseInt(map.get(key));
                    maxDay = key;
                }
            }
        }
        map.put(TurnipProphet.TurnipData.DAY, maxDay);
        pr.put(TurnipProphet.TurnipData.MODEL, array);
        map.put(TurnipProphet.TurnipData.MODEL, pr.toJSONString());
        WebClient.getInstance().quit();
        return map;
    }
}
/*
null.90...........
null.97...........

null.1!.1@.2!.2@.3!.3@.4!.4@.5!.5@.90.
null.1!.1@.2!.2@.3!.3@.4!.4@.5!.5@.6!.90.
 */