package com.cku.restful.v1.open;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import javax.xml.bind.JAXBException;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cku.oa.sfexpress.entity.ExpressOrderResponse;
import com.cku.oa.sfexpress.entity.ExpressPushEntity;
import com.cku.oa.sfexpress.entity.ExpressPushResponse;
import com.cku.oa.sfexpress.entity.Route;
import com.cku.oa.sfexpress.entity.RouteBody;
import com.cku.oa.sfexpress.entity.RoutePushRequest;
import com.cku.oa.sfexpress.entity.RoutePushResponse;
import com.cku.oa.sfexpress.entity.RouteRequest;
import com.cku.oa.sfexpress.entity.RouteResponse;
import com.cku.oa.sfexpress.entity.SfExpressState;
import com.cku.oa.sfexpress.service.SfExpressStateService;
import com.cku.oa.sfexpress.utils.XMLUtils;
import com.cku.oa.sys.service.ExpressSendService;
import com.cku.restful.v1.open.Vo.ClouldPushVo;
import com.cku.thirdparty.oss.OssApiClient;
import com.cku.thirdparty.oss.OssUploadResult;
import com.cku.util.HttpClientUtil;
import com.cku.util.HttpResult;
import com.sf.csim.express.service.CallExpressServiceTools;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.common.web.BaseController;
import com.thoughtworks.xstream.core.util.Base64Encoder;

/**
 * 顺丰揽收和路由状态推送Controller
 *
 * @author zhaoxy
 * @version 2019-08-30
 */
@Controller
@RequestMapping(value = "/api/v1/open/sfexpress")
public class SfExpressController extends BaseController {

	private Logger logger = LoggerFactory.getLogger(SfExpressController.class);

	@Autowired
	private SfExpressStateService sfExpressStateService;

	@Autowired
	private ExpressSendService expressSendService;

	@Value("${sf.serviceUrl}")
	private String sfServiceUrl;

	@Value("${sf.clientcode}")
	private String clientcode;

	@Value("${sf.checkword}")
	private String checkword;
	
	@Value("${sf.serviceUrlOld}")
	private String sfServiceUrlOld;

	@Value("${sf.clientcodeOld}")
	private String clientcodeOld;

	@Value("${sf.checkwordOld}")
	private String checkwordOld;

	@Value("${sf.caacUrl}")
	private String caacUrl;

	@Value("${sf.csvUrl}")
	private String csvUrl;

	@Autowired
	private OssApiClient ossApiClient;

//	@RequestMapping(value = "/ewaybills/back", method = RequestMethod.POST)
//	@ResponseBody
//	public String ewaybills(ClouldPushVo clouldpushVo) throws Exception {
//		logger.info("------------------ ewaybills/back:{}--------------------", clouldpushVo.toString());
//
//		String msgData = clouldpushVo.getMsgData();
//		JSONObject msg = JSONObject.parseObject(msgData);
//		String content = msg.getString("content");
//		String waybillNo = msg.getString("waybillNo");
//
//		Base64Encoder base64Encoder = new Base64Encoder();
//		byte[] fileBytes = base64Encoder.decode(content);
//		InputStream in = new ByteArrayInputStream(fileBytes);
//		OssUploadResult ossResult = ossApiClient.upload(in, "SFPrint", waybillNo);
//		if (Objects.nonNull(in)) {
//			in.close();
//		}
//		logger.info("----- waybillNo:" + waybillNo + "uploadUrl:" + ossResult.getUploadUrl() + " -----");
//
//		JSONObject result = new JSONObject();
//		result.put("success", "true");
//		result.put("msg", "");
//		return result.toJSONString();
//	}

	@RequestMapping(value = "/clouldpush/back", method = RequestMethod.POST)
	@ResponseBody
	public String clouldpush(ClouldPushVo clouldpushVo) throws Exception {
		logger.info("------------------ clouldpush/back:{}--------------------", clouldpushVo.toString());
		String msg = StringEscapeUtils.unescapeHtml4(clouldpushVo.getMsgData());
		logger.info("----- clouldpush msgData:{} -----", msg);
		String content = JSON.parseObject(msg).getString("content");
		String waybillNo = JSON.parseObject(msg).getString("waybillNo");
		Base64Encoder base64Encoder = new Base64Encoder();
		byte[] fileBytes = base64Encoder.decode(content);
		InputStream in = new ByteArrayInputStream(fileBytes);
		OssUploadResult ossResult = ossApiClient.upload(in, "SFPrint", waybillNo);
		if (Objects.nonNull(in)) {
			in.close();
		}
		logger.info("----- waybillNo:" + waybillNo + "uploadUrl:" + ossResult.getUploadUrl() + " -----");

		expressSendService.updateDownUlr(waybillNo, ossResult.getUploadUrl());
		JSONObject result = new JSONObject();
		result.put("success", "true");
		result.put("msg", "");
		return result.toJSONString();
	}

	@RequestMapping(value = "/waybillRoute", method = RequestMethod.POST)
	@ResponseBody
	public String waybillRoute(@RequestBody String json) {
		logger.info("------------------ waybillRoute --------------------");
		JSONObject object = JSONObject.parseObject(json);
		logger.info("----- route:{} -----", object.toJSONString());

		JSONObject body = JSONObject.parseObject(object.getString("Body"));
		JSONArray routes = JSONObject.parseArray(body.getString("WaybillRoute"));
		if (!CollectionUtils.isEmpty(routes)) {
			for (Object route : routes) {
				JSONObject info = JSONObject.parseObject(route.toString());
				sfExpressStateService.newPushRoute(info);
			}
		}
		JSONObject result = new JSONObject();
		result.put("return_code", "0000");
		result.put("return_msg", "成功");
		return result.toJSONString();
	}

	@RequestMapping(value = "/test", method = RequestMethod.GET)
	@ResponseBody
	public void test() {
		logger.info("-------------------test-------------------");
	}

	@RequestMapping(value = "/receiveTest", method = RequestMethod.GET)
	@ResponseBody
	public void receiveTest() {
		sfExpressStateService.overtimeReceive();
	}

	@RequestMapping(value = "/updateSaPayment/{orderNo}", method = RequestMethod.GET)
	@ResponseBody
	public void sendTest(@PathVariable("orderNo") String orderNo) {
		SfExpressState sfExpressState = new SfExpressState();
		sfExpressState.setOrderNo(orderNo);
		sfExpressState.setCreateTime(new Date());
		sfExpressStateService.updateSaPayment(orderNo, sfExpressState);
	}

	/**
	 * 路由推送
	 * 
	 * @param content
	 * @return
	 * @throws JAXBException
	 */
	@RequestMapping(value = "/order", method = RequestMethod.POST)
	@ResponseBody
	public void order(@RequestParam("content") String content) throws JAXBException {
		content = StringEscapeUtils.unescapeHtml4(content);

		if (content != null) {
			logger.info("--------------------------------------");
			logger.info("返回报文: {}", content);
			logger.info("--------------------------------------");
			if (content.contains("ERR")) {
			}
			ExpressOrderResponse expressOrderResponse = (ExpressOrderResponse) XMLUtils
					.xmlConvertBean(ExpressOrderResponse.class, content);

			// 修改send表第三方运单号
			SfExpressState sfExpressState = new SfExpressState();
			sfExpressState.setOrderNo(expressOrderResponse.getBody().getOrderResponse().getOrderid());
			sfExpressState.setWaybillNo(expressOrderResponse.getBody().getOrderResponse().getMailno());
			sfExpressState.setDestcode(expressOrderResponse.getBody().getOrderResponse().getDestcode()); // 目的地区域代码,可用于
			sfExpressState.setOrigincode(expressOrderResponse.getBody().getOrderResponse().getOrigincode());// 原寄地区域代码,可用于
			sfExpressState.setTwoDimensionCode(expressOrderResponse.getBody().getOrderResponse().getRlsInfo()
					.getRlsDetail().getTwoDimensionCode());
//			sfExpressStateDao.updateWaybill(sfExpressState);
			System.out.println(sfExpressState.toString());
		}
	}

	/**
	 * 路由推送
	 * 
	 * @param content
	 * @return
	 * @throws JAXBException
	 */
	@RequestMapping(value = "/routePushService", method = RequestMethod.POST)
	@ResponseBody
	public String routePushService(@RequestParam("content") String content) throws JAXBException {
		content = StringEscapeUtils.unescapeHtml4(content);
		// 输出请求报文
		logger.info("===== routePushService content:{}", content);

		RoutePushResponse resp = new RoutePushResponse();
		resp.setService("RoutePushService");
		resp.setHead("OK");
		if (StringUtils.isEmpty(content) || !content.contains("Request")) { // 空||不包含标签
			resp.setHead("ERR");
			return XMLUtils.beanConvertXml(resp, ExpressPushResponse.class); // 直接返回
		}
		// 解析报文
		RoutePushRequest routePushEntity = (RoutePushRequest) XMLUtils.xmlConvertBean(RoutePushRequest.class, content);
		// 获取路由详情（路由推送接口推送内容不包含opname（路由节点信息） 需要请求路由查询接口查询opname）
		RouteResponse routeResponse = getRouteDetail(routePushEntity);

		Map<String, String> map = new HashMap<>();
		map.put("content", content);
		if (content.contains("CAWGDOG")) {
			// 增量路由信息
			sfExpressStateService.pushRoute(routePushEntity, routeResponse);
		} else if (content.contains("CAWGCAT")) {
			try {
				// 推送给CAAC
				HttpClientUtil.post(null, caacUrl + "routePushService", map);
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else if (content.contains("CAWGCSV")) {
			try {
				// 推送给CSV
				map.put("method", "routePush");
				HttpResult result = HttpClientUtil.get(null, csvUrl, map);
				return result.getResponseBody();
//				System.out.println("result === " + result.getResponseBody());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return XMLUtils.beanConvertXml(resp, RoutePushResponse.class);
	}

	// 路由查询接口
	private RouteResponse getRouteDetail(RoutePushRequest routePushEntity) throws JAXBException {
		// 拼装查询报文
		RouteRequest routeRequest = new RouteRequest();
		routeRequest.setService("RouteService");
		routeRequest.setLang("zh-CN");
		routeRequest.setHead("SLKJ2019");
		RouteBody body = new RouteBody();
		Route route = new Route();
		route.setTracking_type("2"); // 根据顺丰运单号查询
		route.setTracking_number(routePushEntity.getBody().getWaybillRoute().getOrderid());
		body.setRoute(route);
		routeRequest.setBody(body);
		// 转成xml字符串报文
		String reqXml = XMLUtils.beanConvertXml(routeRequest, RouteRequest.class);

		CallExpressServiceTools client = CallExpressServiceTools.getInstance();
		String myReqXML = reqXml.replace("SLKJ2019", clientcodeOld);
		logger.info("请求报文：{}", myReqXML);

		@SuppressWarnings("static-access")
		String respXml = client.callSfExpressServiceByCSIM(sfServiceUrlOld, myReqXML, clientcodeOld, checkwordOld);

		RouteResponse routeResponse = null;
		if (respXml != null) {
			logger.info("--------------------------------------");
			logger.info("返回报文: {}", respXml);
			logger.info("--------------------------------------");
			// 解析返回报文
			routeResponse = (RouteResponse) XMLUtils.xmlConvertBean(RouteResponse.class, respXml);
			System.out.println(JSONObject.toJSONString(routeResponse));
		}
		return routeResponse;
	}

	/**
	 * 揽收推送
	 *
	 * @param content
	 * @return
	 * @throws JAXBException
	 */
	@RequestMapping(value = "/pushOrderState", method = RequestMethod.POST)
	@ResponseBody
	public String pushOrderState(@RequestParam("content") String content) throws JAXBException {
		content = StringEscapeUtils.unescapeHtml4(content);
		// 输出请求报文
		logger.info("===== pushOrderState content:{}", content);
		// 设置response
		ExpressPushResponse resp = new ExpressPushResponse();
		resp.setSuccess("true");
		if (StringUtils.isEmpty(content) || !content.contains("Request")) { // 空||不包含标签
			resp.setSuccess("false");
			resp.setMsg("参数为空");
			return XMLUtils.beanConvertXml(resp, ExpressPushResponse.class); // 直接返回
		}
		// 解析报文
		ExpressPushEntity entity = (ExpressPushEntity) XMLUtils.xmlConvertBean(ExpressPushEntity.class, content);
		if (!"PushOrderState".equals(entity.getService())) { // 不是揽收推送
			resp.setSuccess("false");
			resp.setMsg("请求方法错误");
			return XMLUtils.beanConvertXml(resp, ExpressPushResponse.class); // 直接返回
		}

		Map<String, String> map = new HashMap<>();
		map.put("content", content);
		if (content.contains("CAWGDOG")) {
			// 揽收记录
			sfExpressStateService.pushOrderState(entity);
		} else if (content.contains("CAWGCAT")) {
			try {
				// 推送给CAAC
				HttpClientUtil.post(null, caacUrl + "pushOrderState", map);
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else if (content.contains("CAWGCSV")) {
			try {
				// 推送给CSV
				HttpClientUtil.post(null, caacUrl + "routePush", map);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return XMLUtils.beanConvertXml(resp, ExpressPushResponse.class);
	}

}