package com.ch.jedge.jbot.corpus;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.changhong.qlib.QData;
import com.changhong.qlib.intf.QIData;
import com.changhong.qlib.util.NumberUtils;
import com.changhong.qlib.util.StringUtils;
import com.changhong.qlib.util.file.FileUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class CorpusTask {
    public  static final String qa_pare_fmt_str_ = "\"({\"id\":%d,\"q\":\"%s\",\"a\":\"%s\"})\"";
    public String  baseText;
    public String  key;
    public String  name;
    public String  q_;
    public String  a_;
    private final JSONArray qaList;

    public CorpusTask(QIData data) {
        baseText = data.getString("t");
        name = data.getName();
        key = data.getKey();
        qaList = new JSONArray();
    }

    public void makeCsvFileOutput(String fileName) {
        //遍历qaList数组，生成一个csv的文件序列，到文件路径
        List<String> lines = new ArrayList<>();
        lines.add(",===,,");
        String orgText = ","+baseText+",,";
        orgText = orgText.replaceAll("\n", ",,\n,");
        lines.add(orgText);
        lines.add(",===,,");
        for(Object qa : qaList) {
            if(qa instanceof JSONObject) {
                int id = ((JSONObject) qa).getInteger("id");
                String q = ((JSONObject) qa).getString("q");
                String a = ((JSONObject) qa).getString("a");
                String line = "";
                line = String.format("%03d,%s,%s", id, q, a);
                lines.add(line);
            }
        }
        if(lines.isEmpty()) {
            String line = String.format( "%03d,%s,%s", -1, "<empty>", "<empty>");
            lines.add(line);
        }
        StringUtils.writeStringToFile(new File(fileName), lines, null);
    }

    public boolean updateQuestion(int idx, String q, String a) {
        if(idx<0 || idx>qaList.size()) {
            return false;
        } else if(idx==qaList.size()) {
            if(StringUtils.isValidStr(a) && StringUtils.isValidStr(q)) {
                JSONObject Val = new JSONObject();
                Val.put("a", a);
                Val.put("q", q);
                Val.put("id", idx);
                setVectorId(Val);
                qaList.add(Val);
                return true;
            }
            return false;   //包含空内容的添加
        }
        JSONObject Val = qaList.getJSONObject(idx);
        boolean updated = false;
        if(Val!=null) {
            if(StringUtils.isValidStr(q)) {
                Val.put("q", q);
                updated = true;
            }
            if(StringUtils.isValidStr(a)) {
                Val.put("a", a);
                updated = true;
            }
            if(!Val.containsKey("vi")) {
                updated = true;
                setVectorId(Val);
            }
        }
        return updated;
    }

    public boolean removeQuestion(int idx) {
        if(idx<0 || idx>qaList.size())
            return false;
        qaList.remove(idx);
        resetQuestionNo();
        return true;
    }

    void resetQuestionNo() {
        int id = 0;
        for(Object o :qaList) {
            if(o instanceof JSONObject) {
                ((JSONObject) o).put("id",id);
                id++;
            }
        }
    }

    public boolean updateText(String  text) {
        if(!Objects.equals(baseText, text)) {
            baseText = text;
            return true;
        }
        return false;
    }

    public void setName(String n) {
        this.name = n;
    }

    public void pushQuest(String  text){
        q_ = text;
        if(q_.indexOf('\n')!=-1) {
            q_ = q_.replaceAll("\n","");
        }
    }

    public void pushAnswer(String  text) {
        a_ = text;
        if(a_.indexOf('\n')!=-1) {
            a_ = a_.replaceAll("\n","");
        }
    }

    public String getLastQAContent() {
        int idx = qaList.size();
        String str = String.format(qa_pare_fmt_str_, idx, q_, a_);
        for(Object qa : qaList) {
            // QDLog("Checking old one = %s", StringUtils::valueToJsonString(qa).c_str());
            if(qa instanceof JSONObject && ((JSONObject) qa).containsKey("a") && a_.equals(((JSONObject) qa).getString("a"))) {
                return "";
            }
        }
        QIData val = QData.fromString(str);
        setVectorId(val.asJsonObject());
        qaList.add(val.asJsonObject());
        return str;
    }

    public JSONArray getQAArray() {
        //清空null值的项目
        List<Integer> toDel  =new ArrayList<>();
        for(int i=qaList.size()-1;i>=0;i--) {
            // QDLog("Checking old one = %s", StringUtils::valueToJsonString(qa).c_str());
            Object qa = qaList.get(i);
            if(qa==null || qa instanceof JSONObject && ((JSONObject) qa).isEmpty())
                toDel.add(i);
        }
        for(int i:toDel)
            qaList.remove(i);
        return qaList;
    }

    public String getBaseText() {
        return baseText;
    }

    public String getKey() {
        return key;
    }

    public String getName() {
        return name;
    }

    public boolean empty() {
        return qaList.isEmpty();
    }

    public void saveDefineData(String basePath) {
        String fn = FileUtils.contactPath(basePath, key+".json");
        QIData d = new QData();
        d.setKey(key);
        d.setName(name);
        d.putString("t", baseText); //从baseText中获取Key
        StringUtils.writeStringToFile(fn, d.toJSONString(true));
        fn = FileUtils.contactPath(basePath, key+".qa");
        if(!new File(fn).exists())
            StringUtils.writeStringToFile(fn,"", "UTF-8");
    }

    public void saveQuestions(String basePath) {
        String fn = FileUtils.contactPath(basePath, key+".qa");
        List<String> kl = new ArrayList<>();
        for(Object k : qaList) {
            if(k instanceof JSONObject)
                kl.add(new QData((JSONObject) k).toJSONString());
        }
        StringUtils.writeStringToFile(new File(fn), kl, null);
        if(kl.isEmpty())
            FileUtils.deleteDir(fn,"qa", false);
        //FileUtils.deleteDir(fn,"", false);
    }

    public void loadQuestions(String basePath) {
        String fn = FileUtils.contactPath(basePath, key+".qa");
        List<String> kl = StringUtils.readStringLinesFromFile(fn);
        if(kl==null) {
            return;
        }
        boolean newVi = false;
        qaList.clear();
        for(String l : kl) {
            QIData v = QData.fromString(l);
            if(!v.containsKey("vi")) {
                newVi = true;
                setVectorId(v.asJsonObject());
            }
            qaList.add(v.asJsonObject());
        }
        if(newVi) {
            saveQuestions(basePath);
        }
    }

    public void removeCorpus(String basePath) {
        String fn = FileUtils.contactPath(basePath, key+".json");
        FileUtils.deleteDir(fn,"json", false);
        fn = FileUtils.contactPath(basePath, key+".qa");
        FileUtils.deleteDir(fn,"qa", false);
    }

    public void setVectorId(JSONObject qaVal) {
        long id = 0x00100000 + NumberUtils.randomInt(0x00FFFFFF - 0x00100000);  //随机生成一个64位整型ID
        id = id << 32;
        id += 0x00100000 + NumberUtils.randomInt(0x00FFFFFF - 0x00100000); //
        qaVal.put("vi",id);
    }

    public long getCorpusVi(int id) {
        for(Object v : qaList) {
            if(v instanceof JSONObject && !((JSONObject) v).containsKey("vi"))
                setVectorId((JSONObject) v);
            if(v instanceof JSONObject && ((JSONObject) v).getInteger("id") == id)
                return ((JSONObject) v).getLong("vi");
        }
        return 0;
    }

}
