package cn.freemud.service.impl;

import cn.freemud.adapter.MessageNoticeAdapter;
import cn.freemud.adapter.OrderAdapter;
import cn.freemud.base.util.DateUtil;
import cn.freemud.constant.RedisKeyConstant;
import cn.freemud.entities.dto.ConfirmOrderDto;
import cn.freemud.entities.dto.ShoppingCartBaseResponse;
import cn.freemud.entities.dto.shoppingCart.NewShoppingCartClearDto;
import cn.freemud.entities.vo.PaysuccessNoticeMessage;
import cn.freemud.enums.OrderBeanType;
import cn.freemud.enums.PayStatus;
import cn.freemud.enums.RedisCacheEnum;
import cn.freemud.redis.RedisCache;
import cn.freemud.service.CouponActivityService;
import cn.freemud.service.thirdparty.ShoppingCartClient;
import cn.freemud.utils.DateTimeUtil;
import cn.freemud.utils.RedisUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.freemud.api.assortment.datamanager.entity.vo.AssortmentCustomerInfoVo;
import com.freemud.api.assortment.datamanager.manager.AssortmentOpenPlatformWxappManager;
import com.freemud.api.assortment.datamanager.meal.MealCacheManager;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.ordercenter.entities.v1.OrderBeanV1;
import com.freemud.application.sdk.api.ordercenter.enums.OrderClientType;
import com.freemud.application.sdk.api.ordercenter.request.OrderExtInfoDto;
import com.freemud.application.sdk.api.storecenter.request.ChangeTableOrderStateRequest;
import com.freemud.application.sdk.api.storecenter.service.StoreCenterService;
import com.freemud.application.sdk.api.structure.request.PushMessageNoticeDto;
import com.freemud.application.sdk.api.structure.service.MessageCenterClient;
import com.freemud.sdk.api.assortment.order.request.order.AssortmentGroupOrderAffirmRequest;
import com.freemud.sdk.api.assortment.order.request.order.ClearTableRequest;
import com.freemud.sdk.api.assortment.order.response.order.AssortmentAffirmGroupOrderResponse;
import com.freemud.sdk.api.assortment.order.service.OrderCenterSdkService;
import com.google.common.collect.Maps;
import org.apache.commons.lang.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @version V1.6.0
 * @Title: OrderCommonService
 * @Description: 订单业务处理公共业务逻辑处理
 * @author: qin.zhou
 * @date: 2019/9/514:33
 * @Copyright: ${DATE.YARE} www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
@Service
public class OrderCommonService {
    @Autowired
    private AssortmentOpenPlatformWxappManager openPlatformWxappManager;
    @Autowired
    private OrderAdapter orderAdapter;
    @Autowired
    private OrderCenterSdkService orderCenterSdkService;
    @Autowired
    private MealCacheManager mealCacheManager;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private StoreCenterService storeCenterService;
    @Autowired
    private ShoppingCartClient shoppingCartClient;
    @Autowired
    private MessageNoticeAdapter messageNoticeAdapter;
    @Autowired
    private MessageCenterClient messageNoticeClient;
    @Autowired
    private RedisService redisService;
    @Autowired
    private CouponActivityService couponActivityService;
    @Autowired
    private OrderServiceImpl orderService;

    private final Integer RESPONSE_SUCCESS_CODE = 100;


    /**
     * 支付后通知确认返回信息
     */
    public String sendPaySuccessNoticeMessage() {
        Map<String, Object> map = Maps.newTreeMap();
        map.put("code", 0);
        map.put("message", "success");
        return JSON.toJSONString(map);
    }

    /**
     * 支付后通知确认返回信息
     */
    public String newSendPaySuccessNoticeMessage() {
        Map<String, Object> map = Maps.newTreeMap();
        map.put("code", 100);
        map.put("message", "success");
        return JSON.toJSONString(map);
    }

    /**
     * 支付后通知失败返回信息
     */
    public String newSendPayFaileMessage() {
        Map<String, Object> map = Maps.newTreeMap();
        map.put("code", 102);
        map.put("message", "failed");
        return JSON.toJSONString(map);
    }

    /**
     * 修改桌号状态
     * @return
     */
    public com.freemud.application.sdk.api.base.BaseResponse changeTableNumberStatus(AssortmentCustomerInfoVo assortmentCustomerInfoVo, Integer tableNumberStatus){
        //调用门店服务锁定桌号
        ChangeTableOrderStateRequest tableOrderStateRequest = new ChangeTableOrderStateRequest();
        tableOrderStateRequest.setTableCode(assortmentCustomerInfoVo.getTableNumber());
        tableOrderStateRequest.setStoreCode(assortmentCustomerInfoVo.getStoreId());
        tableOrderStateRequest.setOrderState(tableNumberStatus);  //1开台  2清台
        tableOrderStateRequest.setPartnerId(assortmentCustomerInfoVo.getPartnerId());
        //tableOrderStateRequest.setUpdateUserId(assortmentCustomerInfoVo.getMemberId());
        tableOrderStateRequest.setUpdateUserId(assortmentCustomerInfoVo.getMemberId());
        tableOrderStateRequest.setRemark(tableNumberStatus == 1 ? "开台" : "清台");
        return storeCenterService.changeTableOrderState(tableOrderStateRequest,LogThreadLocal.getTrackingNo());
    }

    /**
     * 支付成功回调
     * @param message
     * @return
     */
    public String paySuccessCallback(PaysuccessNoticeMessage message, ConfirmOrderDto confirmOrderDto, Map<String, OrderBeanV1> orderBeans) {
        OrderBeanV1 orderBean = orderBeans.get(OrderBeanType.SAASORDER.getCode());
        OrderExtInfoDto extInfo = JSONObject.parseObject(orderBean.getExtInfo(), OrderExtInfoDto.class);
        if(PayStatus.HAVE_PAID.getCode().equals(orderBean.getPayStatus()) && ObjectUtils.equals(1,orderBean.getPayType())){
            //发起退款  本期不考虑  极端情况
        }
        //调用清台sdk
        ClearTableRequest clearTableRequest = new ClearTableRequest();
        clearTableRequest.setPartnerId(orderBean.getCompanyId());
        clearTableRequest.setStoreId(orderBean.getShopId());
        clearTableRequest.setTableNumber(orderBean.getBarCounter());
        clearTableRequest.setUserId(extInfo == null ? "" : extInfo.getPrePayUserId());
        clearTableRequest.setOpClearTableEnum(ClearTableRequest.OpClearTableEnum.noOperationOrder);
        clearTableRequest.setOperator(orderBean.getUserName());
        orderCenterSdkService.clearTableNumber(clearTableRequest);
        //调用清除购物车接口
        NewShoppingCartClearDto shoppingCartClearDto = new NewShoppingCartClearDto();
        shoppingCartClearDto.setPartnerId(orderBean.getCompanyId());
        shoppingCartClearDto.setShopId(orderBean.getShopId());
        shoppingCartClearDto.setTableNumber(orderBean.getBarCounter());
        shoppingCartClearDto.setOperationType(3);
        ShoppingCartBaseResponse cartBaseResponse = shoppingCartClient.clearShoppingCart(shoppingCartClearDto);
//        if(cartBaseResponse == null || ObjectUtils.notEqual(cartBaseResponse.getCode(),RESPONSE_SUCCESS_CODE)){
//            AppLogUtil.infoLog("支付成功回调通知清除购物车信息失败 request:{},response:{}",shoppingCartClearDto,cartBaseResponse);
//        }
        //调用围餐订单完成接口
        AssortmentGroupOrderAffirmRequest affirmRequest = new AssortmentGroupOrderAffirmRequest();
        affirmRequest.setOrderClient(OrderClientType.WAI_MEAL.getIndex());
        affirmRequest.setOrderCode(orderBean.getOid());
        affirmRequest.setCompanyId(orderBean.getCompanyId());
        affirmRequest.setPayRequestNo(message.getOut_trade_no());
        affirmRequest.setActualPayAmount(message.getTotal_fee().longValue());
        affirmRequest.setPayTime(DateTimeUtil.getCurrentDateTimeStr());
        if (extInfo != null) {
            extInfo.setPayDate(DateUtil.convert2String(new Date(), "yyyy-MM-dd HH:mm:ss"));
            extInfo.setPayTransId(message.getOut_trade_no());
            affirmRequest.setUserId(extInfo.getPrePayUserId());
            affirmRequest.setUserName(orderBean.getUserName());
            affirmRequest.setMobile(extInfo.getPhone());
            affirmRequest.setExtInfo(JSON.toJSONString(extInfo));
        }
        affirmRequest.setOperator(orderBean.getUserName());
        AssortmentAffirmGroupOrderResponse groupOrderResponse = orderCenterSdkService.affirmGroupOrder(affirmRequest);
        if(ObjectUtils.notEqual(RESPONSE_SUCCESS_CODE,groupOrderResponse.getErrcode())){
            return this.newSendPayFaileMessage();
        }

        //若该订单使用了优惠券，则移除卡包,移除失败也不退款
        couponActivityService.callbackNotify(orderBean);

        // 删除订单自增缓存
        redisCache.delete(RedisUtil.getPaymentTransIdSequenceKey(orderBean.getOid()));
        // 删除支付交易号订单关系缓存
        redisCache.delete(RedisUtil.getPaymentTransIdOrderKey(message.getTrans_id()));

        this.sendPosMessage(orderBean.getCompanyId(),orderBean.getShopId(),orderBean.getOid());
        //支付回掉成功标记
        redisCache.save(RedisKeyConstant.KGD_PAYMENT_CALLBACK_FMID + message.getOut_trade_no(), message.getOut_trade_no(), 10L, TimeUnit.MINUTES);
        //返回调用结果
        return this.newSendPaySuccessNoticeMessage();
    }

    /**
     * 发送pos端消息
     */
    public void sendPosMessage(String partnerId, String storeId,String orderId) {
        PushMessageNoticeDto pushMessageNoticeDto = messageNoticeAdapter.convent2PushMessageNoticeDto(1, partnerId, storeId,
                null, orderId, null, null);
        messageNoticeClient.createMessage(pushMessageNoticeDto,LogThreadLocal.getTrackingNo());
    }

    /**
     * 尝试获取Redis锁 prefix
     * @return
     */
    public String redisLockInfo(AssortmentCustomerInfoVo assortmentCustomerInfoVo,RedisCacheEnum redisCacheEnum){
        StringBuilder sb = new StringBuilder(redisCacheEnum.getCode())
                .append(assortmentCustomerInfoVo.getPartnerId())
                .append(":")
                .append(assortmentCustomerInfoVo.getStoreId())
                .append(":")
                .append(assortmentCustomerInfoVo.getTableNumber());
        return sb.toString();
    }

}
