package com.jianshui.api.config;

import org.w3c.dom.*;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.io.StringWriter;
import java.util.Set;

/**
 * @Description
 * @Author 巩权林
 * @Date 2023/3/10 15:43
 **/
public class WebserviceResponseHandler implements SOAPHandler<SOAPMessageContext> {
    @Override
    public Set<QName> getHeaders() {
        return null;
    }

    public String nodeToString(Node node) throws TransformerException {
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, "element-name");

        StringWriter sw = new StringWriter();
        transformer.transform(new DOMSource(node), new StreamResult(sw));

        return sw.toString();
    }

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        SOAPMessage message = context.getMessage();
        Boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (outbound) {
            // 处理传出的SOAP消息
            try {
                SOAPBody body = message.getSOAPBody();
                Node returnNode = body.getFirstChild().getFirstChild();
                Node dataNode = returnNode.getFirstChild();

                addCDataToLeafNodes(dataNode);


//                String xmlStr = XmlUtil.toStr(dataNode,"GBK",false,false).replaceAll("&lt;","<").replaceAll("&gt;",">");
//
//                System.out.println(xmlStr);
//                CDATASection cdata = dataNode.getOwnerDocument().createCDATASection(  xmlStr );
////                CDATASection cdata = dataNode.getOwnerDocument().createCDATASection( "<" + dataNode.getNodeName() +"><?xml version=\"1.0\" encoding=\"GBK\"><![CDATA[037001700107]]]]>><![CDATA["+ XmlUtil.toStr(dataNode) + "</" + dataNode.getNodeName() + ">");
//                returnNode.removeChild(dataNode);
//                returnNode.appendChild(cdata);

//                dataNode.getOwnerDocument().getDocumentElement().setAttribute("","<?xml version=\"1.0\" encoding=\"GBK\"?>");
//                dataNode.getOwnerDocument().setXmlVersion("<?xml version=\"1.0\" encoding=\"GBK\"?>");
                // 设置 SOAP 版本为 1.1\


//                body.getFirstChild().getOwnerDocument().setTextContent(XmlUtil.toStr(dataNode));
//                body.removeChild(dataNode);

//                addCDataToLeafNodes(dataNode);

//                String aa = XmlUtil.toStr(dataNode,"GBK",false,false);
//                returnNode.replaceChild(XmlUtil.parseXml(aa),dataNode);

//                String cdatameg = "<![CDATA["+ XmlUtil.toStr(returnNode.getFirstChild(),"GBK",false,false) +"]]>";
               /* String cdatameg = XmlUtil.toStr(returnNode.getFirstChild(), "GBK", false, false);
//                CDATASection cdata = childNode.getOwnerDocument().createCDATASection(cdatameg);
                cdatameg = cdatameg.replaceAll("&amp;gt;", ">").replaceAll("&lt;", "<").replaceAll("&gt;", ">");

                String modifiedContent = cdatameg.replace("]]>", "]] >>");
                Element element = body.getOwnerDocument().createElement("return");

                CDATASection cdata = body.getFirstChild().getFirstChild().getOwnerDocument().createCDATASection(modifiedContent);
                element.appendChild(cdata);

                body.removeContents();
                body.appendChild(element);

                body.getOwnerDocument().getOwnerDocument().getTextContent().replaceAll("]] >>", "]]>");*/
//                returnNode.removeChild(dataNode);
//                returnNode.getParentNode().appendChild(element);


               /* System.out.println(cdatameg);
                returnNode.setTextContent(cdatameg);

                String modifiedContent = cdatameg.replace("]]>", "]] >");
                Element element = body.getFirstChild().getFirstChild().getOwnerDocument().createElement("AAD");
                CDATASection cdata = body.getFirstChild().getFirstChild().getOwnerDocument().createCDATASection(modifiedContent);
                element.appendChild(cdata);
                body.appendChild(element);*/
//
//
//                String returnNodeStr = XmlUtil.toStr(returnNode).replaceAll("]]>","]]]]><![CDATA[");
//                System.out.println(returnNodeStr);
//
//                body.getFirstChild().replaceChild(XmlUtil.parseXml(returnNodeStr),returnNode);

               /* System.out.println("1=>" + returnNode.getNodeName() + returnNode.getNodeValue());
                System.out.println("1=>" + body.getFirstChild());

                CDATASection cdataSection = returnNode.getOwnerDocument().createCDATASection( returnNode.getTextContent() );
                returnNode.replaceChild(cdataSection, dataNode);
                System.out.println("2=>" + returnNode);*/


                message.saveChanges();


                // 修改CDATA标签位置
//                addCDataToLeafNodes(dataNode);

//                CDATASection cdata = dataNode.getOwnerDocument().createCDATASection(XmlUtil.toStr(dataNode,"GBK",false,false));
//                returnNode.removeChild(dataNode);
//                returnNode.appendChild(cdata);

//                addCDataToLeafNodes(cdata);

//                CDATASection cdata = dataNode.getOwnerDocument().createCDATASection(XmlUtil.toStr(dataNode,"GBK",false,false));
//                returnNode.removeChild(dataNode);
//                returnNode.appendChild(cdata);

                // TODO: 2023/7/12
//                addCDataToLeafNodes(dataNode);


//                String nodeStr = XmlUtil.toStr(returnNode.getFirstChild(), "GBK", false, false)
//                        .replaceAll("&lt;","<").replaceAll("&gt;",">");
//                nodeStr = "<![CDATA[" + nodeStr + "]]>";

//                dataNode.setTextContent(nodeStr);
//                returnNode.replaceChild(dataNode,XmlUtil.parseXml(nodeStr));
//                System.out.println(nodeStr);
                // 将处理后的XML重新设到SOAP消息中
//                System.out.println(nodeStr);


                // body.getFirstChild().removeChild(body.getFirstChild().getFirstChild());
                // CDATASection cdata = Data.getOwnerDocument().createCDATASection(XmlUtil.toStr(fp, "GBK", false, true));
                // body.setTextContent(XmlUtil.toStr(body.getFirstChild()));

            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            // 处理传入的SOAP消息
        }
        return true;
    }

 /*   public String convertDocumentToString(Document document) throws Exception {
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");  // 忽略 XML 声明
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");  // 格式化输出
        transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, "*");  // 适用于所有元素的 CDATA

        DOMSource source = new DOMSource(document);
        StreamResult result = new StreamResult(new StringWriter());
        transformer.transform(source, result);
        return result.getWriter().toString();
    }*/

    /**
     * @Author: kk
     * @Description: CDATA类
     * @DateTime: 2023/6/5 19:12
     * @Params:
     * @Return
     */
    public static void addCDataToLeafNodes(Node returnNode) {
        NodeList childNodes = returnNode.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node childNode = childNodes.item(i);
            if (childNode.getNodeType() == Node.ELEMENT_NODE) {
                addCDataToLeafNodes(childNode);
            } else if (childNode.getNodeType() == Node.TEXT_NODE) {
                String nodeValue = childNode.getNodeValue();
                if ("Code".equals(returnNode.getNodeName()) ||
                        "Message".equals(returnNode.getNodeName()) ||
                    "Fpdm".equals(returnNode.getNodeName()) ) {
                    childNode.setNodeValue(nodeValue);
                } else if ("00".equals(nodeValue)) {
                    CDATASection cdata = childNode.getOwnerDocument().createCDATASection("");
                    returnNode.removeChild(childNode);
                    returnNode.appendChild(cdata);
                } else {
                    CDATASection cdata = childNode.getOwnerDocument().createCDATASection(childNode.getNodeValue());
                    returnNode.removeChild(childNode);
                    returnNode.appendChild(cdata);
                }
            }
        }
    }

        /*String nodeStr = XmlUtil.toStr(returnNode);
        String[] nodeStrList = nodeStr.split("<");
        String a = "";
        for (String s : nodeStrList) {
            a = a + "<![CDATA[<" + s + "]]]]>>";
        }
        System.out.println(a);*/


    /*public static void addCDataToLeafNodes(Node returnNode) {

        NodeList childNodes = returnNode.getChildNodes();


        for (int i = 0; i < childNodes.getLength(); i++) {
            Node childNode = childNodes.item(i);
            Node firstChild = childNode.getFirstChild();
            if (firstChild != null && childNode.getNodeType() == Node.ELEMENT_NODE) {
                addCDataToLeafNodes(childNode);
            } else if (childNode.getNodeType() == Node.TEXT_NODE) {
                String cdatameg = "<" + childNode.getNodeName() + "><![CDATA[" + childNode.getNodeValue() + "]]]] >><![CDATA[</" + childNode.getNodeName() + ">";
                String cdatamegRes = cdatameg.replaceAll("<#text>", "").replaceAll("</#text>", "");
                childNode.setTextContent(cdatamegRes);
            } else {

                String cdatameg = "<![CDATA[]]]] >><![CDATA[";
                childNode.setTextContent(cdatameg);

            }
        }

        *//*String nodeStr = XmlUtil.toStr(returnNode);
        String[] nodeStrList = nodeStr.split("<");
        String a = "";
        for (String s : nodeStrList) {
            a = a + "<![CDATA[<" + s + "]]]]>>";
        }
        System.out.println(a);*//*


    }*/


    public static void main(String[] args) {

        try {
            // 创建 Document 对象
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.newDocument();

            // 创建根元素节点
            Element rootElement = document.createElement("root");

            // 创建父元素节点 myData
            Element myDataElement = document.createElement("myData");

            // 创建字符数据块节点
            CDATASection cdata = document.createCDATASection("]]>This is some  data");
            myDataElement.appendChild(cdata);

            // 将 myData 父元素节点添加到根元素中
            rootElement.appendChild(myDataElement);

            // 创建父元素节点 Fp
            Element FpElement = document.createElement("Fp");

            // 创建字符数据块节点
            CDATASection cdata1 = document.createCDATASection("]]>This is some  data");
            FpElement.appendChild(cdata1);

            // 将 Fp 父元素节点添加到根元素中
            rootElement.appendChild(FpElement);

            // 将根元素节点添加到文档中
            document.appendChild(rootElement);


            // 移除standalone属性
            document.setXmlStandalone(true);

            // 将 Document 对象转换为字符串输出
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();

            // 设置输出属性，包括编码方式
            transformer.setOutputProperty(OutputKeys.METHOD, "xml");
            transformer.setOutputProperty(OutputKeys.ENCODING, "GBK");
            // 美化输出格式
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");

            // 将 XML 声明节点插入到文档开头
            DOMSource source = new DOMSource(document);
            StreamResult result = new StreamResult(System.out);
            transformer.transform(source, result);
        } catch (ParserConfigurationException | TransformerException e) {
            e.printStackTrace();
        }

    }


    @Override
    public boolean handleFault(SOAPMessageContext context) {
        return false;
    }

    @Override
    public void close(MessageContext context) {

    }
}
