package cn.freemud.service.impl;

import cn.freemud.base.entity.BaseResponse;
import cn.freemud.base.util.DateUtil;
import cn.freemud.constant.RedisKeyConstant;
import cn.freemud.entities.db.OpenPlatformIappWxappConfig;
import cn.freemud.entities.dto.*;
import cn.freemud.entities.vo.ShoppingCartSkuAddRequestVo;
import cn.freemud.enums.BuriedPointEnum;
import cn.freemud.enums.GuessLikeStatus;
import cn.freemud.manager.OpenPlatformIappWxappConfigManager;
import cn.freemud.redis.RedisCache;
import cn.freemud.service.BuriedPointService;
import cn.freemud.service.UserService;
import cn.freemud.service.thirdparty.SyncTxProductClient;
import cn.freemud.utils.LogUtil;
import com.freemud.api.assortment.datamanager.entity.db.AssortmentOpenPlatformWxapp;
import com.freemud.api.assortment.datamanager.manager.AssortmentOpenPlatformWxappManager;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @version V1.0
 * @Title: BuriedPointServiceImpl
 * @Package cn.freemud.service.impl
 * @Description: 简单描述下这个类是做什么用的
 * @author: zhenghuan.yang
 * @date: 2018/9/27 20:24
 * @Copyright: 2018 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
@Slf4j
@Service
public class BuriedPointServiceImpl implements BuriedPointService {
    @Value("${saas.wx.service.provider.appid}")
    private String appId;
    @Value("${saas.wx.service.provider.mchid}")
    private String mchId;
    @Value("${saas.wx.service.provider.signkey}")
    private String signKey;
    @Autowired
    private SyncTxProductClient syncTxProductClient;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private AssortmentOpenPlatformWxappManager openPlatformWxappManager;
    @Autowired
    private OpenPlatformIappWxappConfigManager openPlatformIappWxappConfigManager;

    @Override
    public BaseResponse BuriedPointPayment(BuriedPointPaymentRequestDto requestDto, QueryOrdersResponseDto.DataBean.OrderBean orderBean) {
        try {
            if(getGustLikeStatus(requestDto.getWxAppId())){
                String sessionId = requestDto.getSessionId();
                String redisKey = "saas:user:info:sessionId:" + sessionId;
                Map<String, Object> map = redisCache.getValue(redisKey);
                AssortmentOpenPlatformWxapp wxapp = openPlatformWxappManager.findByWxappId(requestDto.getWxAppId());
                RequestAttributes ra = RequestContextHolder.getRequestAttributes();
                ServletRequestAttributes sra = (ServletRequestAttributes) ra;
                HttpServletRequest request = sra.getRequest();
                String realIp = request.getHeader("X-Forwarded-For");
                if (StringUtils.isEmpty(realIp)) {
                    realIp = request.getRemoteHost();
                } else {
                    // 经过多次代理, 最开始的是离服务器最远的ip
                    realIp = realIp.split(",")[0];
                }
                BuriedPointRequestDto dto = new BuriedPointRequestDto();
                dto.setVer("1");
                dto.setUnifyId(requestDto.getPartnerId());
                dto.setUStoreId(requestDto.getStoreId());
                dto.setAppType("saasOrder");
                dto.setSessionId(requestDto.getSessionId());
                dto.setOpenId(requestDto.getOpenId());
                dto.setIsNew("");
                dto.setWxGender("");
                dto.setCtime(DateUtil.convert2String(new Date(), DateUtil.FORMAT_YYYY_MM_DD_HHMMSS));
                dto.setTs(System.currentTimeMillis());
                dto.setEnv("1");//TODO 测试生产
                dto.setEvent("8");//支付
                List<EventResDto.ProductsVo> products = new ArrayList<EventResDto.ProductsVo>();
                EventResDto.ProductsVo productsVo = new EventResDto.ProductsVo();
                String actionStr = new Gson().toJson(products);
                dto.setEventRes(actionStr);
                dto.setOpt1("UPLOAD_TENCENT");
                OptRequestDto optRequestDto = new OptRequestDto();
                optRequestDto.setAppId(appId);
                optRequestDto.setMchId(mchId);
                optRequestDto.setSubAppId(requestDto.getWxAppId());
                optRequestDto.setSubMchId(wxapp.getMchId());//TODO
                optRequestDto.setSecret(signKey);
                optRequestDto.setAreaCode("");
                optRequestDto.setScene("MOBILE");
                optRequestDto.setStoreId(requestDto.getStoreId());
                optRequestDto.setStoreName("");
                optRequestDto.setActionSource("MINI_PROGRA");
                optRequestDto.setOpenId(requestDto.getOpenId());
                optRequestDto.setMobileNumHash("");
                optRequestDto.setSubOpenId(requestDto.getOpenId());
                ActionListDto actionListDto = new ActionListDto();
                List<ActionListDto.ActionList> actionList = new ArrayList<ActionListDto.ActionList>();
                String redisTxKey = RedisKeyConstant.SAAS_USER_INFO_CNXH + requestDto.getPartnerId() + "_" + requestDto.getStoreId() + "_" + map.get("memberId");
                Map<String, Object> txMap = redisCache.getValue(redisTxKey);
                String traceId=null;
                if (txMap != null) {
                    traceId=txMap.get("traceId") != null ? String.valueOf(txMap.get("traceId")) : "";
                }
                List<QueryOrdersResponseDto.DataBean.OrderBean.ProductBean> productList = orderBean.getProductList();
                for (int i = 0; i < productList.size(); i++) {
                    QueryOrdersResponseDto.DataBean.OrderBean.ProductBean productBean = productList.get(i);
                    if (StringUtils.isBlank(productBean.getParentProductId())) {
                        productsVo.setId(productBean.getProductId());
                        productsVo.setName(productBean.getProductName());
                        products.add(productsVo);
                        ActionListDto.ActionList action = new ActionListDto.ActionList();
                        action.setActionTime(Instant.now().getEpochSecond());
                        action.setActionType("PURCHASE");
                        if (StringUtils.isNotBlank(traceId)) {
                            action.setTraceId(traceId);
                        }
                        ActionListDto.ActionList.ActionParam actionParam = new ActionListDto.ActionList.ActionParam();
                        actionParam.setProductId(productBean.getProductId());
                        actionParam.setProductName(productBean.getProductName());
                        action.setActionParam(actionParam);
                        actionList.add(action);
                    }
                }
                actionListDto.setActionList(actionList);
                String actionListStr = new Gson().toJson(actionListDto);
                optRequestDto.setActionList(actionListStr);
                String strOptRequestDto = new Gson().toJson(optRequestDto);
                dto.setOpt2(strOptRequestDto);
                log.info("syncTxProductClient.BuriedPoint_BuriedPointPaymentbofore**" + dto);
                String str = syncTxProductClient.BuriedPoint(dto);
                LogUtil.info("syncTxProductClient.BuriedPoint_BuriedPointPayment after", dto, str);
            }
        } catch (Exception e) {
            log.info("支付之后埋点报错，让交易继续下去" + e);
        }
        return null;
    }

    /**
     * 查询猜你喜欢状态是否开启（数据行为上传开关控制）
     * @return
     */
    public Boolean getGustLikeStatus(String wxAppId) {
        OpenPlatformIappWxappConfig wxappConfig = openPlatformIappWxappConfigManager.selectIappWxappConfigByWxAppId(wxAppId);
        if (null != wxappConfig && GuessLikeStatus.OPEN.getCode().equals(wxappConfig.getGuessLikeStatus())) {
            return true;
        }
        return false;
    }
}
