package com.liquidnet.service.goblin.service.impl;

import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.CurrentUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.adam.dto.vo.AdamAddressesVo;
import com.liquidnet.service.adam.dto.vo.AdamEntersVo;
import com.liquidnet.service.adam.dto.vo.AdamRscPolymer01Vo;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.constant.GoblinStatusConst;
import com.liquidnet.service.goblin.dto.manage.GoblinOrderParam;
import com.liquidnet.service.goblin.dto.manage.GoblinOrderSkuParam;
import com.liquidnet.service.goblin.dto.manage.GoblinOrderSpuParam;
import com.liquidnet.service.goblin.dto.manage.vo.GoblinPayInnerResultVo;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsInfoVo;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsSkuInfoVo;
import com.liquidnet.service.goblin.entity.GoblinStoreOrder;
import com.liquidnet.service.goblin.service.IGoblinAppOrderService;
import com.liquidnet.service.goblin.service.IGoblinAppZhengzaiService;
import com.liquidnet.service.goblin.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

@Service
@Slf4j
public class GoblinAppOrderServiceImpl implements IGoblinAppOrderService {

    @Autowired
    GoblinRedisUtils redisUtils;
    @Autowired
    GoblinMongoUtils mongoUtils;
    @Autowired
    QueueUtils queueUtils;
    @Autowired
    GoblinOrderUtils orderUtils;

    @Override
    public ResponseDto<GoblinPayInnerResultVo> checkOrder(GoblinOrderParam param) {
        boolean isDownGeneral = false; //是否需要回滚库存
        List<AdamEntersVo> entersVoList = ObjectUtil.cloneArrayListObject();
        String uid = CurrentUtil.getCurrentUid();
        List<String> skuAndPreListAndNumber = CollectionUtil.arrayListString();
        try {
            String orderMasterCode = IDGenerator.storeMasterCode();//总订单id
            List<GoblinOrderSpuParam> goblinOrderSpuParamList = param.getGoblinOrderSpuParamList();//分订单
            //获取用户相关
            String addressId;
            if (param.getAddressIds() == null || param.getAddressIds().size() == 0) {
                addressId = "";
            } else {
                addressId = StringUtils.join(param.getAddressIds(), ",");
            }
            AdamRscPolymer01Vo userVo = orderUtils.adamAddressEnterMember(uid, null, addressId);
            AdamAddressesVo addressesVo;
            boolean isMember;
            if (userVo == null) {
                isMember = false;
                addressesVo = null;
            } else {
                addressesVo = userVo.getAddressesVo();
                switch (userVo.getMembership()) {
                    case 10:
                    case 11:
                        isMember = true;
                        break;
                    default:
                        isMember = false;
                        break;
                }
            }
            for (GoblinOrderSpuParam spuParam : goblinOrderSpuParamList) {
                String orderId = IDGenerator.nextSnowId();
                String orderCode = IDGenerator.storeCode(orderId);
                String spuId = spuParam.getSpuId();
                GoblinGoodsInfoVo goblinGoodsInfoVo = redisUtils.getGoodsInfoVo(spuId);
                if (goblinGoodsInfoVo == null) {
                    return null;//参数异常
                }
                if (!(goblinGoodsInfoVo.getStatus().equals("3") && goblinGoodsInfoVo.getShelvesStatus().equals("3"))) {
                    return null;//该spu不可购买
                }
                String storeId = goblinGoodsInfoVo.getStoreId();
                String platVoucherCode = spuParam.getPlatVoucherCode();
                String storeVoucherCode = spuParam.getStoreVoucherCode();
                for (GoblinOrderSkuParam skuParam : spuParam.getGoblinOrderSkuParamArrayList()) {
                    String skuId = skuParam.getSkuIds();
                    int number = skuParam.getNumber();
                    if (!goblinGoodsInfoVo.getSkuIdList().contains(skuId)) {
                        return null;//参数异常
                    }
                    GoblinGoodsSkuInfoVo skuVo = redisUtils.getGoodsSkuInfoVo(skuId);
                    if (!(skuVo.getStatus().equals("3") && skuVo.getShelvesStatus().equals("3"))) {
                        return null;//该sku不可购买
                    }
                    // 判断库存
                    String pre = GoblinStatusConst.MarketPreStatus.getPre(skuId);
                    int limitCount = skuVo.getBuyLimit() == 0 ? Integer.MAX_VALUE : skuVo.getBuyLimit();
                    int surplusGeneral = redisUtils.decrSkuStock(pre, skuId, number);
                    if (surplusGeneral < 0) {//库存回滚
                        redisUtils.incrSkuStock(pre, skuId, number);
                        return null;//售罄
                    } else {
                        skuAndPreListAndNumber.add(skuId + "," + pre + "," + number);
                        isDownGeneral = true;
                        //判断限购
                        String res1 = orderUtils.judgeOrderLimit(uid, skuId, number, limitCount);
                        if (!res1.equals("")) {
                            redisUtils.incrSkuStock(pre, skuId, number);
                            return ResponseDto.failure(res1);//乱七八糟异常
                        }
                        //下单
                        ResponseDto<GoblinPayInnerResultVo> resultData = order(param, skuVo, uid, isMember, addressesVo, orderMasterCode, orderId, orderCode, storeId, number, pre, spuParam.getPlatVoucherCode());
                        isDownGeneral = false;
                        return resultData;
                    }
                }//GoblinOrderSkuParam
            }//GoblinOrderSpuParam
            return null;//参数异常
        } catch (Exception e) {
            log.error("Kylin Order Pay Error = {}", e);
            if (isDownGeneral) {
                //回顾限购 回滚库存
                for (String item : skuAndPreListAndNumber) {
                    String[] array = item.split(",");
                    String skuId = array[0];
                    String pre = array[1];
                    int number = Integer.parseInt(array[2]);
                    redisUtils.incrSkuStock(pre, skuId, number);
                    redisUtils.decrSkuCountByUid(uid, skuId, number);
                }
                log.error("回滚库存");
            }
            if (e.getMessage() == null) {
                return ResponseDto.failure(ErrorMapping.get("20018"));//乱七八糟异常
            } else if (e.getMessage().equals("券不可用")) {
                return ResponseDto.failure(ErrorMapping.get("20030"));//券不可用
            } else {
                return ResponseDto.failure(ErrorMapping.get("20018"));//乱七八糟异常
            }
        }
    }

    private ResponseDto<GoblinPayInnerResultVo> order(GoblinOrderParam param, GoblinGoodsSkuInfoVo skuInfoVo, String uid, boolean isMember, AdamAddressesVo addressesVo, String orderMasterCode, String orderId, String orderCode, String storeId, int number, String pre, String platVoucherCode) throws Exception {
        LinkedList<String> sqls = CollectionUtil.linkedListString();
        Map token = CurrentUtil.getTokenClaims();
        String headerCliSource = CurrentUtil.getHeaderCliSource(), headerCliVersion = CurrentUtil.getHeaderCliVersion();
        String source = headerCliSource == null ? "" : headerCliSource;
        String version = headerCliVersion == null ? "" : headerCliVersion;
        LocalDateTime now = LocalDateTime.now();

        //价格判断
        BigDecimal price = skuInfoVo.getPrice();
        BigDecimal priceBase = skuInfoVo.getPrice();
        if (pre != null) {
            priceBase = redisUtils.getGoodsSkuInfoVo(skuInfoVo.getSkuId().split(pre)[0]).getPrice();
            if (isMember) {
                priceBase = skuInfoVo.getPriceMember();
            }
        }
        if (isMember) {
            price = skuInfoVo.getPriceMember();
        }
        BigDecimal voucherMarket = priceBase.subtract(price).multiply(BigDecimal.valueOf(number));
        BigDecimal voucherPrice = BigDecimal.ZERO;
        if (platVoucherCode != null && platVoucherCode != "") {
            HashMap<String, Object> hashMap = orderUtils.useCoupon(platVoucherCode, "购买商品spu", priceBase.multiply(BigDecimal.valueOf(number)), "");//todo
            voucherPrice = (BigDecimal) hashMap.get("voucher");
            Integer typeVoucher = (Integer) hashMap.get("type");
            if (typeVoucher.equals(-1)) {
                throw new Exception("券不可用");
            }
        }

        //生成订单
        GoblinStoreOrder storeOrder = GoblinStoreOrder.getNew();
        storeOrder.setMasterOrderCode(orderMasterCode);
        storeOrder.setOrderId(orderId);
        storeOrder.setStoreId(storeId);
        storeOrder.setOrderCode(orderCode);
        storeOrder.setUserId(uid);
        storeOrder.setUserName(StringUtils.defaultString(((String) token.get("nickname")), ""));
        storeOrder.setUserMobile(StringUtils.defaultString(((String) token.get("mobile")), ""));
        storeOrder.setPriceTotal(priceBase.multiply(BigDecimal.valueOf(number)));
        storeOrder.setPriceActual(storeOrder.getPriceTotal().subtract(voucherMarket).subtract(voucherPrice));
        storeOrder.setPriceRefund(BigDecimal.ZERO);
        storeOrder.setPreSalePrice(BigDecimal.ZERO);
        storeOrder.setPriceExpress(BigDecimal.ZERO);//todo 快递费
        storeOrder.setPriceModify(BigDecimal.ZERO);
        storeOrder.setPricePoint((BigDecimal.ZERO));
        storeOrder.setPriceCoupon(voucherPrice);
        storeOrder.setPriceRedEnvelope((BigDecimal.ZERO));
        storeOrder.setPriceVoucher(voucherMarket.add(voucherPrice));
        storeOrder.setStatus(0);
        storeOrder.setStatusPreSale(0);
        storeOrder.setStatusEvaluation(0);
        storeOrder.setRedEnvelopeCode("");
        storeOrder.setUcouponId(platVoucherCode);
        storeOrder.setUsePoint((BigDecimal.ZERO));
        storeOrder.setPayType(param.getPayType());
        storeOrder.setCancelReason("");
        storeOrder.setPreDepositPay(0);
        storeOrder.setSource(source);
        storeOrder.setVersion(version);
        storeOrder.setOrderType(0);
        storeOrder.setLotteryStatus("0");
        storeOrder.setWriteOffCode("");//todo
        storeOrder.setPayCountdownMinute(5);
        storeOrder.setIpAddress(CurrentUtil.getCliIpAddr());
        storeOrder.setCreatedAt(now);
//        storeOrder.setMailNo();
//        storeOrder.setDeliveryTime();
//        storeOrder.setLogisticsCompany();
//        storeOrder.setLogisticsCode();
//        storeOrder.setPayTime();
//        storeOrder.setCancelTime();
//        storeOrder.setModifyTime();
//        storeOrder.setEvaluationTime();
//        storeOrder.setPreSaleTime();
//        storeOrder.setRecommendedId();
//        storeOrder.setSRecommendedId();
//        storeOrder.setCrowdfundingId();
//        storeOrder.setPayCode();
//        storeOrder.setPayStoreId();
        return null;
    }
}
