package org.dromara.common.sms.client;

import jakarta.xml.soap.*;
import org.dromara.common.sms.client.message.FetchMoResponse;
import org.dromara.common.sms.client.message.GetGroupSmsDeliveryStatusResponse;
import org.dromara.common.sms.client.message.GetSmsDeliveryStatusResponse;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.net.MalformedURLException;

/**
 * 说明：本代码是演示代码，提供短信服务调用参考
 */
public class SmsSendTestClient {

    private String www = "http://192.167.111.239:5000/";

    private String serviceId = "1";

    private String v2 = "v2";
    private String v2Uri = "http://www.huawei.com.cn/schema/common/v2_1";

    private String loc = "loc";
    private String locUri = "http://www.csapi.org/schema/parlayx/sms/send/v2_2/local";


    public SmsSendTestClient(String www, String serviceId) {
        this.www = www;
        this.serviceId = serviceId;
    }


    /**
     * 单条短信发送
     */
    public void sendSms(String spId, String spPassword, String phone, String message) {
        SOAPMessageBuilder builder = SOAPMessageBuilder.newInstance("utf-8");
        buildHeader(builder, spId, spPassword);
        buildSendSmsBody(builder, phone, message);

        System.out.println("发送报文：" + builder);

        String address = www + "http://192.167.111.239:5000/SendSmsService/services/SendSms?wsdl";
        sendSoap(address, builder.getSOAPMessage());
    }

    /**
     * 批量发送
     */
    public void batchSendSms(String spId, String spPassword, String[] phones, String message) {
        SOAPMessageBuilder builder = SOAPMessageBuilder.newInstance("utf-8");
        buildHeader(builder, spId, spPassword);
        buildBatchSendSmsBody(builder, phones, message);

        System.out.println("发送报文：" + builder.toString());

        String address = www + "SendSmsService/services/SendSms";
        sendSoap(address, builder.getSOAPMessage());
    }


    /**
     * 获取状态报告
     */
    public void getDeliveryStatus(String spId, String spPassword, String[] smsIds) {
        SOAPMessageBuilder builder = SOAPMessageBuilder.newInstance("utf-8");
        buildHeader(builder, spId, spPassword);
        buildGetDeliveryStatusBody(builder, smsIds);

        System.out.println("发送报文：" + builder.toString());

        String address = www + "SendSmsService/services/SendSms";
        SOAPMessage resp = sendSoap(address, builder.getSOAPMessage());

        Object respObj = unMarshalSoap(resp, GetSmsDeliveryStatusResponse.class);
        if (respObj != null) {
            System.out.println(respObj.toString());
        }
    }

    /**
     * 获取群发状态报告
     */
    public void getGroupDeliveryStatus(String spId, String spPassword, String groupId) {
        SOAPMessageBuilder builder = SOAPMessageBuilder.newInstance("utf-8");
        buildHeader(builder, spId, spPassword);
        buildGroupGetDeliveryStatusBody(builder, groupId);

        System.out.println("发送报文：" + builder.toString());

        String address = www + "SendSmsService/services/SendSms";
        SOAPMessage resp = sendSoap(address, builder.getSOAPMessage());

        Object respObj = unMarshalSoap(resp, GetGroupSmsDeliveryStatusResponse.class);
        if (respObj != null) {
            System.out.println(respObj.toString());
        }
    }

    /**
     * 获取用户上行短信
     * @param spId
     * @param spPassword
     * @param startTime
     * @param endTime
     * @param mobile
     */
    public void fetchMo(String spId, String spPassword, String startTime, String endTime, String mobile) {
        SOAPMessageBuilder builder = SOAPMessageBuilder.newInstance("utf-8");
        buildHeader(builder, spId, spPassword);
        buildFetchMoBody(builder, startTime, endTime, mobile);

        System.out.println("发送报文：" + builder.toString());

        String address = www + "ReceiveSmsService/services/ReceiveSms";
        SOAPMessage resp = sendSoap(address, builder.getSOAPMessage());

        Object respObj = unMarshalSoap(resp, FetchMoResponse.class);
        if (respObj != null) {
            System.out.println(respObj.toString());
        }

    }

    private void buildSendSmsBody(SOAPMessageBuilder builder, String phone, String message) {
        SOAPElement sendSms = builder.addBodyElements("sendSms", loc, locUri);
        builder.addChildElements(sendSms, "addresses", loc, locUri, "tel:" + phone);
        builder.addChildElements(sendSms, "message", loc, locUri, message);
    }

    private void buildBatchSendSmsBody(SOAPMessageBuilder builder, String[] phones, String message) {
        SOAPElement batchSendSms = builder.addBodyElements("batchSendSms", loc, locUri);

        for (String phone : phones) {
            builder.addChildElements(batchSendSms, "addresses", loc, locUri, "tel:" + phone);
        }

        builder.addChildElements(batchSendSms, "message", loc, locUri, message);
    }

    private void buildGetDeliveryStatusBody(SOAPMessageBuilder builder, String[] smsIds) {
        SOAPElement getSmsDeliveryStatus = builder.addBodyElements("getSmsDeliveryStatus", loc, locUri);

        for (String smsId : smsIds) {
            builder.addChildElements(getSmsDeliveryStatus, "smsId", loc, locUri, smsId);
        }
    }

    private void buildFetchMoBody(SOAPMessageBuilder builder, String startTime, String endTime, String mobile) {
        SOAPElement fetchMo = builder.addBodyElements("fetchMo", loc, locUri);
        builder.addChildElements(fetchMo, "startTime", loc, locUri, startTime);
        builder.addChildElements(fetchMo, "endTime", loc, locUri, endTime);
        builder.addChildElements(fetchMo, "mobile", loc, locUri, mobile);
    }


    private void buildGroupGetDeliveryStatusBody(SOAPMessageBuilder builder, String groupId) {
        SOAPElement getGroupSmsDeliveryStatus = builder.addBodyElements("getGroupSmsDeliveryStatus", loc, locUri);
        builder.addChildElements(getGroupSmsDeliveryStatus, "groupId", null, null, groupId);
    }

    private Object unMarshalSoap(SOAPMessage message, Class clazz) {
        Object resp = null;
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

            SOAPBody body = message.getSOAPBody();

            resp = unmarshaller.unmarshal(body.extractContentAsDocument());
        } catch (SOAPException e) {
            e.printStackTrace();
        } catch (JAXBException e) {
            e.printStackTrace();
        }

        return resp;
    }


    private SOAPMessage sendSoap(String address, SOAPMessage soapMessage) {

        SOAPConnectionWare connection = SOAPConnectionUtil.getConnection();

        try {
            SOAPMessage reply = connection.call(soapMessage, address);
            System.out.println("响应报文：" + SOAPMessageUtil.getString(reply));

            SOAPBody body = reply.getSOAPBody();

            SOAPFault fault = body.getFault();
            if (fault != null) {
                System.out.println(fault.getFaultCode());
                System.out.println(fault.getFaultString());
                Detail detail = fault.getDetail();
                if (detail != null) {
                    System.out.println(detail.getTextContent());
                }

                return null;

            } else {
                NodeList nodeList = body.getChildNodes();
                Node node = nodeList.item(0);
                System.out.println(node.getTextContent());
                return reply;
            }

        } catch (SOAPException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } finally {
            try {
                connection.close();
            } catch (SOAPException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    private void buildHeader(SOAPMessageBuilder builder, String spId, String spPassword) {
        SOAPElement requestSOAPHeader = builder.addHeaderElements("RequestSOAPHeader", v2, v2Uri);
        builder.addChildElements(requestSOAPHeader, "spId", v2, v2Uri, spId);
        builder.addChildElements(requestSOAPHeader, "spPassword", v2, v2Uri, spPassword);
        builder.addChildElements(requestSOAPHeader, "serviceId", v2, v2Uri, serviceId);
    }


    public static void main(String[] args) {
        String www = "http://127.0.0.1:1234/";
        String serviceId = "1";

        SmsSendTestClient c = new SmsSendTestClient(www, serviceId);
        String spId = "65000002";
        String spPassword = "qwe12121";

        String message = "测试短信";    //短信内容

        //---------------------------------------------------------
        //1、单条发送
        String phone = "13546471583";            //接收手机号
        //c.sendSms(spId, spPassword, phone, message);
        //---------------------------------------------------------


        //---------------------------------------------------------
        //2、批量发送
        String[] phones = {"13546471583", "13546471584"};
        //c.batchSendSms(spId, spPassword, phones, message);
        //---------------------------------------------------------


        //---------------------------------------------------------
        //3、通过发送时返回的smsId获取状态报告演示
        String[] smsIds = {"1", "2"};
        c.getDeliveryStatus(spId, spPassword, smsIds);
        //---------------------------------------------------------


        //---------------------------------------------------------
        //4、批量发送状态报告
        String groupId = "190521163120001650000020000001";
        //c.getGroupDeliveryStatus(spId, spPassword, groupId);
        //---------------------------------------------------------


        //---------------------------------------------------------
        //5、查询用户上行短信，建议定时调用查询，如：5分钟查询一次

        //格式为：yyyy-mm-dd hh24:mi:ss，不是必填字段，可以为空
        String startTime = "20190615 13:00:09";
        //格式为：yyyy-mm-dd hh24:mi:ss，不是必填字段，可以为空
        String endTime = null;

        //不是必填字段，可以为空
        String mobile = "15035682266";
        c.fetchMo(spId, spPassword, startTime, endTime, mobile);
        //---------------------------------------------------------

    }

}
