package com.ruoyi.spider.ie;

import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Entity;

/**
 * 知识点
 * https://www.eepw.com/shijuan/2036_1_1.html
 * 19119260810、260810
 * @author duzj
 *
 */
public class KnowledgeService2 extends AuthService {
    static String tableName = "csdhe_knowledge";

    private void saveOrUpdate(Long subjectId, Entity parent, JSONArray arr) {
        for (int i = 0; i < arr.size(); i++) {
            JSONObject row = arr.getJSONObject(i);
            Entity record = Entity.create(tableName).set("subject_id", subjectId);
            for (String key : new String[] {"id", "pid", "level", "name", "sort", "image", "icon_color", "is_charge", "is_deploy", "weight",
                "tags", "questions_count"}) {
                record.set(key, row.get(key));
            }
            if (null != parent) {
                // record.set("level", parent.getInt("level") + 1).set("pid", parent.getLong("id"));
            } else {
                // record.set("level", 1).set("pid", null);
            }
            // ThreadUtil.sleep(RandomUtil.randomInt(1, 5) * 1000);
            JSONArray children = row.getJSONArray("children");
            if (null != children && children.size() > 0) {
                record.set("id", children.getJSONObject(0).get("pid")).set("level", 1).set("pid", null);
                insertOrUpdate(record, "id", "level");
                saveOrUpdate(subjectId, record, children);
            } else {
                if (StrUtil.isBlankIfStr(record.get("level"))) {
                    record.set("level", 1).set("pid", null);
                }
                insertOrUpdate(record, "id", "level");
            }
            System.out.println(record.getLong("id"));
        }
    }

    public void syncKnowledgeAll() {
        List<Entity> all = find(Entity.create("csdhe_subject"));
        for (Entity row : all) {
            syncKnowledge(row.getLong("id"));// 科目id;
            ThreadUtil.safeSleep(RandomUtil.randomInt(1, 5) * 800);
        }
    }

    public void syncKnowledge(Long subjectId) {
        JSONArray arr = getKnowledge(subjectId);
        saveOrUpdate(subjectId, null, arr);
    }

    /**
     * 根据科目获取知识点
     *
     * @param subjectId
     * @return
     */
    public JSONArray getKnowledge(Long subjectId) {
        Dict params = commonParams();
        params.set("subject_id", subjectId).set("cate_id", "1399");
        JSONObject res = getJson("/api/v1.5.5/auxpolice/index", params, authorization);
        return res.getJSONObject("data").getJSONObject("data").getJSONArray("data");
    }

    /**
     * 根据知识点获取题目
     *
     * @param knowledgeId
     * @return
     */
    public JSONArray getQuestionList(Long subjectId, Long knowledgeId, String type, Integer configId, StringBuilder groupId) {
        // check_error=0&config_id=0&knowledge_id=19053&question_type=0&type=know_test&is_next=0&cate_id=1399&subject_id=1401&good_app_type=senioriup&sign=6c5f13aa30a92c4a08ab8097957786c8
        // &knowledge_id=18996&type=know_test&is_next=0&config_id=0&subject_id=1402&cate_id=1399",
        int errCnt = 0;
        while (errCnt < 5) {
            try {
                Dict params = commonParams();
                if (null != knowledgeId) {
                    params.set("knowledge_id", knowledgeId);
                }
                if (null != configId) {
                    params.set("config_id", configId);
                }
                params.set("is_next", true);
                params.set("question_type", 0).set("type", type);
                params.set("subject_id", subjectId).set("cate_id", "1399");
                JSONObject res = getJson("/api/v1.5.3/question-list", params, authorization);
                JSONObject data = res.getJSONObject("data");
                groupId.append(data.getString("group_id"));
                return data.getJSONArray("data");
            } catch (Exception e) {
                errCnt += 1;
                ThreadUtil.safeSleep(5 * 1000);
            }
        }
        return null;
    }

    JSONObject postQestionCommit(Long subjectId, String type, String groupId, JSONArray json) {
        try {
            ThreadUtil.safeSleep(RandomUtil.randomInt(1, 5) * 800);
            Dict params = commonParams();
            Map<String, String> data = new LinkedHashMap<>();
            data.put("group_id", groupId);
            data.put("group_status", "1");
            data.put("time", "" + (json.size() * 4));
            data.put("is_beiti", "0");
            data.put("last_number", "" + json.size());
            data.put("last_question_id", json.getJSONObject(json.size() - 1).getString("question_id"));
            data.put("type", type);
            data.put("json", json.toJSONString());
            data.put("subject_id", subjectId.toString());
            data.put("cate_id", "1399");
            data.put("good_app_type", "senioriup");
            JSONObject res = postJson("/api/v1.5.3/group-commit", params, data, authorization);
            // System.out.println(res);
            return res;
        } catch (Exception e) {
            return null;
        }
    }

    Dict getQuestionResult(Long subjectId, String groupId) {
        ThreadUtil.safeSleep(RandomUtil.randomInt(1, 5) * 800);
        Dict params = commonParams();
        params.set("group_id", groupId);
        params.set("subject_id", subjectId).set("cate_id", "1399");
        JSONObject res = getJson("/api/v1.5.3/group-result", params, authorization);
        System.out.println(res.toJSONString());
        JSONArray arr = res.getJSONObject("data").getJSONArray("question");
        Dict map = Dict.create();
        for (int i = 0; i < arr.size(); i++) {
            JSONObject row = arr.getJSONObject(i);
            map.set(row.getString("question_id"), row.getString("right_answer"));
        }
        return map;
    }

    public Integer syncKnowQuestions(Set<Long> idCache, Long subjectId, Long knowledgeId, String type, Integer configId) {
        StringBuilder groupId = new StringBuilder();
        JSONArray arr = getQuestionList(subjectId, knowledgeId, type, configId, groupId);
        if (null == arr) {
            return 0;
        }
        int count = 0;
        JSONArray json = new JSONArray(12);
        String tableName = "csdhe_know_question_2";
        for (int i = 0; i < arr.size(); i++) {
            JSONObject row = arr.getJSONObject(i);
            String[] fields = new String[] {"id", "question_id", "uni_key", "type", "type_name", "name", "grade", "score", "number",
                "analysis", "answer"};
            JSONArray ques = row.getJSONArray("material_ques");
            if (row.getBooleanValue("is_materials") && null != ques && ques.size() > 0) {
                for (int j = 0; j < ques.size(); j++) {
                    row = ques.getJSONObject(j);
                    Long questionId = row.getLong("question_id");
                    addRef(questionId, knowledgeId);
                    if (idCache.contains(questionId)) {
                        continue;
                    }
                    Entity record = Entity.create(tableName).set("know_id", knowledgeId);
                    for (String key : fields) {
                        record.set(key, row.get(key));
                    }
                    record.set("options", row.getString("options")).set("subject_id", subjectId);
                    record.set("is_materials", Boolean.TRUE).set("materials", row.getString("materials"));
                    List<Entity> coll = find(Entity.create(tableName).set("question_id", questionId));
                    if (CollUtil.isNotEmpty(coll)) {
                        Entity old = coll.get(0);
                        for (String key : new String[] {"analysis", "answer2", "is_right_answer"}) {
                            record.set(key, old.get(key));
                        }
                    }
                    insertOrUpdate(record, "question_id");
                    System.out.println("知识点ID:" + knowledgeId + "\t问题ID:" + record.getStr("question_id"));
                    idCache.add(questionId);
                    Dict item = Dict.create();
                    item.set("uni_key", record.getStr("uni_key")).set("my_log_id", "0");
                    item.set("is_right", "0").set("time", "4").set("is_flag", "0");
                    item.set("type", row.getString("type")).set("number", "" + i).set("material_id", "0");
                    item.set("selectUnKnow", "1").set("question_type", record.getStr("type"));
                    item.set("know_id", knowledgeId);
                    item.set("question_id", record.getStr("question_id")).set("user_answer", "A").set("answer", "A");
                    json.add(item);
                }
            } else {
                Long questionId = row.getLong("question_id");
                addRef(questionId, knowledgeId);
                if (idCache.contains(questionId)) {
                    continue;
                }
                Entity record = Entity.create(tableName).set("know_id", knowledgeId);
                for (String key : fields) {
                    record.set(key, row.get(key));
                }
                record.set("options", row.getString("options")).set("subject_id", subjectId);
                record.set("is_materials", Boolean.TRUE).set("materials", row.getString("materials"));
                List<Entity> coll = find(Entity.create(tableName).set("question_id", questionId));
                if (CollUtil.isNotEmpty(coll)) {
                    Entity old = coll.get(0);
                    for (String key : new String[] {"analysis", "answer2", "is_right_answer"}) {
                        record.set(key, old.get(key));
                    }
                }
                insertOrUpdate(record, "question_id");
                System.out.println("知识点ID:" + knowledgeId + "\t问题ID:" + record.getStr("question_id"));
                idCache.add(questionId);
                Dict item = Dict.create();
                item.set("uni_key", record.getStr("uni_key")).set("my_log_id", "0");
                item.set("is_right", "0").set("time", "4").set("is_flag", "0");
                item.set("type", row.getString("type")).set("number", "" + i).set("material_id", "0");
                item.set("selectUnKnow", "1").set("question_type", record.getStr("type"));
                item.set("know_id", knowledgeId);
                item.set("question_id", record.getStr("question_id")).set("user_answer", "A").set("answer", "A");
                json.add(item);
            }
            count += 1;
        }
        postQestionCommit(subjectId, type, groupId.toString(), json);
        return count;
    }

    private void addRef(Long questionId, Long knowledgeId) {
        Entity record = Entity.create("csdhe_know_question_ref").set("q_id", questionId).set("know_id", knowledgeId);
        insertOrUpdate(record, "q_id", "know_id");
    }

    public void syncKnowQuestionsAll() {
        // List<Entity> all = find(Entity.create("csdhe_knowledge").set("level", 2));
        String ids =
            "in 21957,21998,21999,22000,22001,22002,22004,22005,22006,22112,22803,22804,22805,22806,22807,22808,22809,22810,22811,22812,22813,22814,22815,22816,22817,22818,22819,22820,22821,22822,22825,22826,22828,22829,22830,23229";
        List<Entity> all = find(Entity.create("csdhe_knowledge").set("id", ids));
        for (Entity row : all) {
            syncKnowQuestionsAll(row);
        }
        ids =
            "in 14317,19043,19042,19041,19040,19038,19037,19036,19035,19030,19027,19026,19025,19024,19023,19022,19021,14318,14316,19029,20528,20527,20525,20524,20523,20522,20521,20519,20518,20517,20516";
        all = find(Entity.create("csdhe_knowledge").set("id", ids));
        for (Entity row : all) {
            syncKnowQuestionsAll(row);
        }
    }

    public void syncQuestionsAll(Long subjectId) {
        List<Entity> all = find(Entity.create("csdhe_knowledge").set("level", 2).set("subject_id", subjectId));
        for (Entity row : all) {
            syncKnowQuestionsAll(row);
        }
    }

    private void syncKnowQuestionsAll(Entity row) {
        Integer total = row.getInt("questions_count");
        Long knowledgeId = row.getLong("id");
        Long subjectId = row.getLong("subject_id");
        String knowName = row.getStr("name");
        Set<Long> existIds = new HashSet<>();
        // List<Entity> coll = find(Entity.create("csdhe_question_ref").set("type", "know_test").set("ref_id", knowledgeId));
        // coll.forEach(item -> {
        // existIds.add(item.getLong("question_id"));
        // });
        int errCnt = 0;
        while (true) {
            if (errCnt >= 5) {
                System.out.println(subjectId + "\t 知识点:" + knowName + "多次未获取到新的题目数据!");
                break;
            }
            Integer current = syncKnowQuestions(existIds, subjectId, knowledgeId, "know_test", null);// 知识点Id
            System.out.println(subjectId + "\t 知识点:" + knowName + "\t 总数:" + total + "\t 本次获取:" + current + "\t 已记录数:" + existIds.size());
            ThreadUtil.safeSleep(RandomUtil.randomInt(1, 5) * 800);
            if (current == 0 && existIds.size() < total) {
                errCnt += 1;
            }
            if (existIds.size() >= total) {
                break;
            }
        }
    }

    public void syncOtherQuestionsALL() {
        List<Entity> all = find(Entity.create("csdhe_subject"));
        List<Integer> cfgIds = Arrays.asList(437, 406, 403);

        for (Entity row : all) {
            // 基础题库,高频错题,智能刷题
            int i = 0;
            for (String type : new String[] {"auto", "high_error", "smart_test"}) {
                Set<Long> idCache = new HashSet<>();
                syncKnowQuestions(idCache, row.getLong("id"), null, type, cfgIds.get(i));// 科目id;
                System.out.println(type + " \t " + row.getLong("id"));
                ThreadUtil.safeSleep(RandomUtil.randomInt(1, 5) * 800);
                i++;
            }

        }
    }

    public static void main(String[] args) {
        KnowledgeService2 service = new KnowledgeService2();
        // service.syncKnowledgeAll();
        // service.syncQuestions(19053l);
        service.syncKnowQuestionsAll();

        // service.syncOtherQuestionsALL();
        // service.syncQuestionsAll(1401l);
    }
}
