package com.gxwebsoft.shop.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.common.core.exception.BusinessException;
import com.gxwebsoft.common.core.exception.enums.GlobalErrorCodeConstants;
import com.gxwebsoft.common.core.utils.LoginUserUtil;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.shop.dto.ShopGoodsProfitUpdateDto;
import com.gxwebsoft.shop.dto.ShopGoodsProfitUpdateItemDto;
import com.gxwebsoft.shop.entity.ShopDealerUser;
import com.gxwebsoft.shop.entity.ShopGoods;
import com.gxwebsoft.shop.entity.ShopGoodsProfit;
import com.gxwebsoft.shop.mapper.ShopDealerUserMapper;
import com.gxwebsoft.shop.mapper.ShopGoodsMapper;
import com.gxwebsoft.shop.mapper.ShopGoodsProfitMapper;
import com.gxwebsoft.shop.service.ShopGoodsProfitService;
import com.gxwebsoft.shop.vo.ShopGoodsProfitVO;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商品分润设定Service实现
 *
 * @author xm
 * @since 2026-05-20 14:33:00
 */
@Service
@AllArgsConstructor
public class ShopGoodsProfitServiceImpl extends ServiceImpl<ShopGoodsProfitMapper, ShopGoodsProfit> implements ShopGoodsProfitService {

    private ShopDealerUserMapper shopDealerUserMapper;

    private ShopGoodsMapper shopGoodsMapper;

    @Override
    public List<ShopGoodsProfitVO> getByGoodsId(Integer goodsId, Integer type) {
        List<ShopGoodsProfit> list = lambdaQuery().select(ShopGoodsProfit::getId, ShopGoodsProfit::getGoodsId, ShopGoodsProfit::getUserId, ShopGoodsProfit::getProfit,
                ShopGoodsProfit::getStatus).eq(ShopGoodsProfit::getGoodsId, goodsId).eq(ShopGoodsProfit::getType, type).list();

        if(CollectionUtils.isNotEmpty(list)){
            List<Integer> userIdList = list.stream().map(ShopGoodsProfit::getUserId).distinct().collect(Collectors.toList());

            List<ShopDealerUser> shopDealerUserList = shopDealerUserMapper.selectList(new LambdaQueryWrapper<ShopDealerUser>().in(ShopDealerUser::getUserId, userIdList));
            List<ShopGoodsProfitVO> shopGoodsProfitVOS = BeanUtil.copyToList(list, ShopGoodsProfitVO.class);
            for(ShopGoodsProfitVO shopGoodsProfitVO : shopGoodsProfitVOS){
                shopDealerUserList.stream().filter(shopDealerUser -> shopGoodsProfitVO.getUserId().equals(shopDealerUser.getUserId())).findFirst()
                        .ifPresent(shopDealerUser -> shopGoodsProfitVO.setUserName(shopDealerUser.getRealName()));
            }
            return shopGoodsProfitVOS;
        }
        return new ArrayList<>();
    }

    @Override
    public List<ShopGoodsProfitVO> getGoodsProfit(List<Integer> goodsIdList, Integer type) {
        List<ShopGoodsProfit> profitList = lambdaQuery().select(ShopGoodsProfit::getId, ShopGoodsProfit::getGoodsId, ShopGoodsProfit::getUserId, ShopGoodsProfit::getProfit,
                ShopGoodsProfit::getStatus).in(ShopGoodsProfit::getGoodsId, goodsIdList).eq(ShopGoodsProfit::getType, type).eq(ShopGoodsProfit::getStatus, 1).list();
        if(CollectionUtils.isNotEmpty(profitList)){
            return BeanUtil.copyToList(profitList, ShopGoodsProfitVO.class);
        }
        return new ArrayList<>();
    }

    @Override
    public Boolean updateByGoodsId(ShopGoodsProfitUpdateDto entity) {
        User loginUser = LoginUserUtil.getLoginUser();
        if(loginUser == null){
            throw new BusinessException(GlobalErrorCodeConstants.UNAUTHORIZED.getMsg());
        }

        List<ShopGoodsProfitUpdateItemDto> itemList = entity.getItemList();
        LocalDateTime now = LocalDateTime.now();
        if(CollectionUtils.isNotEmpty(itemList)){
            //1.先检查传入的分润总和是否超过100
            BigDecimal profitSum = itemList.stream().map(ShopGoodsProfitUpdateItemDto::getProfit).reduce(BigDecimal.ZERO, BigDecimal::add);
            if(profitSum.compareTo(BigDecimal.valueOf(100)) > 0){
                throw new BusinessException("股东分红比例总和不能超过100%");
            }

            //2.检查分润对象是否有重复
            Map<Integer, List<ShopGoodsProfitUpdateItemDto>> userMap = itemList.stream().collect(Collectors.groupingBy(ShopGoodsProfitUpdateItemDto::getUserId)).entrySet().stream()
                    .filter(entry -> entry.getValue().size() > 1).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
            if(!userMap.isEmpty()){
                String userIds = String.join(",", userMap.keySet().stream().map(String::valueOf).toList());

                throw new BusinessException("用户:【" + userIds + "】存在多条分红数据,请修改后重新提交!");
            }

            //3.查询商品原有分润数据并做超100%管控
            ShopGoods shopGoods = shopGoodsMapper.selectById(entity.getGoodsId());
            if(shopGoods == null){
                throw new BusinessException(GlobalErrorCodeConstants.NOT_FOUND.getMsg());
            }
            BigDecimal goodsOriginalProfit = shopGoods.getVerifyRate().add(shopGoods.getVerifyParentRate());
            if(shopGoods.getCommissionType() == 20){
                goodsOriginalProfit = goodsOriginalProfit.add(shopGoods.getFirstMoney()).add(shopGoods.getSecondMoney()).add(shopGoods.getFirstDividend())
                        .add(shopGoods.getSecondDividend()).add(shopGoods.getDeliveryMoney());
            }
            if(profitSum.add(goodsOriginalProfit).compareTo(BigDecimal.valueOf(100)) > 0){
                throw new BusinessException("股东分红比例与商品原有分销比例加总不能超过100！");
            }

            //4.查询有分润数据并删除
            removeByGoodsId(entity.getGoodsId(), entity.getType(), loginUser.getUserId(), now);

            //5.批量新增分润数据
            List<ShopGoodsProfit> shopGoodsProfits = BeanUtil.copyToList(itemList, ShopGoodsProfit.class);
            shopGoodsProfits.forEach(shopGoodsProfit -> {
                shopGoodsProfit.setType(entity.getType());
                shopGoodsProfit.setGoodsId(entity.getGoodsId());
                shopGoodsProfit.setTenantId(loginUser.getTenantId());
                shopGoodsProfit.setCreator(loginUser.getUserId());
                shopGoodsProfit.setCreateTime(now);
            });
            saveBatch(shopGoodsProfits);
        }else {
            removeByGoodsId(entity.getGoodsId(), entity.getType(), loginUser.getUserId(), now);
        }
        return Boolean.TRUE;
    }

    private void removeByGoodsId(Integer goodsId, Integer type, Integer userId, LocalDateTime date){
        LambdaUpdateWrapper<ShopGoodsProfit> updateWrapper = new LambdaUpdateWrapper<ShopGoodsProfit>().eq(ShopGoodsProfit::getGoodsId, goodsId).eq(ShopGoodsProfit::getType, type)
                .set(ShopGoodsProfit::getUpdater, userId).set(ShopGoodsProfit::getUpdateTime, date).set(ShopGoodsProfit::getDeleted, 1);
        update(updateWrapper);
    }

}
