package weaver.interfaces.htsc.cus;

import java.lang.reflect.Field;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.interfaces.htsc.comInfo.PropBean;
import weaver.interfaces.htsc.cus.webservices.jtgl.InputData;
import weaver.interfaces.htsc.cus.webservices.jtgl.RootData;
import weaver.interfaces.htsc.util.XmlUtils;

/**
 * 浪潮工具类
 */
public class LangChaoClient extends BaseBean {
  
  private static final String MASTER_PATH = "%s/cwbase/JTGL/ZQFYJK.asmx";
  private static final String SLAVE_PATH = "%s/cwbase/service/jtgl/zqfyjk.asmx?wsdl";
  private static final String PART_TIME_TYPE = "@";
  private static HashMap<String, String> repalce_symbols = new HashMap<String, String>();
  
  static {
    repalce_symbols.put("<", "《");
    repalce_symbols.put(">", "》");
    repalce_symbols.put("&", "且");
    repalce_symbols.put("'", "‘");
    repalce_symbols.put("\"", "“");
  }
  
  /**
   * 费用确认通用方法 分别调用浪潮主库和从库
   *
   * @param datas
   * @return
   */
  public String saveHtFydj(List<InputData> datas) {
    String result = "fail";
    try {
      //格式化数据
      for (InputData data : datas) {
        //去除所有字符串中的空格值
        Field[] fields = data.getClass().getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
          Field f = fields[i];
          f.setAccessible(true);
          if ("java.lang.String".equals(f.getType().getName())) {
            String value = (String) f.get(data);
            if (value != null) {
              //替换所有空格
              value = value.replaceAll("\\s", "");
              f.set(data, value);
            }
          }
        }
  
        data.setBXR(replacePartTime(data.getBXR()));
        data.setFTR(replacePartTime(data.getFTR()));
  
        if (null != data.getZY()) {
          String value = data.getZY().replaceAll("\\s", "");
          for (Entry<String, String> entry : repalce_symbols.entrySet()) {
            value = value.replaceAll(entry.getKey(), entry.getValue());
          }
          data.setZY(value);
        }
      }
      RootData rootData = new RootData();
      rootData.setList(datas);
      String applyId = rootData.getList().get(0).getDJID();
      String xmlString = XmlUtils.toXml(rootData, RootData.class, true);
      boolean skipMaster = "true"
          .equalsIgnoreCase(Util.null2String(new PropBean().getPropName("SkipLangChaoMaster")));
      if (skipMaster) {
        String slaveResponse = saveSlaveFydj(xmlString);
        writeLog("save to langchao slave, applyId: " + applyId + ", response: " + slaveResponse);
        if (slaveResponse.contains("成功")) {
          result = "success";
        }
      } else {
        String masterResponse = saveMasterFydj(xmlString);
        if ("1".equals(Util.null2String(new PropBean().getPropName("show.debug.log")))) {
          writeLog("save to langchao master, applyId: " + applyId + ", response: " + masterResponse);
        }
        String slaveResponse = saveSlaveFydj(xmlString);
        if ("1".equals(Util.null2String(new PropBean().getPropName("show.debug.log")))) {
          writeLog("save to langchao slave, applyId: " + applyId + ", response: " + slaveResponse);
        }
        if (masterResponse.contains("成功") && slaveResponse.contains("成功")) {
          result = "success";
        } else if (!masterResponse.contains("成功") && slaveResponse.contains("成功")) {
          result = "slave_success";
        } else if (masterResponse.contains("成功") && !slaveResponse.contains("成功")) {
          result = "master_success";
        }
      }
    } catch (Exception e) {
      writeLog("save to langchao error!", e);
    }
    return result;
  }
  
  private String replacePartTime(String str) {
    if (org.apache.commons.lang.StringUtils.isEmpty(str)) {
      return "";
    }
    str = str.replaceAll("(" + PART_TIME_TYPE + "[a-zA-Z0-9_]+)", "");
    
    return str;
  }
  
  /**
   * 保存到主库（主库需要登陆）
   *
   * @param xmlString
   * @return
   */
  public String saveMasterFydj(String xmlString) {
    String processId = login();
    String response = "";
    HashMap<String, String> param = new LinkedHashMap<>();
    param.put("PID", processId);
    param.put("FYDJXml", xmlString);
    String endpoint = String
        .format(MASTER_PATH, Util.null2String(new PropBean().getPropName("LangChaoMasterIp")));
    String method = "SaveFydj";
    String soapAction = "http://tempuri.org/";
    response = invoke(endpoint, method, soapAction, param);
    writeLog("lang chao master save xmlString: " + xmlString + ", response: " + response);
    quit(processId);
    return response;
  }
  
  /**
   * 保存到从库
   *
   * @param xmlString
   * @return
   */
  public String saveSlaveFydj(String xmlString) {
    String response = "";
    HashMap<String, String> param = new LinkedHashMap<>();
    param.put("appCode", "02");
    param.put("FYDJXml", xmlString);
    String endpoint = String
        .format(SLAVE_PATH, Util.null2String(new PropBean().getPropName("LangChaoSlaveIp")));
    String method = "SaveFydj";
    String soapAction = "http://tempuri.org/";
    response = invoke(endpoint, method, soapAction, param);
    writeLog("lang chao slave save xmlString: " + xmlString + ", response: " + response);
    return response;
  }
  
  /**
   * 主库登陆接口
   *
   * @return
   */
  public String login() {
    String response = "";
    HashMap<String, String> param = new LinkedHashMap<>();
    param.put("Server", Util.null2String(new PropBean().getPropName("LangChaoMasterServer")));
    param.put("AppID", Util.null2String(new PropBean().getPropName("LangChaoMasterAppId")));
    param.put("Date", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
    param.put("Uid", Util.null2String(new PropBean().getPropName("LangChaoMasterUid")));
    param.put("PassWord", Util.null2String(new PropBean().getPropName("LangChaoMasterPassword")));
    String method = "UserLogin52";
    String endpoint = String
        .format(MASTER_PATH, Util.null2String(new PropBean().getPropName("LangChaoMasterIp")));
    String soapAction = "http://tempuri.org/";
    response = invoke(endpoint, method, soapAction, param);
    writeLog("lang chao master login response: " + response);
    return response;
  }
  
  /**
   * 主库登出接口
   *
   * @param processId
   * @return
   */
  public String quit(String processId) {
    String response = "";
    if (StringUtils.isBlank(processId)) {
      throw new NullPointerException("processId is empty!");
    }
    HashMap<String, String> param = new LinkedHashMap<>();
    param.put("processid", processId);
    String method = "UserQuit";
    String endpoint = String
        .format(MASTER_PATH, Util.null2String(new PropBean().getPropName("LangChaoMasterIp")));
    String soapAction = "http://tempuri.org/";
    response = invoke(endpoint, method, soapAction, param);
    writeLog("lang chao master quit response: " + response);
    return response;
  }
  
  /**
   * webservice通用invoke方法
   *
   * @param endpoint
   * @param method
   * @param soapAction
   * @param param
   * @return
   */
  public String invoke(String endpoint, String method, String soapAction,
      HashMap<String, String> param) {
    Service service = new Service();
    String str = "";
    try {
      Call call = (Call) service.createCall();
      call.setTargetEndpointAddress(endpoint);
      //设置要调用哪个方法
      call.setOperationName(new QName(soapAction, method));
      if (CollectionUtils.isNotEmpty(param.keySet())) {
        for (Entry<String, String> entry : param.entrySet()) {
          //设置要传递的参数
          call.addParameter(new QName(soapAction, entry.getKey()), XMLType.XSD_STRING,
              ParameterMode.IN);
        }
      }
      //（标准的类型）
      call.setReturnType(XMLType.XSD_STRING);
      call.setUseSOAPAction(true);
      call.setSOAPActionURI(soapAction + method);
      Object[] params = new Object[param.size()];
      params = param.values().toArray(params);
      str = (String) call.invoke(params);
    } catch (Exception e) {
      e.printStackTrace();
      writeLog("invoke lang chao interface error!", e);
    }
    return str;
  }
}
