package com.hzs.retail.wares.controller.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSONArray;
import com.hzs.common.core.constant.CountryConstants;
import com.hzs.common.core.domain.R;
import com.hzs.common.core.enums.EAccount;
import com.hzs.common.core.enums.ELabelType;
import com.hzs.common.core.enums.ESpecialArea;
import com.hzs.common.core.utils.ComputeUtil;
import com.hzs.common.core.utils.DistinctByKeyUtil;
import com.hzs.common.core.web.controller.BaseController;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.domain.member.ext.CuMemberExt;
import com.hzs.common.domain.sale.ext.BdWaresExt;
import com.hzs.common.domain.sale.ext.BdWaresSpecsSkuExt;
import com.hzs.common.domain.sale.wares.*;
import com.hzs.common.domain.system.config.BdLabel;
import com.hzs.common.domain.system.ext.BdLabelExt;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.member.base.IMemberServiceApi;
import com.hzs.member.base.dto.ShowWaresDTO;
import com.hzs.retail.wares.param.RetailWaresDetailParam;
import com.hzs.retail.wares.param.RetailWaresParam;
import com.hzs.retail.wares.vo.RetailWaresDetailVO;
import com.hzs.retail.wares.vo.RetailWaresVO;
import com.hzs.sale.wares.service.IBdWaresLabelService;
import com.hzs.sale.wares.service.IBdWaresRangeService;
import com.hzs.sale.wares.service.IBdWaresService;
import com.hzs.sale.wares.service.IBdWaresSpecsSkuService;
import com.hzs.system.base.ICurrencyServiceApi;
import com.hzs.system.base.dto.CurrencyDTO;
import com.hzs.system.config.IAreaCurrencyServiceApi;
import com.hzs.system.config.dto.AreaCurrencyDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 商品相关控制器
 */
@RestController
@RequestMapping("/api/retail-wares")
@Slf4j
public class ApiRetailWaresController extends BaseController {

    @Autowired
    private IBdWaresService iBdWaresService;
    @Autowired
    private IBdWaresLabelService iBdWaresLabelService;
    @Autowired
    private IBdWaresSpecsSkuService iBdWaresSpecsSkuService;
    @Autowired
    private IBdWaresRangeService iBdWaresRangeService;

    @DubboReference
    ICurrencyServiceApi currencyServiceApi;
    @DubboReference
    IAreaCurrencyServiceApi iAreaCurrencyServiceApi;
    @DubboReference
    IMemberServiceApi iMemberServiceApi;

    /**
     * 商品列表
     *
     * @param param 商品查询参数
     * @return
     */
    @PostMapping("/wares-list")
    public AjaxResult waresList(@Valid @RequestBody RetailWaresParam param) {
        // 会员信息
        CuMemberExt cuMemberExt = iMemberServiceApi.getMemberById(SecurityUtils.getUserId()).getData();

        // 返回商品列表
        List<RetailWaresVO> resultList = new ArrayList<>();

        param.setPkGrade(cuMemberExt.getPkSettleGrade());
        param.setPkAwards(cuMemberExt.getPkAwards());
        // 添加系统类型
        param.setSystemType(SecurityUtils.getSystemType());
        param.setPkCountry(SecurityUtils.getPkCountry());
        // 商品列表
        startPage();
        List<BdWaresExt> bdWaresExtList = iBdWaresService.listRetailWaresByCondition(param);

        if (CollectionUtil.isNotEmpty(bdWaresExtList)) {
            resultList = this.waresShowHandle(bdWaresExtList, param.getSpecialArea(), cuMemberExt.getPkSettleGrade(), true);
        }
        return AjaxResult.success(resultList);
    }


    /**
     * 商品详情
     *
     * @param param 商品详情查询参数
     * @return
     */
    @PostMapping("/wares-detail")
    public AjaxResult waresDetail(@Valid @RequestBody RetailWaresDetailParam param) {
        // 会员信息
        CuMemberExt cuMemberExt = iMemberServiceApi.getMemberById(SecurityUtils.getUserId()).getData();

        // 添加系统类型
        param.setSystemType(SecurityUtils.getSystemType());
        param.setPkCountry(SecurityUtils.getPkCountry());
        // 商品详情
        RetailWaresDetailVO waresDetailVO = iBdWaresSpecsSkuService.queryWaresDetail(param, cuMemberExt.getPkSettleGrade());

        // 预计发货时间（秒）
        if (waresDetailVO.getArrivalTime() != null && waresDetailVO.getCreationTime() != null) {
            long arrivalTime = waresDetailVO.getArrivalTime().getTime();
            long thisTime = System.currentTimeMillis();
            if (arrivalTime < thisTime) {
                waresDetailVO.setDeliveryTimeMs(0L);
            } else {
                waresDetailVO.setDeliveryTimeMs(DateUtil.betweenMs(waresDetailVO.getArrivalTime(), new Date()) / 1000);
            }
        }
        if (ESpecialArea.RETAIL_RESCISSION.getValue() == param.getSpecialArea()) {
            // 获取抵扣比例
            BigDecimal deductRatio = getSpecialDeductRatio(param.getSpecialArea(), EAccount.REPEAT.getValue());
            Set<Integer> pkCurrencySet = new HashSet<>();
            if (waresDetailVO.getPkSpecialCurrency() != null) {
                pkCurrencySet.add(waresDetailVO.getPkSpecialCurrency());
            }

            List<AreaCurrencyDTO> areaCurrencyDTOList = new ArrayList<>();
            if (pkCurrencySet.size() > 0) {
                areaCurrencyDTOList = iAreaCurrencyServiceApi.queryAreaCurrencyBySpecialArea(pkCurrencySet, EAccount.REPEAT.getValue());
            }

            waresDetailVO.setDeductMoney(ComputeUtil.computeBonusMultiply(waresDetailVO.getWaresPrice(), deductRatio));
            if (areaCurrencyDTOList.size() > 0) {
                for (AreaCurrencyDTO areaCurrencyDTO : areaCurrencyDTOList) {
                    if (areaCurrencyDTO.getPkSpecialCurrency().equals(waresDetailVO.getPkSpecialCurrency())
                            && areaCurrencyDTO.getFieldValue().equals(EAccount.REPEAT.getValue())
                            && areaCurrencyDTO.getDeductMaxRatio().compareTo(BigDecimal.ZERO) > 0) {
                        // 当前支付配置，重消币配置，最大比例不为0
                        waresDetailVO.setDeductMoney(ComputeUtil.computeBonusMultiply(waresDetailVO.getDeductMoney(), areaCurrencyDTO.getDeductMaxRatio()));
                    }
                }
            }

        }
        return AjaxResult.success(waresDetailVO);
    }


    /**
     * 商品显示处理
     *
     * @param bdWaresExtList 商品列表
     * @param specialArea    所属专区
     * @param pkGrade        会员结算等级
     * @param showLabel      是否显示标签
     * @return
     */
    private List<RetailWaresVO> waresShowHandle(List<BdWaresExt> bdWaresExtList, Integer specialArea,
                                                Integer pkGrade, boolean showLabel) {
        // 返回商品列表
        List<RetailWaresVO> resultList = new ArrayList<>();
        // 当前会员ID
        Long userId = SecurityUtils.getUserId();

        // 汇率比例
        R<CurrencyDTO> currency = currencyServiceApi.getCurrency(SecurityUtils.getPkCountry());
        BigDecimal inExchangeRate = currency.getData().getInExchangeRate();

        // 商品主键列表
        List<Integer> waresIdList = bdWaresExtList.stream().map(BdWares::getPkId).collect(Collectors.toList());
        // 查询默认规格
        List<BdWaresSpecsSkuExt> waresSpecsSkuList = iBdWaresSpecsSkuService.selectByWaresSpecsSku(waresIdList);

        // 商品sku 最小值 和 数量
        Map<Integer, List<BdWaresSpecsSkuExt>> waresSpecsSkuMap = waresSpecsSkuList.stream().collect(Collectors.groupingBy(BdWaresSpecsSkuExt::getPkWares));

        List<BdLabelExt> list = null;
        if (showLabel) {
            // 查询标签列表
            BdWaresLabel waresLabel = new BdWaresLabel();
            waresLabel.setPkIdList(waresIdList);
            list = iBdWaresLabelService.selectByList(waresLabel);
        }

        // 商品极差列表
        List<BdWaresRange> waresRangeList = new ArrayList<>();
        if (ESpecialArea.RETAIL_REPURCHASE.getValue() == specialArea
                || ESpecialArea.RETAIL_RESCISSION.getValue() == specialArea) {
            // 复购、复消需要处理级差
            if (waresIdList.size() > 0) {
                waresRangeList = iBdWaresRangeService.listRetailWaresRange(pkGrade, waresIdList);
            }
        }

        // 检验商品团队信息
        Map<Integer, List<BdWaresAuthority>> waresAuthorityMap = iBdWaresService.getWaresAuthority(waresIdList);
        List<ShowWaresDTO> showWaresList = bdWaresExtList.stream().map(tmpBdWares -> {
            ShowWaresDTO showWaresDTO = new ShowWaresDTO();
            showWaresDTO.setPkWares(tmpBdWares.getPkId());
            showWaresDTO.setLoginMember(userId);
            showWaresDTO.setWaresAuthorityList(waresAuthorityMap.get(tmpBdWares.getPkId()));
            return showWaresDTO;
        }).collect(Collectors.toList());
        R<Map<Integer, Boolean>> waresShowMapDto = iMemberServiceApi.checkIsShowWares(showWaresList);
        Map<Integer, Boolean> waresShowMap = waresShowMapDto.getData();


        for (BdWaresExt bdWaresExt : bdWaresExtList) {
            // 校验团队信息
            Boolean isShowWares = waresShowMap.get(bdWaresExt.getPkId());
            if (null == isShowWares || !isShowWares) {
                continue;
            }

            if (null != list) {
                // 商品标签处理
                // 保证标签
                List<BdLabel> ensureLabelList = new ArrayList<>();
                // 卖点标签
                List<BdLabel> sellingLabelList = new ArrayList<>();

                for (BdLabelExt bdLabel : list) {
                    if (ELabelType.PREFIX.getValue() == bdLabel.getLabelType() && bdLabel.getPkWares().equals(bdWaresExt.getPkId())) {
                        // 前缀标签
                        bdWaresExt.setPrefixLabelTarget(bdLabel);
                    }
                    if (ELabelType.COOL.getValue() == bdLabel.getLabelType() && bdLabel.getPkWares().equals(bdWaresExt.getPkId())) {
                        // 酷炫标签
                        bdWaresExt.setCoolLabelTarget(bdLabel);
                    }
                    if (ELabelType.ENSURE.getValue() == bdLabel.getLabelType() && bdLabel.getPkWares().equals(bdWaresExt.getPkId())) {
                        // 保证标签
                        ensureLabelList.add(bdLabel);
                    }
                    if (ELabelType.SELLING.getValue() == bdLabel.getLabelType() && bdLabel.getPkWares().equals(bdWaresExt.getPkId())) {
                        // 卖点标签
                        sellingLabelList.add(bdLabel);
                    }
                }
                // 保证标签
                bdWaresExt.setEnsureLabelList(ensureLabelList.stream().filter(DistinctByKeyUtil.distinctByKey(BdLabel::getPkId)).collect(Collectors.toList()));
                // 卖点标签
                bdWaresExt.setSellingLabelList(sellingLabelList.stream().filter(DistinctByKeyUtil.distinctByKey(BdLabel::getPkId)).collect(Collectors.toList()));
            }

            RetailWaresVO waresVO = BeanUtil.copyProperties(bdWaresExt, RetailWaresVO.class);
            // 价格
            BigDecimal waresPrice = BigDecimal.ZERO;
            // 业绩
            BigDecimal waresAchieve = BigDecimal.ZERO;
            // EV
            BigDecimal assAchieve = BigDecimal.ZERO;

            if (ESpecialArea.RETAIL_REPURCHASE.getValue() == specialArea
                    || ESpecialArea.RETAIL_RESCISSION.getValue() == specialArea) {
                // 复购、复消需要处理级差
                for (BdWaresRange waresRange : waresRangeList) {
                    if (bdWaresExt.getPkId().equals(waresRange.getPkWares())) {
                        waresPrice = waresPrice.add(waresRange.getPrice());
                        waresAchieve = waresAchieve.add(waresRange.getAchieve());
                        assAchieve = assAchieve.add(waresRange.getAssAchieve());
                    }
                }
            } else {
                // 计算商品的价格和业绩 sku价格最小值 * 商品数量
                List<BdWaresSpecsSkuExt> waresSpecsSku = waresSpecsSkuMap.get(bdWaresExt.getPkId());
                waresSpecsSku = waresSpecsSku.stream().peek(a -> a.setProductGift(a.getPkProduct() + "" + a.getIsGift())).collect(Collectors.toList());
                Map<String, List<BdWaresSpecsSkuExt>> col = waresSpecsSku.stream().collect(Collectors.groupingBy(BdWaresSpecsSkuExt::getProductGift));
                for (Map.Entry<String, List<BdWaresSpecsSkuExt>> integerListEntry : col.entrySet()) {
                    // 取得每一个商品价格最小值
                    Optional<BdWaresSpecsSkuExt> minBdWaresSpecsSkuExt = integerListEntry.getValue().stream().filter(Objects::nonNull).min(Comparator.comparing(BdWaresSpecsSkuExt::getPrice));
                    BdWaresSpecsSkuExt bdWaresSpecsSkuExt = minBdWaresSpecsSkuExt.get();
                    waresPrice = waresPrice.add(bdWaresSpecsSkuExt.getPrice().multiply(new BigDecimal(bdWaresSpecsSkuExt.getQuantity())));
                    waresAchieve = waresAchieve.add(bdWaresSpecsSkuExt.getAchieve().multiply(new BigDecimal(bdWaresSpecsSkuExt.getQuantity())));
                    assAchieve = assAchieve.add(bdWaresSpecsSkuExt.getAssAchieve().multiply(new BigDecimal(bdWaresSpecsSkuExt.getQuantity())));
                }
            }

            // 计算商品列表价格和业绩最小值
            waresVO.setWaresPrice(waresPrice);
            waresVO.setWaresAchieve(waresAchieve.multiply(inExchangeRate));
            waresVO.setAssAchieve(assAchieve.multiply(inExchangeRate));
            waresVO.setIsMakerGift(bdWaresExt.getIsMakerGift());

            // 查询默认规格
            JSONArray jsonArray = new JSONArray();
            List<BdWaresSpecsSkuExt> collect = waresSpecsSkuList.stream().filter(DistinctByKeyUtil.distinctByKey(BdWaresSpecsSku::getPkWaresDetail)).collect(Collectors.toList());
            for (BdWaresSpecsSkuExt bdWaresSpecsSku : collect) {
                if (bdWaresSpecsSku.getPkWares().equals(bdWaresExt.getPkId())) {
                    JSONObject js = new JSONObject();
                    js.put("pkProduct", bdWaresSpecsSku.getPkProduct());
                    js.put("pkSkuId", bdWaresSpecsSku.getPkId());
                    js.put("quantity", bdWaresSpecsSku.getQuantity());
                    jsonArray.add(js);
                }
            }
            waresVO.setProductGroup(jsonArray);
            resultList.add(waresVO);
        }

        if (ESpecialArea.RETAIL_RESCISSION.getValue() == specialArea) {
            // 获取抵扣比例
            BigDecimal deductRatio = getSpecialDeductRatio(specialArea, EAccount.REPEAT.getValue());
            Set<Integer> pkCurrencySet = new HashSet<>();
            // 商品是否配置了特殊消费配置
            for (RetailWaresVO retailWaresVO : resultList) {
                if (retailWaresVO.getPkSpecialCurrency() != null) {
                    pkCurrencySet.add(retailWaresVO.getPkSpecialCurrency());
                }
            }
            List<AreaCurrencyDTO> areaCurrencyDTOList = new ArrayList<>();
            if (pkCurrencySet.size() > 0) {
                areaCurrencyDTOList = iAreaCurrencyServiceApi.queryAreaCurrencyBySpecialArea(pkCurrencySet, EAccount.REPEAT.getValue());
            }

            for (RetailWaresVO retailWaresVO : resultList) {
                retailWaresVO.setDeductMoney(ComputeUtil.computeBonusMultiply(retailWaresVO.getWaresPrice(), deductRatio));
                if (areaCurrencyDTOList.size() > 0) {
                    for (AreaCurrencyDTO areaCurrencyDTO : areaCurrencyDTOList) {
                        if (areaCurrencyDTO.getPkSpecialCurrency().equals(retailWaresVO.getPkSpecialCurrency())
                                && areaCurrencyDTO.getFieldValue().equals(EAccount.REPEAT.getValue())
                                && areaCurrencyDTO.getDeductMaxRatio().compareTo(BigDecimal.ZERO) > 0) {
                            // 当前支付配置，重消币配置，最大比例不为0
                            retailWaresVO.setDeductMoney(ComputeUtil.computeBonusMultiply(retailWaresVO.getDeductMoney(), areaCurrencyDTO.getDeductMaxRatio()));
                        }
                    }
                }
            }
        }

        return resultList;
    }

    /**
     * 获取抵扣比例
     *
     * @param specialArea
     * @param accountValue
     * @return
     */
    private BigDecimal getSpecialDeductRatio(Integer specialArea, Integer accountValue) {
        // 查询专区所属币种
        List<AreaCurrencyDTO> areaCurrencyDTOList = iAreaCurrencyServiceApi.queryAreaCurrencyByCondition(specialArea, CountryConstants.CHINA_COUNTRY).getData();
        BigDecimal elseRatio = BigDecimal.ZERO;
        BigDecimal deductRatio = BigDecimal.ZERO;
        boolean flag = false;
        for (AreaCurrencyDTO areaCurrencyDTO : areaCurrencyDTOList) {
            if (accountValue.equals(areaCurrencyDTO.getFieldValue())) {
                deductRatio = ComputeUtil.computeAdd(deductRatio, areaCurrencyDTO.getDeductRatio());
                flag = true;
            } else {
                elseRatio = ComputeUtil.computeAdd(elseRatio, areaCurrencyDTO.getDeductRatio());
            }
        }
        if (flag) {
            if (ComputeUtil.compareValue(deductRatio)) {
                return deductRatio;
            } else {
                return ComputeUtil.computeSubtract(BigDecimal.valueOf(100), elseRatio);
            }
        } else {
            return BigDecimal.ZERO;
        }
    }


}
