
package com.tmerclub.cloud.discount.controller.app;

import cn.hutool.core.collection.CollectionUtil;
import com.tmerclub.cloud.api.discount.constant.DiscountRule;
import com.tmerclub.cloud.api.dto.EsPageDTO;
import com.tmerclub.cloud.api.feign.SearchSpuFeignClient;
import com.tmerclub.cloud.api.vo.EsPageVO;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.database.dto.PageDTO;
import com.tmerclub.cloud.common.database.vo.PageVO;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.product.dto.ProductSearchDTO;
import com.tmerclub.cloud.common.product.vo.search.ProductSearchVO;
import com.tmerclub.cloud.common.product.vo.search.SpuSearchVO;
import com.tmerclub.cloud.common.response.ResponseEnum;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.util.Arith;
import com.tmerclub.cloud.discount.constant.SuitableProdTypeEnum;
import com.tmerclub.cloud.discount.mapper.DiscountSpuMapper;
import com.tmerclub.cloud.discount.model.Discount;
import com.tmerclub.cloud.discount.model.DiscountSpu;
import com.tmerclub.cloud.discount.service.DiscountService;
import com.tmerclub.cloud.discount.vo.DiscountItemVO;
import com.tmerclub.cloud.discount.vo.DiscountVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 满减满折优惠
 *
 * @author tmerclub
 * @date 2020-12-10 13:43:38
 */
@RestController("appDiscountController")
@RequestMapping("/ua/discount")
@Tag(name = "满减满折优惠")
public class DiscountController {

    @Autowired
    private DiscountService discountService;

    @Autowired
    private DiscountSpuMapper discountSpuMapper;

    @DubboReference
    private SearchSpuFeignClient searchSpuFeignClient;

    @GetMapping("/list")
    @Operation(summary = "获取促销活动列表", description = "获取促销活动列表")
    public ServerResponseEntity<PageVO<DiscountVO>> getDiscountList(PageDTO page, Discount discount) {
        PageVO<DiscountVO> spuPage = discountService.getAppDiscountList(page);
        return ServerResponseEntity.success(spuPage);
    }

    @GetMapping("/info")
    @Operation(summary = "获取满减活动信息", description = "获取满减活动信息")
    @Parameter(name = "discountId", description = "活动ID", required = true)
    public ServerResponseEntity<DiscountVO> info(@RequestParam("discountId") Long discountId) {
        DiscountVO discount = discountService.discountInfo(discountId);
        if (Objects.isNull(discount)) {
            // 该活动不存在或者已结束
            return ServerResponseEntity.showFailMsg("该活动不存在或者已结束");
        }
        discount.setSpuIds(null);
        return ServerResponseEntity.success(discount);
    }

    @GetMapping("/getSpuPageByDiscountId")
    @Operation(summary = "获取促销活动商品分页", description = "通过活动id获取促销活动详情")
    @Parameter(name = "discountId", description = "活动ID", required = true)
    public ServerResponseEntity<EsPageVO<ProductSearchVO>> getSpuPageByDiscountId(EsPageDTO pageDTO, ProductSearchDTO productSearchDTO,
                                                                                  @RequestParam("discountId") Long discountId) {
        DiscountVO discount = discountService.getDiscountInfoById(discountId);
        if (!Objects.equals(discount.getStatus(), 1)) {
            return ServerResponseEntity.success(null);
        }
        if (Objects.equals(discount.getSuitableSpuType(), SuitableProdTypeEnum.ALL_SPU.value())) {
            productSearchDTO.setShopId(discount.getShopId());
        } else {
            productSearchDTO.setSpuIds(discount.getSpuIds());
        }
        productSearchDTO.setPageNum(pageDTO.getPageNum());
        productSearchDTO.setPageSize(pageDTO.getPageSize());
        ServerResponseEntity<EsPageVO<ProductSearchVO>> response = searchSpuFeignClient.search(productSearchDTO);
        if (Objects.nonNull(response) && !Objects.equals(response.getCode(), ResponseEnum.OK.value())) {
            throw new LuckException(response.getMsg());
        }
        List<SpuSearchVO> spuList = response.getData().getList().get(0).getSpus();
        if (CollectionUtil.isNotEmpty(spuList)) {

            // 最优惠的那个满减项
            DiscountItemVO discountItem = discount.getDiscountItemList().get(0);

            // 折扣百分比
            double discountProportion;

            // 打折
            if (Objects.equals(discount.getDiscountRule(), DiscountRule.P2D.value())) {
                discountProportion = Arith.sub(1, Arith.div(discountItem.getDiscount(), 1000));
            } else {
                discountProportion = Arith.div(discountItem.getDiscount(), discountItem.getNeedAmount());
            }
            for (SpuSearchVO spuSearchVO : spuList) {
                // 将要减去的价格
                Long subPrice = (long) Arith.div(Arith.mul(spuSearchVO.getPriceFee(), discountProportion), 1.0, 0);
                // 如果有活动价格上限
                if (discount.getMaxReduceAmount() != null && subPrice > discount.getMaxReduceAmount()) {
                    subPrice = discount.getMaxReduceAmount();
                }
                //价格最低只能为0.01
                long activityPrice = spuSearchVO.getPriceFee() - subPrice;
                if (activityPrice < 1L) {
                    activityPrice = 1L;
                }
                spuSearchVO.setActivityPrice(activityPrice);
            }
            if (Objects.equals(discount.getSuitableSpuType(), SuitableProdTypeEnum.ASSIGN_SPU.value()) && Objects.isNull(productSearchDTO.getSort())) {
                //根据满减商品id排序
                Map<Long, SpuSearchVO> searchMap = spuList.stream().collect(Collectors.toMap(SpuSearchVO::getSpuId, s -> s));
                List<DiscountSpu> discountSpuList = discountSpuMapper.getDiscountSpuByDiscountId(discountId);
                discountSpuList = discountSpuList.stream().sorted(Comparator.comparing(DiscountSpu::getDiscountSpuId)).collect(Collectors.toList());
                LinkedHashMap<Long, Long> discountSpuMap = new LinkedHashMap<>(Constant.INITIAL_CAPACITY);
                discountSpuList.forEach(s -> discountSpuMap.put(s.getDiscountSpuId(), s.getSpuId()));
                List<SpuSearchVO> spuVOList = new ArrayList<>(Constant.INITIAL_CAPACITY);
                for (Map.Entry<Long, Long> entry : discountSpuMap.entrySet()) {
                    if (searchMap.containsKey(entry.getValue())) {
                        spuVOList.add(searchMap.get(entry.getValue()));
                    }
                }
                spuList = spuVOList;
                response.getData().getList().get(0).setSpus(spuList);
            }
        }
        return ServerResponseEntity.success(response.getData());
    }
}
