package nc.bs.cmp.settlement.listener;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.NCLocator;
import nc.bs.logging.Logger;
import nc.itf.arap.byzitf.IbyzLogRcord;
import nc.itf.uap.IUAPQueryBS;
import nc.jdbc.framework.SQLParameter;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.pubitf.para.ISysInitDAO;
import nc.vo.arap.arc.ByzLogRcordVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.paratemp.SysinittempVO;

public class SettleForARC {
	private ObjectMapper mapper;
	static final char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
	static final char hexDigitsLower[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e',
			'f' };
	/**
	 * 
	 * @param pk
	 * @param src_code ARC全局唯一单据号
	 * @param type     3、资产处置应收单 6、调拨应付单 7、付款单
	 * @return
	 * @throws BusinessException
	 */
	public String sendApprove(String pk, String src_code, Integer type, String reson, int auittype)
			throws BusinessException {
//		NCLocator.getInstance().lookup(ISecurityTokenCallback.class).token("NCSystem".getBytes(), "pfxx".getBytes());
		mapper = new ObjectMapper();
		String arcip = null, request = null, response = null;
		try {
			// 审批给ARC
			ObjectNode data = mapper.createObjectNode();
			// 单据主键
			data.put("pkCard", pk);
			// 回退类型
			data.put("type", type);
			// 单据编号(ARC)
			data.put("billno", src_code);
			// 审批结果
			data.put("auditResult", auittype);
			// 回退原因
			if (auittype == 0)
				data.put("backReason", "支付成功");
			else
				data.put("backReason", reson);
			// 回退用户
			String user = InvocationInfoProxy.getInstance().getUserId();
			data.put("backUser", user);
			// 回退用户名
			data.put("backUserName", getUserName(user));

			if (type == 6) {
				String str = reson.substring(0, reson.indexOf("#"));
				data.put("faceWebsite", str);
				data.put("yfBillDate", reson.substring(str.length() + 1, reson.length()));
			}

			if (type == 3 && auittype == 0) {
				String str = reson.substring(0, reson.indexOf("#"));
				data.put("yfFinanceOrg", str);
				data.put("yfBill", reson.substring(reson.indexOf("#") + 1, reson.indexOf("*")));
				data.put("payable_pk", reson.substring(reson.indexOf("*") + 1, reson.length()));
			}
			arcip = getSysinittempValue("backtobyz");
			request = getResult(data);
			// 推送给ARC
			response = sendPost(arcip, request);
			JsonNode json = mapper.readTree(response);
			if (json.findValue("code").asInt() != 200) {
				if (json.findValue("msg") == null)
					throw new BusinessException("ARC返回信息：null");
				throw new BusinessException("ARC返回信息：" + json.findValue("msg").asText());
			}
		} catch (IOException e) {
			throw new BusinessException(e.getMessage());
		} finally {
			IbyzLogRcord ibyzLogRcord = (IbyzLogRcord) NCLocator.getInstance().lookup(IbyzLogRcord.class);
			ByzLogRcordVO byzLogRcordVO = new ByzLogRcordVO();
			byzLogRcordVO.setVbillcode(src_code);
			byzLogRcordVO.setItf_type("arap相关单据审批回调ARC");
			byzLogRcordVO.setItfclass(this.getClass().toString());
			byzLogRcordVO.setNcctobyzresult(request);
			byzLogRcordVO.setByztonccparam(response);
			byzLogRcordVO.setItfaddress(arcip);
			try {
				ibyzLogRcord.RcordLogBYZ__RequiresNew(byzLogRcordVO);
			} catch (BusinessException e) {
				Logger.error(e.getMessage(), e);
				Logger.error("日志生成失败！！nc.itf.fa.byzlog.IbyzLogRcord");
			}
		}
		return response;
	}

	private String getUserName(String usercode) throws BusinessException {
		String sql = "SELECT USER_NAME FROM SM_USER WHERE cuserid = ?";
		SQLParameter parameter = new SQLParameter();
		parameter.addParam(usercode);
		IUAPQueryBS bs = NCLocator.getInstance().lookup(IUAPQueryBS.class);
		String result = (String) bs.executeQuery(sql, parameter, new ColumnProcessor());
		if (result == null) {
			throw new BusinessException("没有找到该用户,请检查数据:" + usercode);
		}
		return result;
	}

	private String getResult(JsonNode data) throws BusinessException, IOException {
		ObjectMapper mapper = new ObjectMapper();
		ObjectNode json = mapper.createObjectNode();
		String appid = getSysinittempValue("appid");
		String appkey = getSysinittempValue("appkey");
		long time = System.currentTimeMillis();
		String token = MD5Upper(appid + appkey + time);
		json.put("appid", appid);
		json.put("time", time);
		json.put("token", token);
		json.set("data", data);
		return mapper.writeValueAsString(json);
	}

	private String getSysinittempValue(String initcode) throws BusinessException {
		SysinittempVO sysinittempVO = NCLocator.getInstance().lookup(ISysInitDAO.class).getSysInitTempVO(initcode);
		if (sysinittempVO != null) {
			return sysinittempVO.getDefaultvalue();
		}
		return null;
	}
	
	/**
	 * 对字符串 MD5 加密
	 * 
	 * @param plainText 传入要加密的字符串
	 * @return MD5加密后生成32位(大写字母+数字)字符串
	 */
	private String MD5Upper(String plainText) {
		try {
			// 获得MD5摘要算法的 MessageDigest 对象
			MessageDigest md = MessageDigest.getInstance("MD5");

			// 使用指定的字节更新摘要
			md.update(plainText.getBytes());

			// 获得密文
			byte[] mdResult = md.digest();
			// 把密文转换成十六进制的字符串形式
			int j = mdResult.length;
			char str[] = new char[j * 2];
			int k = 0;
			for (int i = 0; i < j; i++) {
				byte byte0 = mdResult[i];
				str[k++] = hexDigits[byte0 >>> 4 & 0xf];// 取字节中高 4 位的数字转换, >>> 为逻辑右移，将符号位一起右移
				str[k++] = hexDigits[byte0 & 0xf]; // 取字节中低 4 位的数字转换
			}
			return new String(str);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
     * 向指定 URL 发送POST方法的请求
     * 
     * @param url
     *            发送请求的 URL
    
     * @return 所代表远程资源的响应结果
	 * @throws BusinessException 
     */
    public static String sendPost(String postUrl, String postData) throws BusinessException {
        try {
            //发送POST请求
            URL url = new URL(postUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setUseCaches(false);
            conn.setDoOutput(true);
            conn.setConnectTimeout(60000);
            conn.setReadTimeout(60000);
            conn.setRequestProperty("Content-Length", "" + postData.length());
            OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
            out.write(postData);
            out.flush();
            out.close();
            //获取响应状态
            if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
                throw new BusinessException("connect failed!");
            }
            //获取响应内容体
            String line, result = "";
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
            while ((line = in.readLine()) != null) {
                result += line + "\n";
            }
            in.close();
            return result;
        } catch (IOException e) {
        	 e.printStackTrace(System.out);
        	 throw new BusinessException(e.getMessage());
        }
    }
}
