package cn.freemud.demo.manager.coupon;

import cn.freemud.base.log.LogTreadLocal;
import cn.freemud.base.util.JsonUtil;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.demo.entities.bo.goods.ValidateShopProductRequestBO;
import cn.freemud.demo.entities.bo.coupon.CheckSpqBO;
import cn.freemud.demo.entities.bo.coupon.GetCheckSpqBo;
import cn.freemud.demo.entities.bo.coupon.GetCouponDetailBO;
import cn.freemud.demo.entities.bo.goods.GetProductBySkuIdResponseBO;
import cn.freemud.demo.entities.bo.goods.ValiadShopProductBO;
import cn.freemud.demo.entities.bo.product.GetProductBySkuIdBO;
import cn.freemud.demo.entities.bo.promotion.CouponDetailBO;
import cn.freemud.demo.entities.bo.store.GetStoreBO;
import cn.freemud.demo.manager.product.ProductManager;
import cn.freemud.demo.manager.store.StoreService;
import cn.freemud.entities.dto.GetAppKeyRequestDto;
import cn.freemud.entities.dto.GetAppKeyResponseDto;
import cn.freemud.entities.dto.GetCouponDetailResponseDto;
import cn.freemud.enums.CouponStatus;
import cn.freemud.enums.ResponseResult;
import cn.freemud.enums.StoreItemStatus;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.redis.RedisCache;
import cn.freemud.service.thirdparty.CardBinClient;
import cn.freemud.service.thirdparty.CouponOnlineClient;
import cn.freemud.utils.RedisUtil;
import com.freemud.application.sdk.api.productcenter.request.product.valid.ValidateShopProductType;
import com.freemud.application.sdk.api.util.SignUtil;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import ma.glasnost.orika.MapperFacade;
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.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service("KgdCouponService")
public class KgdCouponServiceImpl implements CouponService {

    @Autowired
    CouponOnlineClient couponOnlineClient;

    @Autowired
    @Qualifier("KgdStoreService")
    StoreService storeService;

    @Autowired
    CardBinClient cardBinClient;

    @Autowired
    private RedisCache redisCache;

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

    @Resource
    private MapperFacade mapperFacade;

    @Autowired
    private ProductManager productManager;

    @Override
    public CouponDetailBO getCouponDetail(GetCouponDetailBO getCouponDetailBO) {
        Map<String, String> map = new TreeMap<>();
        if (StringUtils.isBlank(getCouponDetailBO.getPartnerId()) || StringUtils.isBlank(getCouponDetailBO.getCouponCode())) {
            return null;
        }
        map.put(Finals.CODES, getCouponDetailBO.getCouponCode());
        map.put(Finals.PARTNER_ID, getCouponDetailBO.getPartnerId());
        map.put(Finals.MERCHANT_ID, getCouponDetailBO.getPartnerId());
        map.put(Finals.ACTION, "code.allDetails");
        // 券码接口新增参数：组织机构（多个用英文逗号分离）
        GetStoreBO getStoreBO = new GetStoreBO();
        getStoreBO.setPartnerId(getCouponDetailBO.getPartnerId());
        getStoreBO.setStoreCode(getCouponDetailBO.getStoreCode());

        List<String> orgIds = storeService.getOrgIds(getStoreBO);
        String channelIds = CollectionUtils.isNotEmpty(orgIds) ? Joiner.on(",").join(orgIds) : "";
        map.put(Finals.CHANNEL_ID_LIST, channelIds);
        String appSecret = getAppSecret(getCouponDetailBO.getPartnerId());
        String sign = SignUtil.createMD5Sign(map, appSecret);
        map.put(Finals.SIGN, sign);
        GetCouponDetailResponseDto responseDto = couponOnlineClient.getCouponDetails(map);
        if (ResponseCodeConstant.RESPONSE_SUCCESS_1.equals(responseDto.getResult())) {
            return convert2CouponDetailBO(responseDto);
        }
        return null;
    }

    @Override
    public CheckSpqBO checkSpq(GetCheckSpqBo getCheckSpqBo) {

        CheckSpqBO result = new CheckSpqBO();
        GetCouponDetailBO getCouponDetail = convert2GetCouponDetailBO(getCheckSpqBo);

        // 如果是商品券/换购券,获取券信息
        CouponDetailBO couponDetail = getCouponDetail(getCouponDetail);

        if (couponDetail == null || !couponDetail.getResult().equals(ResponseCodeConstant.RESPONSE_SUCCESS_1) || CollectionUtils.isEmpty(couponDetail.getDetails())) {
            return null;
        }
        Integer couponType = 0;
        CouponDetailBO.Details couponActivityDetail = null;
        // 多规格券
        if (StringUtils.isNotBlank(getCheckSpqBo.getSkuId())){
            for (CouponDetailBO.Details detail : couponDetail.getDetails()) {
                if (Objects.nonNull(couponActivityDetail)){
                    break;
                }
                if (!CouponStatus.STATUS_0.getCode().equals(detail.getStatus()) && !CouponStatus.STATUS_2.getCode().equals(detail.getStatus())){
                    continue;
                }
                for (CouponDetailBO.ActiveProduct activeProduct : detail.getActiveProduct()) {
                    if (getCheckSpqBo.getSkuId().equals(activeProduct.getProductIdPartner())) {
                        couponActivityDetail = detail;
                        // todo 和 CouponServiceImpl.checkSpqInfo不一致
                        couponType = detail.getType();
                        break;
                    }
                }
            }
        } else {
            // 单规格券
            if (Objects.equals(couponDetail.getDetails().get(0).getStatus(), CouponStatus.STATUS_0.getCode())) {
                couponActivityDetail = couponDetail.getDetails().get(0);
            }
        }
        if (Objects.isNull(couponActivityDetail)) {
            return null;
        }
        // 判断该券是否在这个门店下(一个券可以在多个门店下使用)
        List<String> couPonstoreIds = Lists.newArrayList();
        for (CouponDetailBO.Details detail : couponDetail.getDetails()) {
            if (!CouponStatus.STATUS_0.getCode().equals(detail.getStatus()) && !CouponStatus.STATUS_2.getCode().equals(detail.getStatus())){
                continue;
            }
            for (CouponDetailBO.ActiveRestrictionVOS activeRestrictionVO : detail.getActiveRestrictionVOS()) {
                couPonstoreIds.add(activeRestrictionVO.getStoreIdPartner());
            }
        }
        if (CollectionUtils.isNotEmpty(couPonstoreIds) && !couPonstoreIds.contains(getCheckSpqBo.getStoreId())) {
            return null;
        }
        // 券返回的商品id
        String skuId = getCheckSpqBo.getSkuId();
        if(StringUtils.isBlank(skuId)){
            skuId = couponActivityDetail.getActiveProduct().get(0).getProductIdPartner();
        }
        // 通过skuid查询spuid
        GetProductBySkuIdBO getProductBySkuIdBO = convert2GetProductBySkuIdBO(getCheckSpqBo,skuId);

        Map<String, GetProductBySkuIdResponseBO> productsInfoBySkuIds = productManager.getProductsInfoBySkuIds(getProductBySkuIdBO, getCheckSpqBo.getProductService());
        GetProductBySkuIdResponseBO productsVo = productsInfoBySkuIds.get(skuId);
        if (null == productsVo || !Objects.equals(productsVo.getStatus(), StoreItemStatus.PUT_ON_SALE.getCode())) {
            return null;
        }
        // 商品券商品时间校验
        ValidateShopProductRequestBO validateShopProductRequestBO = getValidateShopProductRequestBO(productsVo, getCheckSpqBo.getPartnerId(), getCheckSpqBo.getStoreId(), getCheckSpqBo.getMenuType());
        ValiadShopProductBO valiadShopProductBO = productManager.validateShopProduct(validateShopProductRequestBO, getCheckSpqBo.getProductService());
        if (valiadShopProductBO == null || CollectionUtils.isEmpty(valiadShopProductBO.getSuccessList()) ){
            throw new ServiceException(ResponseResult.SHOPPING_CART_COUPON_NOT_USE);
        }

        result.setType(couponType);
        result.setDetails(couponActivityDetail);
        result.setSkuId(productsVo.getSkuId());
        result.setSpuId(productsVo.getSpuId());
        result.setProductPrice(productsVo.getFinalPrice());

        result.setSpuName(productsVo.getSpuName());
        result.setExtra(productsVo.getExtra());
        result.setSpecProductId(productsVo.getDefaultSpecId());
        result.setSubName(productsVo.getDefaultSpecName());

        return result;

    }


    private ValidateShopProductRequestBO getValidateShopProductRequestBO(GetProductBySkuIdResponseBO product, String partnerId, String storeId, String menuType) {
        ValidateShopProductRequestBO request = new ValidateShopProductRequestBO();
        request.setChannel(menuType);
        request.setPartnerId(partnerId);
        request.setStoreId(storeId);
        List<ValidateShopProductType> productTypeList = new ArrayList<>();
        ValidateShopProductType productType = new ValidateShopProductType();

        productType.setAttributeList(null);
        productType.setComboProductTypeList(null);
        productType.setMemberDiscount(null);
        productType.setPrice(product.getFinalPrice().intValue());
        productType.setProductGroupTypeList(null);
        productType.setSkuId(product.getSkuId());
        productType.setSpuId(product.getSpuId());
        productType.setUuid(UUID.randomUUID().toString());
        productType.setValidateAttribute(0);
        productType.setValidatePrice(0);
        productType.setValidateStatuses(null);

        productTypeList.add(productType);
        request.setProductTypeList(productTypeList);
        return  request;

    }

    private CouponDetailBO convert2CouponDetailBO(GetCouponDetailResponseDto responseDto) {
        CouponDetailBO couponDetailBO = mapperFacade.map(responseDto, CouponDetailBO.class);
        return couponDetailBO;
    }

    public String getAppSecret(String partnerId) {
        // 获取券服务的密钥
        String couponAppSecret = RedisUtil.getCouponAppSecret(partnerId);
        String appSecret = redisCache.getValue(couponAppSecret);
        if (StringUtils.isBlank(appSecret)) {
            GetAppKeyResponseDto getAppKeyResponseDto = cardBinClient.getAppKey(GetAppKeyRequestDto.builder().partnerId(partnerId).appId(appid).build());
            if (Objects.equals(String.valueOf(getAppKeyResponseDto.getStatusCode()), ResponseResult.SUCCESS.getCode())
                    && getAppKeyResponseDto.getData() != null) {
                redisCache.save(couponAppSecret, getAppKeyResponseDto.getData().getAppKey());
                appSecret = getAppKeyResponseDto.getData().getAppKey();
            }
        }
        return appSecret;
    }



    private GetCouponDetailBO convert2GetCouponDetailBO(GetCheckSpqBo getCheckSpqBo) {
        GetCouponDetailBO getCouponDetailBO = new GetCouponDetailBO();
        getCouponDetailBO.setPartnerId(getCheckSpqBo.getPartnerId());
        getCouponDetailBO.setCouponCode(getCheckSpqBo.getCouponCode());
        getCouponDetailBO.setStoreCode(getCheckSpqBo.getStoreId());

        return getCouponDetailBO;
    }

    private GetProductBySkuIdBO convert2GetProductBySkuIdBO(GetCheckSpqBo getCheckSpqBo,String skuId) {
        GetProductBySkuIdBO getProductBySkuIdBO = new GetProductBySkuIdBO();
        getProductBySkuIdBO.setMenuType(getCheckSpqBo.getMenuType());
        getProductBySkuIdBO.setPartnerId(getCheckSpqBo.getPartnerId());
        getProductBySkuIdBO.setSkuids(Collections.singletonList(skuId));
        getProductBySkuIdBO.setStoreId(getCheckSpqBo.getStoreId());
        return getProductBySkuIdBO;
    }


}
