package com.brilliance.mda.runtime.mda.util;

import com.brilliance.mda.runtime.mda.*;
import com.brilliance.mda.runtime.mda.driver.MdaEnv;
import com.brilliance.mda.runtime.mda.impl.StreamImpl;
import com.brilliance.mda.support.service.CodetableService;
import com.brilliance.mda.support.td.ModuleInfoManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.CollectionUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class Codetables {

    private static final Logger log = LoggerFactory.getLogger(Codetables.class);
    //码表路径
    static String codeTableFilePath = "codeTable";
    static Map<String, List<CodetableItem>> staticCodeTableCache = new ConcurrentHashMap<>();

    public static List<CodetableItem> getCodetable(String codeName) {
        return null;
    }

    public static String getCodetableLabelOfTd(String key, String codetable, String language) {
        String label = "";
        List<CodetableItem> codeTable = getCodeTable(codetable, language);
        if (!CollectionUtils.isEmpty(codeTable)) {
            for (CodetableItem codetableItem : codeTable) {
                if (key.equalsIgnoreCase(codetableItem.getValue())) {
                    label = codetableItem.getLabel();
                    break;
                }
            }
        }
        return label;
    }

    public static String getCodeTableKeyOfTd(String txt, String codetable, String language) {
        String key = "";
        List<CodetableItem> codeTable = getCodeTable(codetable, language);
        if (!CollectionUtils.isEmpty(codeTable)) {
            for (CodetableItem codetableItem : codeTable) {
                if (txt.equals(codetableItem.getLabel())) {
                    key = codetableItem.getValue();
                }
            }
        }
        return key;
    }

    public static void setTblText(String key, String table, String language, String value) {
        File file = new File(codeTableFilePath, table + "_" + language + ".ctl");
        if (file.exists()) {
            String codetable = "<?xml version=\"1.0\" encoding = \"UTF-8\" standalone=\"no\"?>\n<codetable>\n";
            codetable += "<item> description=\"description\" lable=\"" + value + "\" value=\"" + key + "\"/>\n";
            codetable += "</codetable>";
            try {
                FileWriter fileWriter = new FileWriter(file);
                fileWriter.write(codetable);
                fileWriter.flush();
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static IStream getTblKeyList(String codetable, String language) {
        IStream keylst = new StreamImpl();
        List<CodetableItem> codeTable = getCodeTable(codetable, language);
        if (!CollectionUtils.isEmpty(codeTable)) {
            for (CodetableItem codetableItem : codeTable) {
                keylst.addLine(codetableItem.getValue());
            }
        }
        return keylst;
    }
//    public static IStream getTblKeyList(String table, String language) {
//        return getTblKeyList(table, language);
//    }


    public static List<CodetableItem> getCodeTable(String codeName, String lang) {
        List codetable = new ArrayList<>();

        if (codeName.indexOf(":") > 0) {
            String arr[] = codeName.split(":");
            Map<String, Object> fieldInfo = ModuleInfoManager.getModuleFieldInfo(arr[0].trim().toLowerCase(), arr[1].trim().toLowerCase());
            if (fieldInfo == null)
                return codetable;
            codeName = (String) fieldInfo.get("codetable");
            if (MdaUtils.isEmpty(codeName))
                return codetable;
        } else {
            //尝试从组件中加载
            CodetableService codetableService = MdaEnv.getBean(CodetableService.class);
            List<CodetableItem> dbCodeTable = codetableService.selectList(codeName.toUpperCase(), lang);
            if (dbCodeTable != null && !dbCodeTable.isEmpty())
                return dbCodeTable;
        }

        String fileName = codeTableFilePath + "/";
        if ("CN".equals(lang)) {
            fileName = fileName + codeName.toLowerCase() + "_zh_CN.ctl";
        } else {
            fileName = fileName + codeName.toLowerCase() + "_en_US.ctl";
        }
        //Cache判断
        List<CodetableItem> tempCodeTableList = staticCodeTableCache.get(fileName);
        if (tempCodeTableList != null) {
            return tempCodeTableList;
        }
        //判断结束
        log.info("filePath:{}", fileName);
        //if(file.exists()){
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            InputStream ins = new ClassPathResource(fileName).getInputStream();
            if (ins == null) {
                return codetable;
            }
            Document parse = documentBuilder.parse(ins);
            Element documentElement = parse.getDocumentElement();
            NodeList item = documentElement.getElementsByTagName("item");
            for (int i = 0; i < item.getLength(); i++) {
                Element item1 = (Element) item.item(i);
                codetable.add(new CodetableItem(item1.getAttribute("label"), item1.getAttribute("value")));
            }

        } catch (Exception e) {
            log.error(e.getMessage());
            e.printStackTrace();
        }

        //缓存放入
        staticCodeTableCache.put(fileName, codetable);
        return codetable;
    }

    //private static String ATTR_CODE_VALUES="ATTR_CODE_VALUES";
    public static void setCodeValues(String key, IStream stream) {
    }

    public static void setCodeValues(IDatafield<Object> datafield, IStream values) {
        //MdaEnv.getContext().setAttribute(datafield.getParent(),datafield.getName(),ATTR_CODE_VALUES,stream);
        setCodeValues(datafield.getParent(), datafield.getName(), values);
    }

    public static void setCodeValues(IModule parent, String prop, IStream values) {
        //拦截做values专项处理
        Systems.setValuesToContextSet(parent, prop, values);
        MdaEnv.getContext().setAttribute(parent, prop, Constants.ATTR_CODE_VALUES, values);
    }

}
