package com.fufan.mtsaas.tools;

import com.alibaba.fastjson.JSON;
import com.fufan.mtsaas.util.EnUtil;
import com.fufan.mtsaas.util.EnUtil;
import org.dom4j.*;

import java.io.UnsupportedEncodingException;
import java.util.*;

public class XMLUtil{
    /**
     * 读取xml
     * @param xml
     * @param nodeptah
     * @return
     * @throws DocumentException
     * @throws UnsupportedEncodingException
     */
    public static Map<String, String> readXMLByNodePath(String xml, String nodeptah) throws DocumentException, UnsupportedEncodingException {
        Document document = DocumentHelper.parseText(xml);
        Map<String, String> paramMap = new HashMap<>();
        List<Element> list = document.selectNodes(nodeptah);

        for (Element elm : list) {
            paramMap.put(elm.getName(), elm.getText());
        }
        return paramMap;
    }

    /**
     * 创建xml
     * @param headMap
     * @param lists
     * @param list
     * @return
     */
    public static String buildRespXML(Map<String, String> headMap,List<Object> lists,List<String> list){
        Document doc = DocumentFactory.getInstance().createDocument();
        Element rootEl = doc.addElement("MESSAGE");
        Element headEl = rootEl.addElement("MHEAD");
        Iterator<String> keys= headMap.keySet().iterator();
        while(keys.hasNext()){
            String key = keys.next();
            Element el = headEl.addElement(key.toUpperCase());
            el.setText((headMap.get(key) != null || "".equals(headMap.get(key)))?headMap.get(key):"");
        }

        Element bodyEl = rootEl.addElement("MBODY");
        if(list.size() > 0){
            Element bodyE2 = bodyEl.addElement(list.get(0));
            for(Object o:lists){
                if(list.size() > 1){
                    Element bodyE3 = bodyE2.addElement(list.get(1));
                    String bodyStr = JSON.toJSONString(o);
                    Map<String,String> bodyMap = (Map)JSON.parseObject(bodyStr);
                    keys= bodyMap.keySet().iterator();
                    while(keys.hasNext()){
                        String key = keys.next();
                        Element el = bodyE3.addElement(key.toUpperCase());
                        el.setText((bodyMap.get(key) != null || "".equals(bodyMap.get(key)))?bodyMap.get(key):null);
                    }
                }else{
                    String bodyStr = JSON.toJSONString(o);
                    Map<String,String> bodyMap = (Map)JSON.parseObject(bodyStr);
                    keys= bodyMap.keySet().iterator();
                    while(keys.hasNext()){
                        String key = keys.next();
                        Element el = bodyE2.addElement(key.toUpperCase());
                        el.setText((bodyMap.get(key) != null || "".equals(bodyMap.get(key)))?bodyMap.get(key):null);
                    }
                }
            }
        }else{
            for(Object o:lists) {
                String bodyStr = JSON.toJSONString(o);
                Map<String, String> bodyMap = (Map) JSON.parseObject(bodyStr);
                keys = bodyMap.keySet().iterator();
                while (keys.hasNext()) {
                    String key = keys.next();
                    Element el = bodyEl.addElement(key.toUpperCase());
                    el.setText((bodyMap.get(key) != null || "".equals(bodyMap.get(key))) ? bodyMap.get(key) : null);
                }
            }
        }
        doc.setXMLEncoding("UTF-8");
        return doc.asXML();
    }

    public static String buildRespXML(Map<String, String> headMap,Map<String, String> map,List<Object> lists,List<String> list){
        Document doc = DocumentFactory.getInstance().createDocument();
        Element rootEl = doc.addElement("MESSAGE");
        Element headEl = rootEl.addElement("MHEAD");
        Iterator<String> keys= headMap.keySet().iterator();
        while(keys.hasNext()){
            String key = keys.next();
            Element el = headEl.addElement(key.toUpperCase());
            el.setText((headMap.get(key) != null || "".equals(headMap.get(key)))?headMap.get(key):"");
        }

        Element bodyEl = rootEl.addElement("MBODY");
        Iterator<String> keyBody= map.keySet().iterator();
        while(keyBody.hasNext()){
            String key = keyBody.next();
            Element el = bodyEl.addElement(key.toUpperCase());
            el.setText((map.get(key) != null || "".equals(map.get(key)))?map.get(key):"");
        }
        if(list.size() > 0){
            Element bodyE2 = bodyEl.addElement(list.get(0));
            for(Object o:lists){
                if(list.size() > 1){
                    Element bodyE3 = bodyE2.addElement(list.get(1));
                    String bodyStr = JSON.toJSONString(o);
                    Map<String,String> bodyMap = (Map)JSON.parseObject(bodyStr);
                    keys= bodyMap.keySet().iterator();
                    while(keys.hasNext()){
                        String key = keys.next();
                        Element el = bodyE3.addElement(key.toUpperCase());
                        el.setText((bodyMap.get(key) != null || "".equals(bodyMap.get(key)))?bodyMap.get(key):null);
                    }
                }else{
                    String bodyStr = JSON.toJSONString(o);
                    Map<String,String> bodyMap = (Map)JSON.parseObject(bodyStr);
                    keys= bodyMap.keySet().iterator();
                    while(keys.hasNext()){
                        String key = keys.next();
                        Element el = bodyE2.addElement(key.toUpperCase());
                        el.setText((bodyMap.get(key) != null || "".equals(bodyMap.get(key)))?bodyMap.get(key):null);
                    }
                }
            }
        }else{
            for(Object o:lists) {
                String bodyStr = JSON.toJSONString(o);
                Map<String, String> bodyMap = (Map) JSON.parseObject(bodyStr);
                keys = bodyMap.keySet().iterator();
                while (keys.hasNext()) {
                    String key = keys.next();
                    Element el = bodyEl.addElement(key.toUpperCase());
                    el.setText((bodyMap.get(key) != null || "".equals(bodyMap.get(key))) ? bodyMap.get(key) : null);
                }
            }
        }
        doc.setXMLEncoding("UTF-8");
        return doc.asXML();
    }

    public static Map<String, Object> Dom2Map(Document doc){
        Map<String, Object> map = new HashMap<String, Object>();
        if(doc == null) {
            return map;
        }
        Element root = doc.getRootElement();
        for (Iterator iterator = root.elementIterator(); iterator.hasNext();) {
            Element e = (Element) iterator.next();
            List list = e.elements();
            if(list.size() > 0){
                map.put(e.getName(), Dom2Map(e));
            }else {
                map.put(e.getName(), e.getText());
            }
        }
        return map;
    };

    public static Map Dom2Map(Element e){
        Map map = new HashMap();
        List list = e.elements();
        if(list.size() > 0){
            for (int i = 0;i < list.size(); i++) {
                Element iter = (Element) list.get(i);
                List mapList = new ArrayList();
                if(iter.elements().size() > 0){
                    Map m = Dom2Map(iter);
                    if(map.get(iter.getName()) != null){
                        Object obj = map.get(iter.getName());
                        if(!obj.getClass().getName().equals("java.util.ArrayList")){
                            mapList = new ArrayList();
                            mapList.add(obj);
                            mapList.add(m);
                        }
                        if(obj.getClass().getName().equals("java.util.ArrayList")){
                            mapList = (List) obj;
                            mapList.add(m);
                        }
                        map.put(iter.getName(), mapList);
                    }else {
                        map.put(iter.getName(), m);
                    }
                }
                else{
                    if(map.get(iter.getName()) != null){
                        Object obj = map.get(iter.getName());
                        if(!obj.getClass().getName().equals("java.util.ArrayList")){
                            mapList = new ArrayList();
                            mapList.add(obj);
                            mapList.add(iter.getText());
                        }
                        if(obj.getClass().getName().equals("java.util.ArrayList")){
                            mapList = (List) obj;
                            mapList.add(iter.getText());
                        }
                        map.put(iter.getName(), mapList);
                    }else{
                        map.put(iter.getName(), iter.getText());
                    }
                }
            }
        }else{
            map.put(e.getName(), e.getText());}
        return map;
    }

    public static String responseXml(String xml,String companyKey) {
        Document doc;
        try {
            doc = DocumentHelper.parseText(xml);
            doc.setXMLEncoding("UTF-8");
            String mac = EnUtil.xorAndGenMac(doc.asXML(), companyKey);
            Element docBody = doc.getRootElement().element("MBODY");
            Element macE = docBody.addElement("MAC");
            macE.setText(mac);

            String xmlStr = doc.asXML();
            //数据长度
            String xmlLength = String.format("%04X", xmlStr.length()).toUpperCase();
            if (xmlLength.length() > 4) {
                xmlLength = "FFFF";
            }
            return xmlLength + xmlStr;
        } catch (Exception e) {
            return "转换报文异常";
        }
    }
}
