package com.fjs.scenic.service.ticket.impl;

import java.io.StringReader;
import java.io.StringWriter;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fjs.scenic.cyt.request.ApplyOrderRefundByUserRequestBody;
import com.fjs.scenic.cyt.request.CancelOrderByOTARequestBody;
import com.fjs.scenic.cyt.request.CreateOrderRequestBody;
import com.fjs.scenic.cyt.request.CreatePaymentOrderRequestBody;
import com.fjs.scenic.cyt.request.GetOrderByOTARequestBody;
import com.fjs.scenic.cyt.request.GetProductByOTARequestBody;
import com.fjs.scenic.cyt.request.GetProductStockByOTARequestBody;
import com.fjs.scenic.cyt.request.PayOrderRequestBody;
import com.fjs.scenic.cyt.request.Request;
import com.fjs.scenic.cyt.request.RequestBody;
import com.fjs.scenic.cyt.request.RequestHeader;
import com.fjs.scenic.cyt.response.ApplyOrderRefundByUserResponseBody;
import com.fjs.scenic.cyt.response.CreateOrderResponseBody;
import com.fjs.scenic.cyt.response.CreatePaymentOrderResponseBody;
import com.fjs.scenic.cyt.response.EditOrderStatusByOTAResponseBody;
import com.fjs.scenic.cyt.response.GetOrderByOTAResponseBody;
import com.fjs.scenic.cyt.response.GetProductByOTAResponseBody;
import com.fjs.scenic.cyt.response.GetProductByOTAResponseBody.ProductInfos.ProductInfo;
import com.fjs.scenic.cyt.response.GetProductByOTAResponseBody.ProductInfos.ProductInfo.BaseInfo;
import com.fjs.scenic.cyt.response.GetProductByOTAResponseBody.ProductInfos.ProductInfo.BookConfig;
import com.fjs.scenic.cyt.response.GetProductByOTAResponseBody.ProductInfos.ProductInfo.PriceConfig;
import com.fjs.scenic.cyt.response.GetProductByOTAResponseBody.ProductInfos.ProductInfo.PriceConfig.CalendarPrices.CalendarPrice;
import com.fjs.scenic.cyt.response.GetProductStockByOTAResponseBody;
import com.fjs.scenic.cyt.response.GetProductStockByOTAResponseBody.ProductstockInfos.ProductstockInfo;
import com.fjs.scenic.cyt.response.PayOrderResponseBody;
import com.fjs.scenic.cyt.response.Response;
import com.fjs.scenic.cyt.utils.AgentStandardExchangeJsonObject;
import com.fjs.scenic.cyt.utils.Base64Util;
import com.fjs.scenic.cyt.utils.EncryptUtil;
import com.fjs.scenic.cyt.utils.HttpUtil;
import com.fjs.scenic.cyt.utils.JsonUtils;
import com.fjs.scenic.entity.good.DateSurplus;
import com.fjs.scenic.entity.good.Goods;
import com.fjs.scenic.entity.good.PriceRule;
import com.fjs.scenic.entity.order.ErrorOrder;
import com.fjs.scenic.entity.order.Orders;
import com.fjs.scenic.entity.order.PlayMan;
import com.fjs.scenic.mapper.good.DateSurplusMapper;
import com.fjs.scenic.mapper.good.GoodsMapper;
import com.fjs.scenic.mapper.good.PriceRuleMapper;
import com.fjs.scenic.mapper.order.ErrorOrderMapper;
import com.fjs.scenic.mapper.order.OrdersMapper;
import com.fjs.scenic.mapper.order.PlayManMapper;
import com.fjs.scenic.service.ticket.TicketService;
import com.fjs.scenic.ticket.config.CytConfiguration;
import com.fjs.scenic.utils.Cons;
import com.fjs.scenic.utils.ReturnResult;
import com.fjs.scenic.utils.WXPayUtil;

@Component
public class TicketServiceImpl implements TicketService {

	private Logger log = LoggerFactory.getLogger(TicketServiceImpl.class);

	@Autowired
	private CytConfiguration cytConfiguration;
	@Autowired
	private GoodsMapper goodsMapper;
	@Autowired
	private PriceRuleMapper priceRuleMapper;
	@Autowired
	private DateSurplusMapper dateSurplusMapper;
	@Autowired
	private ErrorOrderMapper errorOrderMapper;
	@Autowired
	private OrdersMapper ordersMapper;
	@Autowired
	private PlayManMapper playManMapper;
	@Autowired
	private RedisTemplate<String, Object> redisTemplate;

	public void creatOTAOrder() {
		// 请求体
		// --------------------获取产品信息--------------------
		GetProductByOTARequestBody body = new GetProductByOTARequestBody();
		body.setMethod("SINGLE"); // 仅支持SINGLE方法
		body.setCurrentPage("");
		body.setPageSize("");
		body.setResourceId("44");

		Request request = new Request();

		// 获取产品信息
		Response response = sendData(request, body, "getProductByOTA");

		if (response == null) {
			System.out.println(":response-> response is null");
			return;
		}

		GetProductByOTAResponseBody getProductByOTAResponseBody = (GetProductByOTAResponseBody) response.getBody();

		System.out.println(":response-> " + JSON.toJSONString(getProductByOTAResponseBody));
	}

	public String createPaymentOrder(String goodsId, String price) {
		Request request = new Request();
		// ---------------------创建订单-----------------------
		CreatePaymentOrderRequestBody body = new CreatePaymentOrderRequestBody();
		CreatePaymentOrderRequestBody.OrderInfo orderInfo = new CreatePaymentOrderRequestBody.OrderInfo();
		CreatePaymentOrderRequestBody.OrderInfo.Product product = new CreatePaymentOrderRequestBody.OrderInfo.Product();
		// 产品信息
		product.setResourceId(goodsId);// 产品ID
		product.setProductName("欢乐谷测试票");// 票名
		/*
		 * SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		 * product.setVisitDate(format.format(new Date()));
		 */// 游览日期
		product.setVisitDate("2019-4-23");
		product.setSellPrice(price);// 人价 单位：分

		// 取票人信息
		CreatePaymentOrderRequestBody.OrderInfo.ContactPerson contactPerson = new CreatePaymentOrderRequestBody.OrderInfo.ContactPerson();

		contactPerson.setName("LWQ-cyttest");
		contactPerson.setMobile("13823122406");
		contactPerson.setCredentialsType("ID_CARD");
		contactPerson.setCredentials("360122199011201234");

		// 游客信息，根据产品的实际情况处理
		// 产品bookPersonType为CONTACT_PERSON时，person节点赋空值即可
		orderInfo.setVisitPerson(new CreatePaymentOrderRequestBody.OrderInfo.VisitPerson());

		// OTA订单ID
		orderInfo.setOrderId(UUID.randomUUID().toString());
		// 产品信息
		orderInfo.setProduct(product);
		// 取票人信息
		orderInfo.setContactPerson(contactPerson);
		// 订单数量
		orderInfo.setOrderQuantity("1");
		// 订单金额
		orderInfo.setOrderPrice("10000");
		// 订单状态
		orderInfo.setOrderStatus("PREPAY_ORDER_PRINTING");

		orderInfo.setSubstockId("117");

		// o.setOrderStatus("CASHPAY_ORDER_INIT");

		CreatePaymentOrderRequestBody.OrderInfo.VisitPerson visitPerson = new CreatePaymentOrderRequestBody.OrderInfo.VisitPerson();
		List<CreatePaymentOrderRequestBody.OrderInfo.VisitPerson.Person> visiList = visitPerson.getPerson();
		CreatePaymentOrderRequestBody.OrderInfo.VisitPerson.Person person = new CreatePaymentOrderRequestBody.OrderInfo.VisitPerson.Person();
		person.setName("杨亚");
		person.setCredentialsType("ID_CARD");
		person.setCredentials("500237199402280020");
		visiList.add(person);
		orderInfo.setVisitPerson(visitPerson);

		body.setOrderInfo(orderInfo);

		Response response = sendData(request, body, "createPaymentOrder");

		if (response == null) {
			System.out.println(":response-> response is null");
			return ":response-> response is null";
		}

		CreatePaymentOrderResponseBody createOrderResponse = (CreatePaymentOrderResponseBody) response.getBody();

		System.out.println(":response-> " + JSON.toJSONString(createOrderResponse));
		return JSON.toJSONString(createOrderResponse);
	}

	private Response sendData(Request request, RequestBody body, String method) {
		request.setBody(body);
		request.setHeader(new RequestHeader());
		request.getHeader().setApplication("tour.ectrip.com");
		request.getHeader().setBodyType(request.getBody().getClass().getSimpleName());
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		request.getHeader().setCreateTime(format.format(new Date()));
		request.getHeader().setCreateUser(cytConfiguration.getCreateUser());
		request.getHeader().setVersion("v1.0.0");
		request.getHeader().setProcessor("DataExchangeProcessor");
		request.getHeader().setSupplierIdentity("");

		JAXBContext requestJc;
		try {
			requestJc = JAXBContext.newInstance("com.fjs.scenic.cyt.request");
			Marshaller requestMarshaller = requestJc.createMarshaller();

			StringWriter sw = new StringWriter();
			requestMarshaller.marshal(request, sw);
			String requestString = sw.toString();
			log.info("发送给分销系统的xml={}", requestString);
			requestString = Base64Util.getBASE64(requestString);

			AgentStandardExchangeJsonObject requsetJson = new AgentStandardExchangeJsonObject();
			requsetJson.setData(requestString);
			requsetJson.setSecurityType("MD5");
			requsetJson.setSigned(EncryptUtil.MD5Hex(cytConfiguration.getKey() + requestString).toUpperCase());
			log.info("开始发送给分销系统的xml={}", requestString);
			String responseString = HttpUtil.httpPost(cytConfiguration.getApiUrl(), method,
					JsonUtils.marshalToString(requsetJson));
			log.info("畅游通响应后返回responseString={}",responseString);
			if (null == responseString) {
				// 畅游通交互失败
				log.error("畅游通响应回来的参数为空，请求参数=requestString={}",requestString);
				throw new Exception("response is empty");
			} else {
				log.info("畅游通响应回来的参数={}", responseString);
			}

			AgentStandardExchangeJsonObject responseJson = new AgentStandardExchangeJsonObject();
			try {
				responseJson = JsonUtils.unmarshalFromString(responseString, AgentStandardExchangeJsonObject.class);
			} catch (Exception e) {
				log.error("畅游通响应回来的参数转换异常，请求参数=requestString={}",requestString);
				e.printStackTrace();
			} finally {
				responseJson.setPlanString(responseString);
			}
			String responseData = responseJson.getData();

			if (!StringUtils.equals(EncryptUtil.MD5Hex(cytConfiguration.getKey() + responseData).toUpperCase(),
					responseJson.getSigned().toUpperCase())) {
				log.error("畅游通响应回来的参数解密失败，请求参数=requestString={}",requestString);
			}
			responseData = Base64Util.getFromBASE64(responseData);
			log.info("分销系统响应回来的xml={}", responseData);
			StringReader reader = new StringReader(responseData);
			JAXBContext responseJc = JAXBContext.newInstance("com.fjs.scenic.cyt.response");
			Unmarshaller responseUnmarshaller = responseJc.createUnmarshaller();
			Response response = (Response) responseUnmarshaller.unmarshal(reader);

			return response;
		} catch (Exception e) {
			e.printStackTrace();
			log.error("请求畅游通接口发生异常，请求参数body={}",JSONObject.toJSONString(body));
			return null;
		}

	}

	public void getProduct() {
		Request request = new Request();
		// 请求体
		// --------------------获取产品信息--------------------
		GetProductByOTARequestBody body = new GetProductByOTARequestBody();
		body.setMethod("ALL"); // 仅支持SINGLE方法
		body.setCurrentPage("0");
		body.setPageSize("100");
		body.setResourceId("44");

		// 获取产品信息
		Response response = sendData(request, body, "getProductByOTA");
		if (response == null) {
			log.error("获取产品信息为空:response-> response is null");
			return;
		}
		GetProductByOTAResponseBody getProductByOTAResponseBody = (GetProductByOTAResponseBody) response.getBody();
		System.out.println(":response-> " + JSON.toJSONString(getProductByOTAResponseBody));
		log.info("获取产品列表:response={}", JSON.toJSONString(getProductByOTAResponseBody));
		if (StringUtils.isBlank(getProductByOTAResponseBody.getCount())) {
			log.info("获取产品列表数量为空count={}", getProductByOTAResponseBody.getCount());
			return;
		}
		;
		if (Integer.parseInt(getProductByOTAResponseBody.getCount()) <= 0) {
			log.info("获取产品列表数量为空count={}", getProductByOTAResponseBody.getCount());
			return;
		}
		List<ProductInfo> productInfo = getProductByOTAResponseBody.getProductInfos().getProductInfo();
		if (productInfo.size() <= 0) {
			log.info("获取产品列表数量为空count={}", getProductByOTAResponseBody.getCount());
			return;
		}
		StringBuffer sb = new StringBuffer();
		productInfo.forEach(pi -> {
			BaseInfo baseInfo = pi.getBaseInfo();
			if (baseInfo == null) {
				return;
			}
			sb.append(baseInfo.getResourceId()).append(",");
			String sortType="0";
			String qrcode="0";
			String doorType="dm";
			Goods goods = goodsMapper.selectByGoodsId(Integer.parseInt(baseInfo.getResourceId()));
			if(pi.getIsstock()!=null){
				sortType = pi.getIsstock()+"";
			}
			if(StringUtils.isNotBlank(pi.getSzgardengatecode())){
				doorType = pi.getSzgardengatecode().equals("1")?"dm":"xm";
			}
			if(pi.getSpecial()!=null){
				qrcode = pi.getSpecial()==2?"1":"0";
			}
			
			BookConfig bc = pi.getBookConfig();
			String personType = "0";
			if(bc!=null && StringUtils.isNotBlank(bc.getBookPersonType())){
				personType = bc.getBookPersonType().equals("CONTACT_PERSON_AND_VISIT_PERSON")?"1":"0";
			}
			if (goods != null) {
				goods.setName(baseInfo.getProductName());
				goods.setSort(pi.getSort());
				goods.setSightName(baseInfo.getProductName());
				goods.setResourceid(baseInfo.getResourceId());
				goods.setScenicId(1);
				goods.setRemind(pi.getProductDescription().getRemind());
				goods.setDoorType(doorType);
				goods.setQrcode(qrcode);
				goods.setSortType(sortType);
				goods.setPersonType(personType);
				goodsMapper.updateByCytGoodsIdSelective(goods);
			} else {
				goods = new Goods();
				goods.setSort(pi.getSort());
				goods.setName(baseInfo.getProductName());
				goods.setSightName(baseInfo.getProductName());
				goods.setResourceid(baseInfo.getResourceId());
				goods.setScenicId(1);
				goods.setDoorType(doorType);
				goods.setQrcode(qrcode);
				goods.setSortType(sortType);
				goods.setRemind(pi.getProductDescription().getRemind());
				goods.setPersonType(personType);
				goodsMapper.insert(goods);
			}
			// 門票規則
			/*
			 * BookConfig bookConfig = pi.getBookConfig(); if(bookConfig!=null){
			 * TicketRuleWithBLOBs ticketRule =
			 * ticketRuleMapper.selectByGoodsId(Integer.parseInt(baseInfo.
			 * getResourceId())); if(ticketRule!=null){
			 * ticketRuleMapper.updateByCytGoodsIdSelective(ticketRule); }
			 * 
			 * 
			 * }
			 */
			// 價格規則
			priceRuleMapper.deleteByGoodsId(Integer.parseInt(baseInfo.getResourceId()));
			dateSurplusMapper.deleteByGoodsId(Integer.parseInt(baseInfo.getResourceId()));
			PriceConfig priceConfig = pi.getPriceConfig();
			if (priceConfig == null) {
				return;
			}
			List<CalendarPrice> calendarPrice = priceConfig.getCalendarPrices().getCalendarPrice();
			if (calendarPrice != null && calendarPrice.size() > 0) {
				calendarPrice.forEach(cp -> {
					PriceRule priceRule = new PriceRule();
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
					priceRule.setGoodsId(Integer.parseInt(baseInfo.getResourceId()));
					try {
						priceRule.setDate(sdf.parse(cp.getUseDate()));
					} catch (ParseException e) {
						log.error("同步游玩日期异常goodsid={},date={}", baseInfo.getResourceId(), cp.getUseDate());
						e.printStackTrace();
						return;
					}
					priceRule.setSellPrice(Integer.parseInt(cp.getSellPrice()));// 售价
					priceRule.setRepertory(Integer.parseInt(cp.getSellstock()));
					priceRule.setSettlementPrice(Integer.parseInt(cp.getSellPrice()));// 结算价
					priceRule.setSuggestPrice(Integer.parseInt(cp.getMarketPrice()));// 门市价
					priceRuleMapper.insertSelective(priceRule);
					// 插入时间段和库存
					getProductStock(baseInfo.getResourceId(), cp.getUseDate(), priceRule.getId());

				});
			}

		});
		String goodsIds = sb.toString();
		String[] gids = goodsIds.split(",");
		/*
		 * if(goodsIds.contains(",")){ goodsIds =
		 * goodsIds.substring(0,goodsIds.length() - 1); //goodsIds =
		 * goodsIds.substring(goodsIds.length(), goodsIds.length()-1); }
		 */
		goodsMapper.deleteGoodsNotIn(gids);
		Set<String> keys = redisTemplate.keys("priceRule:" + "*");
        redisTemplate.delete(keys);
        Set<String> keys2 = redisTemplate.keys("indexTopData:" + "*");
        redisTemplate.delete(keys2);
	}

	public String getOrder(String cytOrderNo) {
		Request request = new Request();
		GetOrderByOTARequestBody body = new GetOrderByOTARequestBody();
		// 畅游通生成的订单ID：
		body.setPartnerOrderId(cytOrderNo);
		Response response = sendData(request, body, "getOrderByOTA");
		if (response == null) {
			System.out.println(":response-> response is null");
			return ":response-> response is null";
		}
		GetOrderByOTAResponseBody GetOrderResponse = (GetOrderByOTAResponseBody) response.getBody();
		System.out.println(":response-> " + JSON.toJSONString(GetOrderResponse));
		return JSON.toJSONString(GetOrderResponse);
	}

	public ReturnResult refundTicket(Orders order, String num) {
		ApplyOrderRefundByUserResponseBody applyOrderRefundResponse;
		try {
			Request request = new Request();
			ApplyOrderRefundByUserRequestBody body = new ApplyOrderRefundByUserRequestBody();
			ApplyOrderRefundByUserRequestBody.OrderInfo refund = new ApplyOrderRefundByUserRequestBody.OrderInfo();
			// 畅游通订单ID
			refund.setPartnerorderId(order.getDistOrderNo());
			// 分销商退款流水号ID
			refund.setRefundSeq(order.getOrderNo());
			// 订单金额
			Integer totelPrice = order.getTotelPrice();
			refund.setOrderPrice(totelPrice + "");
			// 订单票张数
			refund.setOrderQuantity(num);
			// 退订张数
			refund.setRefundQuantity(num);
			// 退订金额
			refund.setOrderRefundPrice(totelPrice + "");
			// 退订手续费
			refund.setOrderRefundCharge("0");
			List<PlayMan> playMans = playManMapper.getPlayMansByOrderId(order.getId());
			ApplyOrderRefundByUserRequestBody.OrderInfo.VisitPerson visitPerson = new ApplyOrderRefundByUserRequestBody.OrderInfo.VisitPerson();
			List<ApplyOrderRefundByUserRequestBody.OrderInfo.VisitPerson.Person> visiList = visitPerson.getPerson();
			playMans.forEach(pms -> {
				ApplyOrderRefundByUserRequestBody.OrderInfo.VisitPerson.Person person = new ApplyOrderRefundByUserRequestBody.OrderInfo.VisitPerson.Person();
				person.setName(pms.getName());
				person.setCredentialsType("ID_CARD");
				person.setCredentials(pms.getIdCard());
				visiList.add(person);
			});
			refund.setVisitPerson(visitPerson);

			// 退订说明
			refund.setRefundExplain("行程取消");
			body.setOrderInfo(refund);
			log.info("向票务系统发起退款申请body={}", JSONObject.toJSONString(body));
			Response response = sendData(request, body, "applyOrderRefundByUser");
			if (response == null) {
				log.error("向票务系统发起退款申请失败，未返回数据order={}", JSONObject.toJSONString(order));
				return ReturnResult.build(500, "网络异常");
			}
			JSONObject json = (JSONObject) JSONObject.toJSON(response);
			log.info("申请退款请求票务返回参数response={}", JSONObject.toJSONString(response));
			String code = json.getJSONObject("header").getString("code");
			if (StringUtils.isBlank(code) || !code.equals("1000")) {
				log.error("向票务系统发起退款申请失败，返回数据状态码不正确,data={}",JSONObject.toJSONString(response));
				return ReturnResult.build(500, json.getJSONObject("header").getString("describe"));
			}
			applyOrderRefundResponse = (ApplyOrderRefundByUserResponseBody) response.getBody();
			log.info("------------用户申请退款------------");
			return ReturnResult.ok(applyOrderRefundResponse);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("向票务系统发起退款申请，异常order={}", JSONObject.toJSONString(order));
			return ReturnResult.build(500, "网络异常");
		}
	}

	public String getProductStock(String goodsId, String time, Integer priceRoleId) {
		log.info("获取库存，根据时间段goodsId={},time={},priceRoleId={}", goodsId, time, priceRoleId);
		Request request = new Request();
		GetProductStockByOTARequestBody body = new GetProductStockByOTARequestBody();
		body.setMethod("getProductStock");
		body.setProductId(goodsId);
		body.setServiceProvider("222");
		body.setStime(time);
		Response response = sendData(request, body, "getProductStock");
		if (response == null) {
			System.out.println(":response-> response is null");
			return ":response-> response is null";
		}
		GetProductStockByOTAResponseBody applyOrderRefundResponse = (GetProductStockByOTAResponseBody) response
				.getBody();
		if (applyOrderRefundResponse.getStatus() != 200) {
			return JSON.toJSONString(applyOrderRefundResponse);
		}
		System.out.println(":response-> " + JSON.toJSONString(applyOrderRefundResponse));
		if (applyOrderRefundResponse != null && applyOrderRefundResponse.getProductstockInfos() != null
				&& applyOrderRefundResponse.getProductstockInfos().getProductstockInfo() != null
				&& applyOrderRefundResponse.getProductstockInfos().getProductstockInfo().size() > 0) {
			List<ProductstockInfo> productstockInfo = applyOrderRefundResponse.getProductstockInfos()
					.getProductstockInfo();
			productstockInfo.forEach(p -> {
				DateSurplus dateSurplus = new DateSurplus();
				dateSurplus.setId(Integer.parseInt(p.getSubstockId()));
				dateSurplus.setGoodsId(Integer.parseInt(goodsId));
				dateSurplus.setPriceRuleId(priceRoleId);
				dateSurplus.setStartTime(p.getStarttime());
				dateSurplus.setEndTime(p.getEndtime());
				dateSurplus.setSurplus(Integer.parseInt(p.getSurplus()));
				dateSurplusMapper.insert(dateSurplus);
			});

		}
		return JSON.toJSONString(applyOrderRefundResponse);
	}

	public ReturnResult getCytProductStock(PriceRule priceRule) {
		log.info("获取库存，根据时间段goodsId={},time={},priceRoleId={}", priceRule.getGoodsId(), priceRule.getDate(),
				priceRule.getId());
		Request request = new Request();
		GetProductStockByOTARequestBody body = new GetProductStockByOTARequestBody();
		body.setMethod("getProductStock");
		body.setProductId(priceRule.getGoodsId() + "");
		body.setServiceProvider("222");
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

		body.setStime(format.format(priceRule.getDate()));
		Response response = sendData(request, body, "getProductStock");
		if (response == null) {
			log.error("获取库存，分销返回null，priceRule={}",JSONObject.toJSONString(priceRule));
			return ReturnResult.build(500, "网络异常");
		}
		if(!response.getHeader().getCode().equals("1000")){
			log.error("获取库存失败返回errorinfo={}",response.getHeader().getDescribe());
			return ReturnResult.build(500, "网络异常");
		}
		GetProductStockByOTAResponseBody applyOrderRefundResponse = (GetProductStockByOTAResponseBody) response
				.getBody();
		if (applyOrderRefundResponse.getStatus() != 200) {
			log.error("获取库存，分销返回错误，data={}",JSON.toJSONString(applyOrderRefundResponse));
			return ReturnResult.build(500, applyOrderRefundResponse.getMsg());
		}
		/*
		 * if(applyOrderRefundResponse!=null &&
		 * applyOrderRefundResponse.getProductstockInfos()!=null &&
		 * applyOrderRefundResponse.getProductstockInfos().getProductstockInfo()
		 * !=null &&
		 * applyOrderRefundResponse.getProductstockInfos().getProductstockInfo()
		 * .size()>0){ List<ProductstockInfo> productstockInfo =
		 * applyOrderRefundResponse.getProductstockInfos().getProductstockInfo()
		 * ; productstockInfo.forEach(p->{ DateSurplus dateSurplus = new
		 * DateSurplus();
		 * dateSurplus.setId(Integer.parseInt(p.getSubstockId()));
		 * dateSurplus.setGoodsId(Integer.parseInt(goodsId));
		 * dateSurplus.setPriceRuleId(priceRoleId);
		 * dateSurplus.setStartTime(p.getStarttime());
		 * dateSurplus.setEndTime(p.getEndtime());
		 * dateSurplus.setSurplus(Integer.parseInt(p.getSurplus()));
		 * dateSurplusMapper.insert(dateSurplus); });
		 * 
		 * }
		 */
		return ReturnResult.ok(applyOrderRefundResponse.getProductstockInfos());
	}

	@Override
	public ReturnResult createOrder(Orders order, List<PlayMan> playMans, String goodsId, Integer price, int num) {
		try {
			log.info("下单请求票务方法参数，order={}，playMans={},", JSONObject.toJSON(order), JSONObject.toJSON(playMans));
			Request request = new Request();
			// ---------------------创建订单-----------------------
			CreateOrderRequestBody body = new CreateOrderRequestBody();
			CreateOrderRequestBody.OrderInfo orderInfo = new CreateOrderRequestBody.OrderInfo();
			CreateOrderRequestBody.OrderInfo.Product product = new CreateOrderRequestBody.OrderInfo.Product();
			// 产品信息
			product.setResourceId(goodsId);// 产品ID
			product.setProductName(order.getOrderName());// 票名
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
			product.setVisitDate(format.format(order.getPlayTime()));
			product.setSellPrice(price + "");// 人价 单位：分
			// 取票人信息
			CreateOrderRequestBody.OrderInfo.ContactPerson contactPerson = new CreateOrderRequestBody.OrderInfo.ContactPerson();
			contactPerson.setName(order.getBuyUserName());
			contactPerson.setMobile(order.getBuyPhone());
			if(playMans.isEmpty()){
				contactPerson.setCredentialsType("OTHER");
			}else{
				contactPerson.setCredentialsType("ID_CARD");
				contactPerson.setCredentials(order.getBuyIdCard());
			}
			/*contactPerson.setCredentialsType("ID_CARD");
			contactPerson.setCredentials(order.getBuyIdCard());*/
			// 游客信息，根据产品的实际情况处理
			// 产品bookPersonType为CONTACT_PERSON时，person节点赋空值即可
			// orderInfo.setVisitPerson(new
			// CreateOrderRequestBody.OrderInfo.VisitPerson());
			CreateOrderRequestBody.OrderInfo.VisitPerson visitPerson = new CreateOrderRequestBody.OrderInfo.VisitPerson();
			List<CreateOrderRequestBody.OrderInfo.VisitPerson.Person> visiList = visitPerson.getPerson();
			if(!playMans.isEmpty()){
				playMans.forEach(pms -> {
					CreateOrderRequestBody.OrderInfo.VisitPerson.Person person = new CreateOrderRequestBody.OrderInfo.VisitPerson.Person();
					person.setName(pms.getName());
					person.setCredentialsType("ID_CARD");
					person.setCredentials(pms.getIdCard());
					visiList.add(person);
				});
			}
			orderInfo.setVisitPerson(visitPerson);
			// OTA订单ID
			orderInfo.setOrderId(order.getOrderNo());
			// 产品信息
			orderInfo.setProduct(product);
			// 取票人信息
			orderInfo.setContactPerson(contactPerson);
			// 订单数量
			orderInfo.setOrderQuantity(num + "");
			// 订单金额
			orderInfo.setOrderPrice(order.getTotelPrice() + "");
			// 订单状态
			orderInfo.setOrderStatus("PREPAY_ORDER_INIT");
			if(null!=order.getDistTimeId()){
				orderInfo.setSubstockId(order.getDistTimeId() + "");
			}
			// o.setOrderStatus("CASHPAY_ORDER_INIT");
			body.setOrderInfo(orderInfo);
			log.info("下单请求票务参数body={}", JSONObject.toJSON(body));
			Response response = sendData(request, body, "createOrder");
			if (response == null) {
				log.error("未支付订单提交返回null,data={}", JSON.toJSONString(order));
				return ReturnResult.build(500, "网络异常，请稍后再试");
			}
			JSONObject json = (JSONObject) JSONObject.toJSON(response);
			log.info("下单请求票务返回参数response={}", JSONObject.toJSONString(response));
			String code = json.getJSONObject("header").getString("code");
			if (StringUtils.isBlank(code) || !code.equals("1000")) {
				log.error("下单请求票务返回异常，error={}",json.getJSONObject("header").getString("describe"));
				return ReturnResult.build(500, json.getJSONObject("header").getString("describe"));
			}
			CreateOrderResponseBody createOrderResponse = (CreateOrderResponseBody) response.getBody();
			log.info("未支付订单提交返回数据data={}", JSON.toJSONString(createOrderResponse));
			if (createOrderResponse.getOrderInfo().getOrderStatus().equals("PREPAY_ORDER_NOT_PAYED")) {
				return ReturnResult.ok(createOrderResponse.getOrderInfo().getPartnerorderId());
			}
			log.error("未支付订单提交返回数据data={}", JSON.toJSONString(createOrderResponse));
			return ReturnResult.build(500, "网络异常，稍后再试");
		} catch (Exception e) {
			e.printStackTrace();
			log.error("未支付订单提交异常data={}", JSON.toJSONString(order));
			return ReturnResult.build(500, "网络异常，请稍后再试");
		}
	}

	public ReturnResult getTestProductStock(String goodsId, String time) {
		log.info("获取库存，根据时间段goodsId={},time={}", goodsId, time);
		Request request = new Request();
		GetProductStockByOTARequestBody body = new GetProductStockByOTARequestBody();
		body.setMethod("getProductStock");
		body.setProductId(goodsId);
		body.setServiceProvider("222");
		body.setStime(time);
		Response response = sendData(request, body, "getProductStock");
		if (response == null) {
			log.error("获取库存，分销返回null，priceRule={}",goodsId);
			return ReturnResult.build(500, "网络异常");
		}
		if(!response.getHeader().getCode().equals("1000")){
			log.error("获取库存失败返回errorinfo={}",response.getHeader().getDescribe());
			return ReturnResult.build(500, "网络异常");
		}
		GetProductStockByOTAResponseBody applyOrderRefundResponse = (GetProductStockByOTAResponseBody) response
				.getBody();
		if (applyOrderRefundResponse.getStatus() != 200) {
			return ReturnResult.build(500, applyOrderRefundResponse.getMsg());
		}
		/*
		 * if(applyOrderRefundResponse!=null &&
		 * applyOrderRefundResponse.getProductstockInfos()!=null &&
		 * applyOrderRefundResponse.getProductstockInfos().getProductstockInfo()
		 * !=null &&
		 * applyOrderRefundResponse.getProductstockInfos().getProductstockInfo()
		 * .size()>0){ List<ProductstockInfo> productstockInfo =
		 * applyOrderRefundResponse.getProductstockInfos().getProductstockInfo()
		 * ; productstockInfo.forEach(p->{ DateSurplus dateSurplus = new
		 * DateSurplus();
		 * dateSurplus.setId(Integer.parseInt(p.getSubstockId()));
		 * dateSurplus.setGoodsId(Integer.parseInt(goodsId));
		 * dateSurplus.setPriceRuleId(priceRoleId);
		 * dateSurplus.setStartTime(p.getStarttime());
		 * dateSurplus.setEndTime(p.getEndtime());
		 * dateSurplus.setSurplus(Integer.parseInt(p.getSurplus()));
		 * dateSurplusMapper.insert(dateSurplus); });
		 * 
		 * }
		 */
		return ReturnResult.ok(applyOrderRefundResponse.getProductstockInfos());
	}

	@Override
	public String updateOrder(String price, String otaOrderNo) {
		Request request = new Request();
		PayOrderRequestBody body = new PayOrderRequestBody();
		PayOrderRequestBody.OrderInfo orderInfo = new PayOrderRequestBody.OrderInfo();
		orderInfo.setOrderPrice(price);
		orderInfo.setOrderStatus("ORDER_RESERVE_SUCCESSFUL");
		orderInfo.setPartnerOrderId(otaOrderNo);
		body.setOrderInfo(orderInfo);
		Response response = sendData(request, body, "payOrder");
		if (response == null) {
			log.error("获取库存，分销返回null，otaOrderNo={}",otaOrderNo);
			return null;
		}
		if(!response.getHeader().getCode().equals("1000")){
			log.error("获取库存失败返回errorinfo={}",response.getHeader().getDescribe());
			return response.getHeader().getDescribe();
		}
		PayOrderResponseBody applyOrderRefundResponse = (PayOrderResponseBody) response.getBody();
		log.info(":response-> " + JSON.toJSONString(applyOrderRefundResponse));
		return JSON.toJSONString(applyOrderRefundResponse);
	}

	@Override
	public String refundOrder(String orderNo, String otaOrderNo) {
		Request request = new Request();
		ApplyOrderRefundByUserRequestBody body = new ApplyOrderRefundByUserRequestBody();
		ApplyOrderRefundByUserRequestBody.OrderInfo refund = new ApplyOrderRefundByUserRequestBody.OrderInfo();
		// 畅游通订单ID
		refund.setPartnerorderId(otaOrderNo);
		// 分销商退款流水号ID
		refund.setRefundSeq(orderNo);
		// 订单金额
		// Double total = (double) (order.getTotalPrice() * 100);
		refund.setOrderPrice("10000");
		// 订单票张数
		refund.setOrderQuantity("1");
		// 退订张数
		refund.setRefundQuantity("1");
		// 退订金额
		refund.setOrderRefundPrice("10000");
		// 退订手续费
		refund.setOrderRefundCharge("0");
		// 退订说明
		refund.setRefundExplain("");
		body.setOrderInfo(refund);
		Response response = sendData(request, body, "applyOrderRefundByUser");
		if (response == null) {
			log.error("获取库存，分销返回null，otaOrderNo={}",otaOrderNo);
			return null;
		}
		if(!response.getHeader().getCode().equals("1000")){
			log.error("获取库存失败返回errorinfo={}",response.getHeader().getDescribe());
			return response.getHeader().getDescribe();
		}
		ApplyOrderRefundByUserResponseBody applyOrderRefundResponse = (ApplyOrderRefundByUserResponseBody) response
				.getBody();
		log.info(":response-> " + JSON.toJSONString(applyOrderRefundResponse));
		return JSON.toJSONString(applyOrderRefundResponse);
	}

	@Override
	public ReturnResult updateOrderToPayment(Orders order) {
		try {
			Request request = new Request();
			PayOrderRequestBody body = new PayOrderRequestBody();
			PayOrderRequestBody.OrderInfo orderInfo = new PayOrderRequestBody.OrderInfo();
			orderInfo.setOrderPrice(order.getTotelPrice() + "");
			orderInfo.setOrderStatus("ORDER_RESERVE_SUCCESSFUL");
			orderInfo.setPartnerOrderId(order.getDistOrderNo());
			orderInfo.setSubstocktimes(order.getParkingTime());
			body.setOrderInfo(orderInfo);
			Response response = sendData(request, body, "payOrder");
			log.info("调用票务系统修改订单状态为已支付返回response={}", JSONObject.toJSONString(response));
			if (response == null) {
				return errorRefund(order);
			}
			if(!response.getHeader().getCode().equals("1000")){
				log.error("调用票务系统修改订单状态为已支付失败返回errorinfo={}",response.getHeader().getDescribe());
				return errorRefund(order);
			}
			/*
			 * JSONObject json = (JSONObject)JSONObject.toJSON(response);
			 * if(StringUtils.isNotBlank(json.getJSONObject("header").getString(
			 * "describe"))){ return
			 * ReturnResult.build(500,json.getJSONObject("header").getString(
			 * "describe")); }
			 */
			PayOrderResponseBody applyOrderRefundResponse = (PayOrderResponseBody) response.getBody();
			if (applyOrderRefundResponse.getOrderInfo().getOrderStatus().equals("PREPAY_ORDER_PRINT_SUCCESS")) {
				order.setStatus(Cons.ORDER_STATUS.TICKET);
				//TODO 设置二维码
				if(StringUtils.isNotBlank(applyOrderRefundResponse.getOrderInfo().getQrcode())){
					order.setQrcode(applyOrderRefundResponse.getOrderInfo().getQrcode());
				}
				int i = ordersMapper.update(order);
				if (i <= 0) {
					log.error("更新票务订单为已支付成功，微信更新失败，order={}",JSONObject.toJSONString(order));
					ErrorOrder record = new ErrorOrder();
					record.setOrderId(order.getId());
					record.setOrderNo(order.getOrderNo());
					record.setTime(new Date());
					record.setDescription("分销系统订单状态修改为已支付，微信系统修改失败，管理员接入修改订单状态为购票成功");
					errorOrderMapper.insert(record);
				}
				return ReturnResult.ok();
			}
			// TODO 修改分销系统订单状态为已支付失败，记录异常日志
			ErrorOrder record = new ErrorOrder();
			record.setOrderId(order.getId());
			record.setOrderNo(order.getOrderNo());
			record.setTime(new Date());
			record.setDescription("修改分销系统订单状态为已支付失败");
			errorOrderMapper.insert(record);
			log.error("畅游通修改订单状态为已支付异常{}", JSON.toJSONString(applyOrderRefundResponse));
			return ReturnResult.build(500, "畅游通返回订单状态不正确");
		} catch (Exception e) {
			e.printStackTrace();
			log.error("畅游通修改订单状态为已支付异常order={}", JSON.toJSONString(order));
			return ReturnResult.build(500, "网络异常");
		}

	}

	@Override
	public ReturnResult deleteOTAorder(String cytOrderNo) {
		try {
			Request request = new Request();
			// 请求体
			// --------------------获取产品信息--------------------
			CancelOrderByOTARequestBody body = new CancelOrderByOTARequestBody();
			body.setOrdercodes(cytOrderNo);

			// 获取产品信息
			Response response = sendData(request, body, "cancelOrder");
			if (response == null) {
				log.error("分销系统返回null,cytOrderNo={}", cytOrderNo);
				return ReturnResult.build(500, "分销系统未返回数据");
			}
			JSONObject json = (JSONObject) JSONObject.toJSON(response);
			log.info("取消订单请求票务返回参数response={}", JSONObject.toJSONString(response));
			String code = json.getJSONObject("header").getString("code");
			if (StringUtils.isBlank(code) || !code.equals("1000")) {
				log.error("分销系统返回状态码不正确response={}", JSONObject.toJSONString(response));
				return ReturnResult.build(500, json.getJSONObject("header").getString("describe"));
			}
			EditOrderStatusByOTAResponseBody getProductByOTAResponseBody = (EditOrderStatusByOTAResponseBody) response
					.getBody();
			if (getProductByOTAResponseBody.getStatus() == 200) {
				return ReturnResult.ok();
			}
			log.error("分销系统返回数据格式不正确response={}", JSONObject.toJSONString(getProductByOTAResponseBody));
		} catch (Exception e) {
			e.printStackTrace();
			log.error("分销系统返回异常cytOrderNo={}", cytOrderNo);
		}
		log.error("分销系统返回异常cytOrderNo={}", cytOrderNo);
		return ReturnResult.build(500, "网络异常");
	}

	@Override
	public ReturnResult createOrder() {
		Request request = new Request();
		// ---------------------创建订单-----------------------
		CreateOrderRequestBody body = new CreateOrderRequestBody();
		CreateOrderRequestBody.OrderInfo orderInfo = new CreateOrderRequestBody.OrderInfo();
		CreateOrderRequestBody.OrderInfo.Product product = new CreateOrderRequestBody.OrderInfo.Product();
		// 产品信息
		product.setResourceId("25579");// 产品ID
		product.setProductName("22222222222222");// 票名
		/*
		 * SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		 * product.setVisitDate(format.format(new Date()));// 游览日期
		 */
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		product.setVisitDate("2019-04-25");
		product.setSellPrice("1");// 人价 单位：分

		// 取票人信息
		CreateOrderRequestBody.OrderInfo.ContactPerson contactPerson = new CreateOrderRequestBody.OrderInfo.ContactPerson();
		contactPerson.setName("yangya");
		contactPerson.setMobile("15922719534");
		contactPerson.setCredentialsType("ID_CARD");
		contactPerson.setCredentials("500221199701065331");
		// 游客信息，根据产品的实际情况处理
		// 产品bookPersonType为CONTACT_PERSON时，person节点赋空值即可
		// orderInfo.setVisitPerson(new
		// CreateOrderRequestBody.OrderInfo.VisitPerson());
		CreateOrderRequestBody.OrderInfo.VisitPerson visitPerson = new CreateOrderRequestBody.OrderInfo.VisitPerson();
		List<CreateOrderRequestBody.OrderInfo.VisitPerson.Person> visiList = visitPerson.getPerson();
		CreateOrderRequestBody.OrderInfo.VisitPerson.Person person = new CreateOrderRequestBody.OrderInfo.VisitPerson.Person();
		person.setName("yangya");
		person.setCredentialsType("ID_CARD");
		person.setCredentials("500221199701065331");
		visiList.add(person);
		orderInfo.setVisitPerson(visitPerson);
		// OTA订单ID
		orderInfo.setOrderId(UUID.randomUUID().toString());
		// 产品信息
		orderInfo.setProduct(product);
		// 取票人信息
		orderInfo.setContactPerson(contactPerson);
		// 订单数量
		orderInfo.setOrderQuantity("1");
		// 订单金额
		orderInfo.setOrderPrice("1");
		// 订单状态
		orderInfo.setOrderStatus("PREPAY_ORDER_INIT");
		orderInfo.setSubstockId("6");
		// o.setOrderStatus("CASHPAY_ORDER_INIT");
		body.setOrderInfo(orderInfo);
		log.info("下单请求票务参数body={}", JSONObject.toJSON(body));
		Response response = sendData(request, body, "createOrder");
		log.info("下单请求票务返回参数response={}", JSONObject.toJSON(response));
		if (response == null) {
			System.out.println(":response-> response is null");
			return ReturnResult.build(500, "网络异常，请稍后再试");
		}
		CreateOrderResponseBody createOrderResponse = (CreateOrderResponseBody) response.getBody();
		log.info("未支付订单提交返回数据data={}", JSON.toJSONString(createOrderResponse));
		if (createOrderResponse.getOrderInfo().getOrderStatus().equals("PREPAY_ORDER_NOT_PAYED")) {
			return ReturnResult.ok(createOrderResponse.getOrderInfo().getPartnerorderId());
		}
		return ReturnResult.build(500, "网络异常，稍后再试");
	}
	
	private ReturnResult errorRefund(Orders order){
		log.error("更新票务订单为已支付失败，order={}",JSONObject.toJSONString(order));
		DecimalFormat decimalFormat = new DecimalFormat("#");
		boolean b = WXPayUtil.refund(order.getOrderNo(), decimalFormat.format(order.getTotelPrice()),order.getOrderNo());
		if (b) {
			order.setStatus(Cons.ORDER_STATUS.REFUNDEDING);
			ordersMapper.updateByPrimaryKeySelective(order);
			return ReturnResult.build(500, "出票失败已自动退款");
		}
		log.error("微信支付成功异步回掉修改订单状态,分销系统返回null,自动退款，order={}", JSONObject.toJSONString(order));
		return ReturnResult.build(500, "畅游通未返回数据");
	}

}
