package com.sckw.product.dubbo;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sckw.core.utils.BeanUtils;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.web.response.HttpResult;
import com.sckw.product.api.dubbo.GoodsInfoService;
import com.sckw.product.api.model.AddressInfoDetail;
import com.sckw.product.api.model.GoodsDetail;
import com.sckw.product.api.model.GoodsDetails;
import com.sckw.product.api.model.KwpGoods;
import com.sckw.product.dao.KwpGoodsAddressMapper;
import com.sckw.product.model.KwpGoodsAddress;
import com.sckw.product.repository.KwpGoodsRepository;
import com.sckw.product.service.KwpGoodsService;
import com.sckw.redis.constant.RedisConstant;
import com.sckw.redis.utils.RedissonUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @desc: 商品信息dubbo接口
 * @author: yzc
 * @date: 2023-07-13 14:17
 */
@DubboService(group = "design", version = "1.0.0")
@Slf4j
@RequiredArgsConstructor
public class GoodsInfoServiceImpl implements GoodsInfoService {

    @Autowired
    private KwpGoodsService kwpGoodsService;
    private final KwpGoodsRepository kwpGoodsRepository;
    @Autowired
    private KwpGoodsAddressMapper kwpGoodsAddressMapper;

    @Override
    public GoodsDetails getDetail(Long id) {
        return kwpGoodsService.getDetails(id);
    }

    @Override
    public GoodsDetail getDetailById(Long id) {
        return BeanUtils.copyProperties(kwpGoodsService.detail(id), GoodsDetail.class);
    }

    @Override
    public KwpGoods getGoodsById(Long id) {
        return BeanUtils.copyProperties(kwpGoodsService.selectById(id), KwpGoods.class);
    }

    @Override
    public Map<Long, KwpGoods> getGoodsByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyMap();
        }
        List<KwpGoods> list = BeanUtils.copyToList(kwpGoodsService.selectByIds(ids), KwpGoods.class);
        if (CollectionUtils.isEmpty(list)) {
            return Collections.emptyMap();
        }
        return list.stream().collect(Collectors.toMap(KwpGoods::getId, e -> e, (k1, k2) -> k1));
    }

    @Override
    public HttpResult updateGoodsAmount(Long id, BigDecimal amount) {
        String lockKey = String.format(RedisConstant.GOODS_UPDATE_AMOUNT_KEY, id);
        if (Boolean.FALSE.equals(RedissonUtils.tryLock(lockKey, 10L, 30L))) {
            return HttpResult.error("业务繁忙，请稍后再试!");
        }
        try {
            com.sckw.product.model.KwpGoods goods = kwpGoodsService.getOnShelfGoodsById(id);
            if (Objects.isNull(goods)) {
                return HttpResult.error("商品不存在!");
            }
            BigDecimal goodsAmount = goods.getAmount();
            if (goods.getAmount().compareTo(amount) < 0) {
                return HttpResult.error("商品库存不足，请联系供应方!");
            }
            goods.setAmount(goodsAmount.subtract(amount))
                    .setPerformedAmount(Objects.nonNull(goods.getPerformedAmount()) ? goods.getPerformedAmount().add(amount) : amount);
            kwpGoodsService.updateById(goods);
        } finally {
            RedissonUtils.unlock(lockKey);
        }
        return HttpResult.ok();
    }

    @Override
    public Boolean associateManager(Long userId) {
        Long count = kwpGoodsService.getCountByManager(userId);
        return Objects.nonNull(count) && count > 0L;
    }

    @Override
    public Boolean associateSupplyEnt(Long entId) {
        Long count = kwpGoodsService.getCountBySupplyEnt(entId);
        return Objects.nonNull(count) && count > 0L;
    }

    @Override
    public KwpGoods getGoodsByGoodsName(String goodsName) {
        return kwpGoodsService.getGoodsByGoodsName(goodsName);
    }

    @Override
    public List<Long> getGoodsByGoodsNameAndTaxRate(String name, String goodsTaxRate) {
        List<Long> ids = kwpGoodsService.selectIdsTaxRateAndLikeGoodsName(name, goodsTaxRate);
        return CollUtil.emptyIfNull(ids);
    }

    @Override
    public List<Long> getGoodsByPara(String goodsName, List<String> goodsType, String goodsSpec) {
        List<Long> ids = kwpGoodsService.selectByPara(goodsName, goodsType, goodsSpec);
        return CollUtil.emptyIfNull(ids);
    }

    @Override
    public List<KwpGoods> getGoodsByNameTypeDesc(String goodsName, String goodsType, String goodsSpec) {
        List<com.sckw.product.model.KwpGoods> kwpGoods = kwpGoodsRepository.queryByGoodsNameAndTypeAndDesc(goodsName, goodsType, goodsSpec);
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(kwpGoods)){
            return Collections.emptyList();
        }
        return kwpGoods.stream()
                .map(GoodsInfoServiceImpl::getKwpGoods)
                .collect(Collectors.toList());
    }

    @Override
    public List<KwpGoods> findGoodsByGoodsName(String goodsName) {
        List<com.sckw.product.model.KwpGoods> kwpGoods = kwpGoodsRepository.queryByGoodsName(goodsName);
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(kwpGoods)){
            return Collections.emptyList();
        }

        return kwpGoods.stream()
                .map(GoodsInfoServiceImpl::getKwpGoods)
                .collect(Collectors.toList());
    }

    @Override
    public AddressInfoDetail getGoodsAddress(Long goodsId) {
        KwpGoodsAddress kwpGoodsAddress = kwpGoodsAddressMapper.selectOne(new LambdaQueryWrapper<KwpGoodsAddress>()
                .eq(KwpGoodsAddress::getGoodsId, goodsId).eq(KwpGoodsAddress::getDelFlag, 0).last("limit 1"));
        if (Objects.nonNull(kwpGoodsAddress)) {
            return BeanUtil.toBean(kwpGoodsAddress, AddressInfoDetail.class);
        }
        return null;
    }

    @NotNull
    private static KwpGoods getKwpGoods(com.sckw.product.model.KwpGoods g) {
        KwpGoods goods = new KwpGoods();
        goods.setEntId(g.getEntId());
        goods.setSupplyEntId(g.getSupplyEntId());
        goods.setCode(g.getCode());
        goods.setName(g.getName());
        goods.setGoodsType(g.getGoodsType());
        goods.setAreaCode(g.getAreaCode());
        goods.setAddressName(g.getAddressName());
        goods.setAmount(g.getAmount());
        goods.setUnit(g.getUnit());
        goods.setSpec(g.getSpec());
        goods.setTaxRate(g.getTaxRate());
        goods.setPrepaidLimit(g.getPrepaidLimit());
        goods.setAdvancePrice(g.getAdvancePrice());
        goods.setManager(g.getManager());
        goods.setPerformedAmount(g.getPerformedAmount());
        goods.setThumb(g.getThumb());
        goods.setAddedTime(g.getAddedTime());
        goods.setShelfTime(g.getShelfTime());
        goods.setId(g.getId());
        goods.setRemark(g.getRemark());
        goods.setStatus(g.getStatus());
        goods.setCreateBy(g.getCreateBy());
        goods.setCreateTime(g.getCreateTime());
        goods.setUpdateBy(g.getUpdateBy());
        goods.setUpdateTime(g.getUpdateTime());
        goods.setDelFlag(g.getDelFlag());
        return goods;
    }

    @Override
    public List<KwpGoods> queryGoodsByEntId(Long entId) {
        List<com.sckw.product.model.KwpGoods> kwpGoods = kwpGoodsRepository.queryGoodsByEntId(entId);
        if (CollectionUtils.isEmpty(kwpGoods)){
            return Collections.emptyList();
        }

        return kwpGoods.stream()
                .map(GoodsInfoServiceImpl::getKwpGoods)
                .collect(Collectors.toList());
    }
}
