package com.freemud.sdk.api.assortment.shoppingcart.service.impl;

import ch.qos.logback.classic.Level;
import cn.freemud.base.entity.BaseResponse;
import com.freemud.application.sdk.api.log.ErrorLog;
import com.freemud.sdk.api.assortment.shoppingcart.constant.CartResponseConstant;
import com.freemud.sdk.api.assortment.shoppingcart.constant.RedisKeyConstant;
import com.freemud.sdk.api.assortment.shoppingcart.constant.ShoppingCartConstant;
import com.freemud.sdk.api.assortment.shoppingcart.constant.VersionUtils;
import com.freemud.sdk.api.assortment.shoppingcart.domain.CartAddItem;
import com.freemud.sdk.api.assortment.shoppingcart.domain.CartGoods;
import com.freemud.sdk.api.assortment.shoppingcart.domain.CartParamDto;
import com.freemud.sdk.api.assortment.shoppingcart.service.ShoppingCartBaseService;
import com.freemud.sdk.api.assortment.shoppingcart.util.CartResponseUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @version V1.0
 * @Title: ShoppingCartBaseServiceImpl
 * @Package com.freemud.sdk.api.assortment.shoppingcart.service.impl
 * @Description:
 * @author: yuhao.chi
 * @date: 2019/4/10 15:30
 * @Copyright: 2019 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目的
 */
@Service("shoppingCartMallBaseService")
public class ShoppingCartMallBaseServiceImpl implements ShoppingCartBaseService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${coupon.app.id}")
    private String appId;

    @Override
    public BaseResponse<List<CartAddItem>> detailCart(CartParamDto cartParamDto, String trackingNo) {
        return null;
    }

    @Override
    public BaseResponse<List<CartGoods>> getCartGoodsList(CartParamDto cartParamDto, String trackingNo) {
        try {
            String redisKey = getShoppingCartGoodsKey(cartParamDto);
            BoundHashOperations<String, String, CartGoods> operations = redisTemplate.boundHashOps(redisKey);
            List<CartGoods> cartGoodsList = operations.values();
            //对创建时间进行排序
            cartGoodsList.sort(Comparator.comparingLong(CartGoods::getCreateTimeMili));
            return CartResponseUtil.success(cartGoodsList);
        } catch (Exception e) {
            ErrorLog.printErrorLog("assortment-shoppingcart-sdk", trackingNo, e.getMessage(), "getCartGoodsList", cartParamDto, e, Level.ERROR);
            return null;
        }
    }

    @Override
    public BaseResponse<List<CartGoods>> setCartGoodsList(CartParamDto cartParamDto, String trackingNo) {
        try {
            String redisKey = getShoppingCartGoodsKey(cartParamDto);
            BoundHashOperations<String, String, CartGoods> operations = redisTemplate.boundHashOps(redisKey);
            if(1 == cartParamDto.getBuyType() )
            this.clear(cartParamDto, trackingNo);
            Map<String, CartGoods> cartGoodsMap = cartParamDto.getCartGoodsList().parallelStream()
                    .filter(k -> StringUtils.isNotEmpty(k.getCartGoodsUid()))
                    .collect(Collectors.toMap(CartGoods::getCartGoodsUid, Function.identity(), (k1, k2) -> k1));
            operations.putAll(cartGoodsMap);
            return this.getCartGoodsList(cartParamDto, trackingNo);
        } catch (Exception e) {
            ErrorLog.printErrorLog("assortment-shoppingcart-sdk", trackingNo, e.getMessage(), "setCartGoodsList", cartParamDto, e, Level.ERROR);
            return null;
        }
    }

    @Override
    public BaseResponse<CartGoods> getCartGoods(CartParamDto cartParamDto, String trackingNo) {
        try {
            String redisKey = getShoppingCartGoodsKey(cartParamDto);
            BoundHashOperations<String, String, CartGoods> operations = redisTemplate.boundHashOps(redisKey);
            CartGoods cartGoods = operations.get(cartParamDto.getCartGoodsUid());
            return CartResponseUtil.success(cartGoods);
        } catch (Exception e) {
            ErrorLog.printErrorLog("assortment-shoppingcart-sdk", trackingNo, e.getMessage(), "getCartGoods", cartParamDto, e, Level.ERROR);
            return null;
        }
    }

    @Override
    public BaseResponse<List<CartGoods>> updateGoodsQty(CartParamDto cartParamDto, String trackingNo) {
        try {
            String redisKey = getShoppingCartGoodsKey(cartParamDto);
            BoundHashOperations<String, String, CartGoods> operations = redisTemplate.boundHashOps(redisKey);
            CartGoods cartGoods = operations.get(cartParamDto.getCartGoodsUid());
            if (cartGoods != null) {
                // 当数量为0时,移除
                if (Objects.equals(cartParamDto.getQty(), 0)) {
                    operations.delete(cartParamDto.getCartGoodsUid());
                } else {
                    cartGoods.setQty(cartParamDto.getQty());
                    operations.put(cartParamDto.getCartGoodsUid(), cartGoods);
                }
            }
            return this.getCartGoodsList(cartParamDto, trackingNo);
        } catch (Exception e) {
            ErrorLog.printErrorLog("assortment-shoppingcart-sdk", trackingNo, e.getMessage(), "updateGoodsQty", cartParamDto, e, Level.ERROR);
            return null;
        }
    }

    @Override
    public BaseResponse clear(CartParamDto cartParamDto, String trackingNo) {
        try {
            redisTemplate.delete(this.getShoppingCartGoodsKey(cartParamDto));
            redisTemplate.delete(this.getShoppingCartGoodsAmountKey(cartParamDto));
            return new BaseResponse(VersionUtils.VER_1, CartResponseConstant.SUCCESS.getCode(), CartResponseConstant.SUCCESS.getMessage());
        } catch (Exception e) {
            ErrorLog.printErrorLog("assortment-shoppingcart-sdk", trackingNo, e.getMessage(), "clear", cartParamDto, e, Level.ERROR);
            return null;
        }
    }

    @Override
    public String getCouponAppId() {
        return this.appId;
    }

    @Override
    public Map<String, Boolean> getCouponOrderWay(String partnerId, List<String> activityCodes, Integer orderTye, String trackingNo) {
        return null;
    }

    /**
     * 获取绑定微商城门店id 
     */
    public String getBindMallShopId(String appId, String trackingNo) {
        try {
            BoundValueOperations operations = redisTemplate.boundValueOps(this.getBindMallShopKey(appId));
            String mallShopId = (String) operations.get();
            return mallShopId;
        } catch (Exception e) {
            ErrorLog.printErrorLog("assortment-shoppingcart-sdk", trackingNo, e.getMessage(), "getBindMallShopId", appId, e, Level.ERROR);
            return null;
        }
    }

    /**
     * 获取记录购物车信息的key
     *
     * @return
     */
    private String getShoppingCartGoodsKey(CartParamDto cartParamDto) {
        if(cartParamDto.getBuyType() == ShoppingCartConstant.NOW_BUY_TYPE) {
            //立即购买key设置30分钟能自动过期
            String key = RedisKeyConstant.SAAS_MALL_SHOPPINGCART_KEY_PREFIX + cartParamDto.getPartnerId() + "_" + cartParamDto.getStoreId() + "_" + cartParamDto.getUserId()+"_" + "temp";
            redisTemplate.expire(key,30, TimeUnit.MINUTES);
            return key;
        }
        return RedisKeyConstant.SAAS_MALL_SHOPPINGCART_KEY_PREFIX + cartParamDto.getPartnerId() + "_" + cartParamDto.getStoreId() + "_" + cartParamDto.getUserId();
    }

    /**
     * 获取记录购物车价格的key
     *
     * @return
     */
    private String getShoppingCartGoodsAmountKey(CartParamDto cartParamDto) {
        return RedisKeyConstant.SAAS_MALL_SHOPPINGCART_AMOUNT_PREFIX + cartParamDto.getPartnerId() + "_" + cartParamDto.getStoreId() + "_" + cartParamDto.getUserId();
    }
    
    /**
     * 获取绑定的微商城门店
     */
    private String getBindMallShopKey(String appId) {
        return RedisKeyConstant.OPENSTORE_MICROMALL_BIND_STOREID_PREFIX + appId;
    }

}
