package com.sckw.product.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sckw.core.common.enums.enums.DictEnum;
import com.sckw.core.common.enums.enums.DictTypeEnum;
import com.sckw.core.exception.BusinessException;
import com.sckw.core.model.constant.Global;
import com.sckw.core.model.page.PageResult;
import com.sckw.core.model.vo.TableBottom;
import com.sckw.core.model.vo.TableStatisticRes;
import com.sckw.core.model.vo.TableTop;
import com.sckw.core.utils.BeanUtils;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.utils.NumberUtils;
import com.sckw.core.utils.StringUtils;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.excel.utils.DateUtil;
import com.sckw.product.dao.KwpGoodsMapper;
import com.sckw.product.enums.GoodsStatusEnum;
import com.sckw.product.model.*;
import com.sckw.product.model.vo.req.*;
import com.sckw.product.model.vo.res.*;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.model.dto.res.EntCacheResDto;
import com.sckw.system.api.model.dto.res.SysDictResDto;
import com.sckw.system.api.model.dto.res.UserCacheResDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @desc: 商品service
 * @author: yzc
 * @date: 2023-06-25 14:47
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class KwpGoodsService {

    @DubboReference(version = "2.0.0", group = "design", check = false)
    private RemoteSystemService remoteSystemService;

    private final KwpGoodsMapper kwpGoodsMapper;
    private final KwpGoodsAddressService kwpGoodsAddressService;
    private final KwpGoodsAttributeService kwpGoodsAttributeService;
    private final KwpGoodsImageService kwpGoodsImageService;
    private final KwpGoodsPriceRangeService kwpGoodsPriceRangeService;


    /**
     * @desc: 添加草稿商品
     * @author: yzc
     * @date: 2023-07-03 9:30
     * @Param param:
     * @return: void
     */
    @Transactional(rollbackFor = Exception.class)
    public void addDraft(AddGoodsDraftParam param) {
        Long entId = LoginUserHolder.getEntId();
        //添加商品信息
        KwpGoods goods = BeanUtils.copyProperties(param, KwpGoods.class);
        if (Objects.nonNull(param.getAddressInfo())) {
            Integer cityCode = param.getAddressInfo().getCityCode();
            goods.setAreaCode(cityCode);
        }
        goods.setEntId(entId).setStatus(GoodsStatusEnum.SAVED.getCode());
        kwpGoodsMapper.insert(goods);
        AddGoodsParam addGoodsParam = BeanUtils.copyProperties(param, AddGoodsParam.class);
        addGoodsOtherInfo(goods.getId(), addGoodsParam);
    }

    /**
     * @desc: 添加上架商品
     * @author: yzc
     * @date: 2023-07-03 9:30
     * @Param addGoodsParam:
     * @return: void
     */
    @Transactional(rollbackFor = Exception.class)
    public void addShelves(AddGoodsParam addGoodsParam) {
        if (addGoodsParam.getTrading().startsWith("0") && Objects.isNull(addGoodsParam.getAdvancePrice())) {
            throw new BusinessException("交易方式为预付款时，预付款最低限额不能为空！");
        }
        Long entId = LoginUserHolder.getEntId();
        //添加商品信息
        KwpGoods goods = BeanUtils.copyProperties(addGoodsParam, KwpGoods.class);
        Integer cityCode = addGoodsParam.getAddressInfo().getCityCode();
        goods.setCode(NumberUtils.createRandomVcode()).setAreaCode(cityCode).setEntId(entId)
                .setAddedTime(new Date()).setStatus(GoodsStatusEnum.PUT_ON_SHELVES.getCode());
        kwpGoodsMapper.insert(goods);
        addGoodsOtherInfo(goods.getId(), addGoodsParam);
    }

    /**
     * @desc: 添加商品其他信息
     * @author: yzc
     * @date: 2023-07-05 11:45
     * @Param goodsId:
     * @Param addGoodsParam:
     * @return: void
     */
    private void addGoodsOtherInfo(Long goodsId, AddGoodsParam addGoodsParam) {
        //添加商品地址信息
        KwpGoodsAddress address = BeanUtils.copyProperties(addGoodsParam.getAddressInfo(), KwpGoodsAddress.class);
        if (Objects.nonNull(address)) {
            address.setGoodsId(goodsId);
            kwpGoodsAddressService.insert(address);
        }
        //添加商品属性信息
        List<GoodsAttributes> attributes = addGoodsParam.getAttributes();
        if (CollectionUtils.isNotEmpty(attributes)) {
            List<KwpGoodsAttribute> list = new ArrayList<>(attributes.size());
            attributes.forEach(e -> {
                KwpGoodsAttribute attribute = BeanUtils.copyProperties(e, KwpGoodsAttribute.class);
                attribute.setGoodsId(goodsId);
                list.add(attribute);
            });
            kwpGoodsAttributeService.insertBatch(list);
        }
        //添加商品图片信息
        List<GoodsImages> images = addGoodsParam.getImages();
        if (CollectionUtils.isNotEmpty(images)) {
            List<KwpGoodsImage> list = new ArrayList<>(images.size());
            images.forEach(e -> {
                KwpGoodsImage image = BeanUtils.copyProperties(e, KwpGoodsImage.class);
                image.setGoodsId(goodsId);
                list.add(image);
            });
            kwpGoodsImageService.insertBatch(list);
        }
        //添加商品价格梯度信息
        List<GoodsPriceRanges> priceRanges = addGoodsParam.getPriceRanges();
        if (CollectionUtils.isNotEmpty(priceRanges)) {
            List<KwpGoodsPriceRange> list = new ArrayList<>(priceRanges.size());
            priceRanges.forEach(e -> {
                KwpGoodsPriceRange priceRange = BeanUtils.copyProperties(e, KwpGoodsPriceRange.class);
                priceRange.setGoodsId(goodsId);
                list.add(priceRange);
            });
            kwpGoodsPriceRangeService.insertBatch(list);
        }
    }

    /**
     * @desc: 获取商品详情
     * @author: yzc
     * @date: 2023-07-05 11:57
     * @Param id:
     * @return: com.sckw.product.model.vo.res.GoodsDetail
     */
    public GoodsDetail detail(Long id, Boolean isDubbo) {
        KwpGoods goods;
        if (isDubbo) {
            goods = kwpGoodsMapper.selectById(id);
            if (Objects.isNull(goods)) {
                return null;
            }
        } else {
            goods = getGoodsById(id);
            if (Objects.isNull(goods)) {
                throw new BusinessException("当前商品信息为空！");
            }
        }
        GoodsDetail detail = BeanUtils.copyProperties(goods, GoodsDetail.class);
        List<EntCacheResDto> entCacheList = remoteSystemService.queryEntCacheByIds(Arrays.asList(detail.getEntId(), detail.getSupplyEntId()));
        Map<Long, String> entMap = entCacheList.stream().collect(Collectors.toMap(EntCacheResDto::getId, EntCacheResDto::getFirmName, (k1, k2) -> k1));
        detail.setEnt(entMap.get(detail.getEntId())).setSupplyEnt(entMap.get(detail.getSupplyEntId()));
        UserCacheResDto managerInfo = remoteSystemService.queryUserCacheById(detail.getManager());
        if (Objects.nonNull(managerInfo)) {
            detail.setManagerName(managerInfo.getName()).setManagerPhone(managerInfo.getPhone());
        }
        detail.setGoodsTypeLabel(DictEnum.getLabel(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), detail.getGoodsType()))
                .setTradingLabel(DictEnum.getLabel(DictTypeEnum.TRADE_TYPE.getType(), detail.getTrading()))
                .setUnitLabel(DictEnum.getLabel(DictTypeEnum.UNIT_TYPE.getType(), detail.getUnit()))
                .setTaxRateLabel(DictEnum.getLabel(DictTypeEnum.TAX_RATE.getType(), detail.getTaxRate()))
                .setStatusLabel(DictEnum.getLabel(DictTypeEnum.GOODS_STATUS.getType(), String.valueOf(detail.getStatus())));
        //商品图片信息
        List<KwpGoodsImage> goodsImages = kwpGoodsImageService.getByGoodsId(id);
        List<GoodsImagesDetail> images = BeanUtils.copyToList(goodsImages, GoodsImagesDetail.class);
        //商品价格段信息
        List<KwpGoodsPriceRange> priceRanges = kwpGoodsPriceRangeService.getByGoodsId(id);
        List<GoodsPriceRangesDetail> ranges = BeanUtils.copyToList(priceRanges, GoodsPriceRangesDetail.class);
        //商品属性信息
        List<KwpGoodsAttribute> attributesList = kwpGoodsAttributeService.getByGoodsId(id);
        List<GoodsAttributesDetail> attributes = BeanUtils.copyToList(attributesList, GoodsAttributesDetail.class);
        //商品地址信息
        KwpGoodsAddress goodsAddress = kwpGoodsAddressService.getByGoodsId(id);
        AddressInfoDetail addressInfo = BeanUtils.copyProperties(goodsAddress, AddressInfoDetail.class);
        if (Objects.nonNull(addressInfo)) {
            addressInfo.setTypeName(DictEnum.getLabel(DictTypeEnum.ADDRESS_TYPE.getType(), addressInfo.getType()));
        }
        detail.setImages(images).setPriceRanges(ranges).setAttributes(attributes).setAddressInfo(addressInfo);

        return detail;
    }


    /**
     * @desc: 更新商品信息
     * @author: yzc
     * @date: 2023-07-06 8:50
     * @Param param:
     * @return: void
     */
    @Transactional(rollbackFor = Exception.class)
    public void update(UpdateGoodsParam param) {
        KwpGoods goods = getGoodsById(param.getId());
        if (Objects.isNull(goods)) {
            throw new BusinessException("当前商品不存在！");
        }
        if (Objects.equals(goods.getStatus(), GoodsStatusEnum.PUT_ON_SHELVES.getCode())
                || Objects.equals(goods.getStatus(), GoodsStatusEnum.TAKE_OFF_SHELVES.getCode())) {
            judgeParameters(param);
        }
        BeanUtils.copyProperties(param, goods);
        if (Objects.nonNull(param.getAddressInfo())) {
            Integer cityCode = param.getAddressInfo().getCityCode();
            goods.setAreaCode(cityCode);
        }
        kwpGoodsMapper.updateById(goods);
        updateGoodsOtherInfo(param);
    }

    /**
     * @desc: 更新商品其他信息
     * @author: yzc
     * @date: 2023-07-06 14:53
     * @Param param:
     * @return: void
     */
    private void updateGoodsOtherInfo(UpdateGoodsParam param) {
        Long goodsId = param.getId();
        //更新商品地址信息
        kwpGoodsAddressService.delByGoodsIds(Collections.singletonList(goodsId));
        if (Objects.nonNull(param.getAddressInfo())) {
            KwpGoodsAddress address = BeanUtils.copyProperties(param.getAddressInfo(), KwpGoodsAddress.class);
            address.setGoodsId(goodsId);
            kwpGoodsAddressService.insert(address);
        }

        //更新商品属性信息
        kwpGoodsAttributeService.delByGoodsIds(Collections.singletonList(goodsId));
        if (CollectionUtils.isNotEmpty(param.getAttributes())) {
            List<KwpGoodsAttribute> list = new ArrayList<>(param.getAttributes().size());
            param.getAttributes().forEach(e -> {
                KwpGoodsAttribute attribute = BeanUtils.copyProperties(e, KwpGoodsAttribute.class);
                attribute.setGoodsId(goodsId);
                list.add(attribute);
            });
            kwpGoodsAttributeService.insertBatch(list);
        }

        //更新商品图片信息
        kwpGoodsImageService.delByGoodsIds(Collections.singletonList(goodsId));
        if (CollectionUtils.isNotEmpty(param.getImages())) {
            List<KwpGoodsImage> list = new ArrayList<>(param.getImages().size());
            param.getImages().forEach(e -> {
                KwpGoodsImage image = BeanUtils.copyProperties(e, KwpGoodsImage.class);
                image.setGoodsId(goodsId);
                list.add(image);
            });
            kwpGoodsImageService.insertBatch(list);
        }

        //更新商品价格梯度信息
        kwpGoodsPriceRangeService.delByGoodsIds(Collections.singletonList(goodsId));
        if (CollectionUtils.isNotEmpty(param.getPriceRanges())) {
            List<KwpGoodsPriceRange> list = new ArrayList<>(param.getPriceRanges().size());
            param.getPriceRanges().forEach(e -> {
                KwpGoodsPriceRange priceRange = BeanUtils.copyProperties(e, KwpGoodsPriceRange.class);
                priceRange.setGoodsId(goodsId);
                list.add(priceRange);
            });
            kwpGoodsPriceRangeService.insertBatch(list);
        }
    }

    /**
     * @desc: 参数校验
     * @author: yzc
     * @date: 2023-07-06 14:33
     * @Param param:
     * @return: void
     */
    private void judgeParameters(UpdateGoodsParam param) {
        if (StringUtils.isBlank(param.getName())) {
            throw new BusinessException("商品名称不能为空！");
        }
        if (StringUtils.isBlank(param.getGoodsType())) {
            throw new BusinessException("商品类型不能为空！");
        }
        if (StringUtils.isBlank(param.getUnit())) {
            throw new BusinessException("计量单位不能为空！");
        }
        if (StringUtils.isBlank(param.getSpec())) {
            throw new BusinessException("规格尺寸不能为空！");
        }
        if (Objects.isNull(param.getAmount())) {
            throw new BusinessException("库存数量不能为空！");
        }
        if (StringUtils.isBlank(param.getTaxRate())) {
            throw new BusinessException("发票税率不能为空！");
        }
        if (StringUtils.isBlank(param.getTrading())) {
            throw new BusinessException("交易方式不能为空！");
        }
        if (param.getTrading().startsWith("0") && Objects.isNull(param.getAdvancePrice())) {
            throw new BusinessException("交易方式为预付款时，预付款最低限额不能为空！");
        }

        List<GoodsAttributes> attributes = param.getAttributes();
        if (CollectionUtils.isNotEmpty(attributes)) {
            attributes.forEach(e -> {
                if (StringUtils.isBlank(e.getName()) || StringUtils.isBlank(e.getVal())) {
                    throw new BusinessException("参数名称或参数值不能为空且！");
                }
            });
        }
        List<GoodsImages> images = param.getImages();
        if (CollectionUtils.isNotEmpty(images)) {
            images.forEach(e -> {
                if (StringUtils.isBlank(e.getImage())) {
                    throw new BusinessException("商品图片地址不能为空！");
                }
                if (Objects.isNull(e.getSort())) {
                    throw new BusinessException("商品图片排序不能为空！");
                }
            });
        }
        List<GoodsPriceRanges> priceRanges = param.getPriceRanges();
        if (CollectionUtils.isEmpty(priceRanges)) {
            throw new BusinessException("价格梯度不能为空！");
        }
        priceRanges.forEach(e -> {
            if (Objects.isNull(e.getStartAmount()) || e.getStartAmount().compareTo(BigDecimal.ZERO) < 0) {
                throw new BusinessException("起售量最小为零！");
            }
            if (Objects.isNull(e.getEndAmount()) || e.getEndAmount().compareTo(new BigDecimal("-1.00")) < 0) {
                throw new BusinessException("上限售量最小为零！");
            }
            if (Objects.isNull(e.getPrice()) || e.getStartAmount().compareTo(BigDecimal.ZERO) < 0) {
                throw new BusinessException("含税价最低为零！");
            }
            if (Objects.isNull(e.getSort())) {
                throw new BusinessException("梯度顺序不能为空！");
            }
        });
        AddressInfo address = param.getAddressInfo();
        if (Objects.isNull(address)) {
            throw new BusinessException("地址信息不能为空！");
        }
        if (StringUtils.isBlank(address.getName()) || address.getName().length() > 50) {
            throw new BusinessException("地址名称不能为空且最长50字符！");
        }
        if (StringUtils.isBlank(address.getType())) {
            throw new BusinessException("地址类型不能为空！");
        }
        if (StringUtils.isBlank(address.getContacts())) {
            throw new BusinessException("联系人不能为空！");
        }
        if (StringUtils.isBlank(address.getPhone())) {
            throw new BusinessException("联系电话不能为空！");
        }
        if (Objects.isNull(address.getCityCode())) {
            throw new BusinessException("所在地区code不能为空！");
        }
        if (StringUtils.isBlank(address.getCityName()) || address.getCityName().length() > 40) {
            throw new BusinessException("所属区域名称不能为空最长40字符！");
        }
        if (Objects.isNull(address.getLat())) {
            throw new BusinessException("纬度不能为空！");
        }
        if (Objects.isNull(address.getLng())) {
            throw new BusinessException("经度不能为空！");
        }
        if (Objects.isNull(param.getSupplyEntId())) {
            throw new BusinessException("供应企业不能为空！");
        }
        if (Objects.isNull(param.getManager())) {
            throw new BusinessException("客户经理不能为空！");
        }
    }

    /**
     * @desc: 分页查询商品信息
     * @author: yzc
     * @date: 2023-07-05 11:58
     * @Param params:
     * @return: java.util.List<com.sckw.product.model.vo.res.GoodsList>
     */
    public PageResult select(SelectGoodsListParam params, Boolean isPage) {
        IPage<KwpGoods> goodsIpage = getGoodsLists(params, isPage);
        List<KwpGoods> goodsLists = goodsIpage.getRecords();
        if (CollectionUtils.isEmpty(goodsLists)) {
            return PageResult.build(params.getPage(), params.getPageSize(), goodsIpage.getTotal(), Collections.emptyList());
        }
        List<GoodsList> result = new ArrayList<>(goodsLists.size());
        List<Long> goodsIds = new ArrayList<>(goodsLists.size());
        List<Long> supplyEntIds = new ArrayList<>(goodsLists.size());
        List<Long> userIds = new ArrayList<>();
        goodsLists.forEach(e -> {
            goodsIds.add(e.getId());
            if (Objects.nonNull(e.getSupplyEntId())) {
                supplyEntIds.add(e.getSupplyEntId());
            }
            if (Objects.nonNull(e.getManager())) {
                userIds.add(e.getManager());
            }
            if (Objects.nonNull(e.getCreateBy())) {
                userIds.add(e.getCreateBy());
            }
        });
        //地址信息
        Map<Long, KwpGoodsAddress> addressMap = kwpGoodsAddressService.getByGoodsIds(goodsIds)
                .stream().collect(Collectors.toMap(KwpGoodsAddress::getGoodsId, e -> e, (k1, k2) -> k1));
        //价格梯度信息
        Map<Long, List<KwpGoodsPriceRange>> priceRangeMap = kwpGoodsPriceRangeService.getByGoodsIds(goodsIds)
                .stream().collect(Collectors.groupingBy(KwpGoodsPriceRange::getGoodsId));
        //用户信息
        List<UserCacheResDto> userList = remoteSystemService.queryUserCacheByIds(userIds);
        Map<Long, UserCacheResDto> userMap = userList.stream().collect(Collectors.toMap(UserCacheResDto::getId, e -> e, (k1, k2) -> k1));
        //供应企业信息
        List<EntCacheResDto> entList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(supplyEntIds)) {
            entList = remoteSystemService.queryEntCacheByIds(supplyEntIds);
        }
        Map<Long, String> entMap = entList.stream().collect(Collectors.toMap(EntCacheResDto::getId, EntCacheResDto::getFirmName, (k1, k2) -> k1));
        goodsLists.forEach(e -> {
            Long id = e.getId();
            GoodsList goodsList = BeanUtils.copyProperties(e, GoodsList.class);
            UserCacheResDto manager = userMap.get(e.getManager());
            UserCacheResDto createUser = userMap.get(e.getCreateBy());
            goodsList.setStatusLabel(DictEnum.getLabel(DictTypeEnum.GOODS_STATUS.getType(), String.valueOf(goodsList.getStatus())))
                    .setGoodsTypeLabel(DictEnum.getLabel(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), goodsList.getGoodsType()))
                    .setUnitLabel(DictEnum.getLabel(DictTypeEnum.UNIT_TYPE.getType(), goodsList.getUnit()))
                    .setTradingLabel(DictEnum.getLabel(DictTypeEnum.TRADE_TYPE.getType(), goodsList.getTrading()))
                    .setTaxRateLabel(DictEnum.getLabel(DictTypeEnum.TAX_RATE.getType(), goodsList.getTaxRate()))
                    .setManageName(Objects.nonNull(manager) ? manager.getName() : null)
                    .setPhone(Objects.nonNull(manager) ? manager.getPhone() : null)
                    .setSupplyEnt(Objects.nonNull(entMap.get(e.getSupplyEntId())) ? entMap.get(e.getSupplyEntId()) : null)
                    .setAddress(Objects.isNull(addressMap.get(id)) ? null : addressMap.get(id).getName() + addressMap.get(id).getDetailAddress())
                    .setCreateByName(Objects.nonNull(createUser) ? createUser.getName() : null);
            List<KwpGoodsPriceRange> priceRanges = priceRangeMap.get(id);
            goodsList.setHighestPrice(CollectionUtils.isEmpty(priceRanges) ? null : priceRanges.get(priceRanges.size() - 1).getPrice())
                    .setLowestPrice(CollectionUtils.isEmpty(priceRanges) ? null : priceRanges.get(0).getPrice());
            result.add(goodsList);
        });
        return PageResult.build(params.getPage(), params.getPageSize(), goodsIpage.getTotal(), result);
    }

    /**
     * @desc: 商品表格列表查询
     * @author: yzc
     * @date: 2023-07-07 9:09
     * @Param params:
     * @return: java.util.List<com.sckw.product.model.KwpGoods>
     */
    private IPage<KwpGoods> getGoodsLists(SelectGoodsListParam params, Boolean isPage) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(params.getIds())) {
            List<Long> ids = StringUtils.splitStrToList(params.getIds(), ",", Long.class);
            wrapper.in(KwpGoods::getId, ids);
        } else {
            if (Objects.nonNull(params.getEndCreateTime())) {
                wrapper.le(KwpGoods::getCreateTime, DateUtil.offsetDay(params.getEndCreateTime(), 1));
            }
            wrapper.ge(Objects.nonNull(params.getStartCreateTime()), KwpGoods::getCreateTime, params.getStartCreateTime())
                    .eq(StringUtils.isNotBlank(params.getTrading()), KwpGoods::getTrading, params.getTrading())
                    .eq(Objects.nonNull(params.getStatus()) && isPage, KwpGoods::getStatus, params.getStatus());
            if (StringUtils.isNotBlank(params.getGoodsType()) && StringUtils.isNotBlank(params.getGoodsTypeValue())) {
                List<SysDictResDto> goodsTypeList = remoteSystemService.queryDictBottom(params.getGoodsType(), params.getGoodsTypeValue());
                if (CollectionUtils.isNotEmpty(goodsTypeList)) {
                    List<String> goodsTypes = goodsTypeList.stream().map(SysDictResDto::getValue).toList();
                    wrapper.in(KwpGoods::getGoodsType, goodsTypes);
                }
            }
            if (StringUtils.isNotBlank(params.getKeywords())) {
                List<EntCacheResDto> entList = remoteSystemService.queryEntCacheByName(params.getKeywords());
                List<Long> entIds = entList.stream().map(EntCacheResDto::getId).toList();
                if (CollectionUtils.isEmpty(entIds)) {
                    wrapper.like(KwpGoods::getName, params.getKeywords());
                } else {
                    wrapper.and(e -> e.in(KwpGoods::getSupplyEntId, entIds).or().like(KwpGoods::getName, params.getKeywords()));
                }
            }
        }
        wrapper.eq(KwpGoods::getEntId, LoginUserHolder.getEntId()).eq(KwpGoods::getDelFlag, Global.NO).orderByDesc(KwpGoods::getCreateTime);
        IPage<KwpGoods> goodsIpage = new Page<>();
        if (isPage) {
            Page<KwpGoods> page = new Page<>(params.getPage(), params.getPageSize());
            goodsIpage = kwpGoodsMapper.selectPage(page, wrapper);
        } else {
            List<KwpGoods> list = kwpGoodsMapper.selectList(wrapper);
            goodsIpage.setRecords(list);
        }
        return goodsIpage;
    }


    /**
     * @desc: 统计查询
     * @author: yzc
     * @date: 2023-07-05 17:55
     * @Param params:
     * @return: com.sckw.core.model.vo.TableStatisticRes
     */
    public TableStatisticRes statistic(GoodsListParam params) {
        TableStatisticRes res = new TableStatisticRes();
        List<KwpGoods> goodsList = getGoodsLists(BeanUtils.copyProperties(params, SelectGoodsListParam.class), false).getRecords();
        Map<Integer, List<KwpGoods>> map = goodsList.stream().collect(Collectors.groupingBy(KwpGoods::getStatus));
        List<TableTop> tableTops = new ArrayList<>();
        GoodsStatusEnum.getSortList().forEach(e -> {
            List<KwpGoods> list = map.get(e.getCode());
            int total = CollectionUtils.isEmpty(list) ? 0 : list.size();
            TableTop tableTop = new TableTop();
            tableTop.setName(e.getMsg()).setValue(e.getCode()).setTotal(total);
            tableTops.add(tableTop);
        });
        TableBottom tableBottom = new TableBottom();
        tableBottom.setTotal(CollectionUtils.isEmpty(goodsList) ? 0 : goodsList.size());
        res.setTableTops(tableTops).setTableBottom(tableBottom);
        return res;
    }

    /**
     * @desc: 导出
     * @author: yzc
     * @date: 2023-07-06 9:07
     * @Param params:
     * @return: void
     */
    public List<GoodsListExport> export(ExportGoodsListParam params) {
        PageResult pageResult = select(BeanUtils.copyProperties(params, SelectGoodsListParam.class), false);
        List<GoodsList> goodsLists = pageResult.getList();
        if (CollectionUtils.isEmpty(goodsLists)) {
            return Collections.emptyList();
        }
        List<GoodsListExport> list = new ArrayList<>();
        goodsLists.forEach(e -> {
            GoodsListExport export = BeanUtils.copyProperties(e, GoodsListExport.class);
            export.setHighestPrice(Objects.isNull(e.getHighestPrice()) ? null : String.valueOf(e.getHighestPrice()))
                    .setLowestPrice(Objects.isNull(e.getLowestPrice()) ? null : String.valueOf(e.getLowestPrice()))
                    .setAddedTime(Objects.isNull(e.getAddedTime()) ? null : DateUtil.getDateTime(e.getAddedTime()))
                    .setShelfTime(Objects.isNull(e.getShelfTime()) ? null : DateUtil.getDateTime(e.getShelfTime()));
            list.add(export);
        });
        return list;

    }

    /**
     * @desc: 单个上架
     * @author: yzc
     * @date: 2023-07-06 8:56
     * @Param id:
     * @return: void
     */
    public void batchPutOnShelves(Long id) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(KwpGoods::getId, id).eq(KwpGoods::getEntId, LoginUserHolder.getEntId())
                .eq(KwpGoods::getDelFlag, Global.NO).last("LIMIT 1");
        KwpGoods goods = kwpGoodsMapper.selectOne(wrapper);
        if (Objects.isNull(goods)) {
            throw new BusinessException("商品不存在！");
        }
        if (Objects.equals(GoodsStatusEnum.PUT_ON_SHELVES.getCode(), goods.getStatus())) {
            throw new BusinessException("上架操作仅针对“已下架”“草稿”状态的单据！");
        }
        if (Objects.equals(GoodsStatusEnum.SAVED.getCode(), goods.getStatus())) {
            UpdateGoodsParam updateParam = BeanUtils.copyProperties(goods, UpdateGoodsParam.class);
            updateParam.setAttributes(BeanUtils.copyToList(kwpGoodsAttributeService.getByGoodsId(id), GoodsAttributes.class));
            updateParam.setPriceRanges(BeanUtils.copyToList(kwpGoodsPriceRangeService.getByGoodsId(id), GoodsPriceRanges.class));
            updateParam.setImages(BeanUtils.copyToList(kwpGoodsImageService.getByGoodsId(id), GoodsImages.class));
            updateParam.setAddressInfo(BeanUtils.copyProperties(kwpGoodsAddressService.getByGoodsId(id), AddressInfo.class));
            judgeParameters(updateParam);
        }
        LambdaUpdateWrapper<KwpGoods> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(KwpGoods::getStatus, GoodsStatusEnum.PUT_ON_SHELVES.getCode()).set(KwpGoods::getAddedTime, new Date())
                .eq(KwpGoods::getId, id);
        kwpGoodsMapper.update(null, updateWrapper);
    }


    /**
     * @desc: 批量下架
     * @author: yzc
     * @date: 2023-07-06 8:56
     * @Param ids:
     * @return: void
     */
    public void batchTakeOffShelves(List<Long> ids) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(KwpGoods::getId, ids).eq(KwpGoods::getStatus, GoodsStatusEnum.PUT_ON_SHELVES.getCode())
                .eq(KwpGoods::getEntId, LoginUserHolder.getEntId()).eq(KwpGoods::getDelFlag, Global.NO);
        List<KwpGoods> list = kwpGoodsMapper.selectList(wrapper);
        if (!Objects.equals(ids.size(), list.size())) {
            throw new BusinessException("下架操作仅针对“已上架”状态的单据");
        }
        LambdaUpdateWrapper<KwpGoods> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(KwpGoods::getStatus, GoodsStatusEnum.TAKE_OFF_SHELVES.getCode()).set(KwpGoods::getShelfTime, new Date())
                .in(KwpGoods::getId, ids);
        kwpGoodsMapper.update(null, updateWrapper);
    }

    /**
     * @desc: 批量删除
     * @author: yzc
     * @date: 2023-07-06 8:56
     * @Param ids:
     * @return: void
     */
    @Transactional(rollbackFor = Exception.class)
    public void batchDelete(List<Long> ids) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(KwpGoods::getId, ids).in(KwpGoods::getStatus, 0, 2)
                .eq(KwpGoods::getEntId, LoginUserHolder.getEntId()).eq(KwpGoods::getDelFlag, Global.NO);
        List<KwpGoods> list = kwpGoodsMapper.selectList(wrapper);
        if (!Objects.equals(ids.size(), list.size())) {
            throw new BusinessException("删除操作仅针对“已下架”“草稿”状态的单据");
        }
        LambdaUpdateWrapper<KwpGoods> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(KwpGoods::getDelFlag, Global.YES).in(KwpGoods::getId, ids);
        kwpGoodsMapper.update(null, updateWrapper);
        //不作删除，防止订单详情查不出相关信息或查出以往被删除的相关信息
//        kwpGoodsAddressService.delByGoodsIds(ids);
//        kwpGoodsAttributeService.delByGoodsIds(ids);
//        kwpGoodsImageService.delByGoodsIds(ids);
//        kwpGoodsPriceRangeService.delByGoodsIds(ids);
    }


    /**
     * @desc: 建材市场分页查询
     * @author: yzc
     * @date: 2023-07-06 9:38
     * @Param params:
     * @return: com.sckw.core.model.page.PageResult
     */
    public PageResult buildingMaterialsMarketList(BuildingMaterialsMarketListParam params) {
        Page<KwpGoods> page = new Page<>(params.getPage(), params.getPageSize());
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(params.getGoodsType()) && StringUtils.isNotBlank(params.getGoodsTypeValue())) {
            List<SysDictResDto> goodsTypeList = remoteSystemService.queryDictBottom(params.getGoodsType(), params.getGoodsTypeValue());
            if (CollectionUtils.isNotEmpty(goodsTypeList)) {
                List<String> goodsTypes = goodsTypeList.stream().map(SysDictResDto::getValue).toList();
                wrapper.in(KwpGoods::getGoodsType, goodsTypes);
            }
        }
        wrapper.in(CollectionUtils.isNotEmpty(params.getTradings()), KwpGoods::getTrading, params.getTradings())
                .eq(KwpGoods::getStatus, GoodsStatusEnum.PUT_ON_SHELVES.getCode()).eq(KwpGoods::getDelFlag, Global.NO);
        if (Objects.nonNull(params.getAreaCode()) && Objects.nonNull(params.getAreaLevel())) {
            switch (params.getAreaLevel()) {
                case 1 ->
                        wrapper.likeRight(KwpGoods::getAreaCode, String.valueOf(params.getAreaCode()).substring(0, 2));
                case 2 ->
                        wrapper.likeRight(KwpGoods::getAreaCode, String.valueOf(params.getAreaCode()).substring(0, 4));
                case 3 -> wrapper.eq(KwpGoods::getAreaCode, params.getAreaCode());
            }
        }
        if (StringUtils.isNotBlank(params.getKeywords())) {
            List<EntCacheResDto> entList = remoteSystemService.queryEntCacheByName(params.getKeywords());
            List<Long> entIds = entList.stream().map(EntCacheResDto::getId).toList();
            if (CollectionUtils.isNotEmpty(entIds)) {
                wrapper.and(e -> e.in(KwpGoods::getSupplyEntId, entIds).or().like(KwpGoods::getName, params.getKeywords()));
            } else {
                wrapper.like(KwpGoods::getName, params.getKeywords());
            }
        }
        wrapper.orderByDesc(KwpGoods::getCreateTime);
        Page<KwpGoods> kwpGoodsPage = kwpGoodsMapper.selectPage(page, wrapper);
        List<KwpGoods> list = kwpGoodsPage.getRecords();
        if (CollectionUtils.isEmpty(list)) {
            return PageResult.build(params.getPage(), params.getPageSize(), kwpGoodsPage.getTotal(), Collections.emptyList());
        }
        List<BuildingMaterialsMarketList> result = new ArrayList<>(list.size());
        List<Long> goodsIds = new ArrayList<>(list.size());
        List<Long> supplyEntIds = new ArrayList<>(list.size());
        list.forEach(e -> {
            goodsIds.add(e.getId());
            supplyEntIds.add(e.getSupplyEntId());
        });
        //地址信息
        Map<Long, KwpGoodsAddress> addressMap = kwpGoodsAddressService.getByGoodsIds(goodsIds)
                .stream().collect(Collectors.toMap(KwpGoodsAddress::getGoodsId, e -> e, (k1, k2) -> k1));
        //价格梯度信息
        Map<Long, List<KwpGoodsPriceRange>> priceRangeMap = kwpGoodsPriceRangeService.getByGoodsIds(goodsIds)
                .stream().collect(Collectors.groupingBy(KwpGoodsPriceRange::getGoodsId));
        //供应企业信息
        List<EntCacheResDto> entList = remoteSystemService.queryEntCacheByIds(supplyEntIds);
        Map<Long, String> entMap = entList.stream().collect(Collectors.toMap(EntCacheResDto::getId, EntCacheResDto::getFirmName, (k1, k2) -> k1));

        list.forEach(e -> {
            BuildingMaterialsMarketList materials = BeanUtils.copyProperties(e, BuildingMaterialsMarketList.class);
            KwpGoodsAddress address = addressMap.get(e.getId());
            List<KwpGoodsPriceRange> priceRanges = priceRangeMap.get(e.getId());
            materials.setAddressName(Objects.isNull(address) ? null : address.getName())
                    .setDetailAddress(Objects.isNull(address) ? null : address.getDetailAddress())
                    .setPrice(CollectionUtils.isEmpty(priceRanges) ? null : priceRanges.get(0).getPrice())
                    .setGoodsTypeLabel(DictEnum.getLabel(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), e.getGoodsType()))
                    .setTradingLabel(DictEnum.getLabel(DictTypeEnum.TRADE_TYPE.getType(), e.getTrading()))
                    .setUnitLabel(DictEnum.getLabel(DictTypeEnum.UNIT_TYPE.getType(), e.getUnit()))
                    .setSupplyEnt(entMap.get(e.getSupplyEntId()));
            result.add(materials);
        });
        return PageResult.build(params.getPage(), params.getPageSize(), kwpGoodsPage.getTotal(), result);
    }


    /**
     * @desc: 商品下拉列表
     * @author: yzc
     * @date: 2023-07-06 8:45
     * @Param params:
     * @return: java.util.List<com.sckw.product.model.vo.res.GoodsDropList>
     */
    public List<GoodsDropList> dropList(GoodsDropListReq params) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotBlank(params.getName()), KwpGoods::getName, params.getName())
                .eq(KwpGoods::getStatus, GoodsStatusEnum.PUT_ON_SHELVES.getCode())
                .eq(KwpGoods::getDelFlag, Global.NO).orderByDesc(KwpGoods::getAddedTime);
        List<KwpGoods> list = kwpGoodsMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(list)) {
            return Collections.emptyList();
        }
        List<Long> supplyEntIds = list.stream().map(KwpGoods::getSupplyEntId).distinct().toList();
        List<EntCacheResDto> entList = remoteSystemService.queryEntCacheByIds(supplyEntIds);
        Map<Long, String> entMap = entList.stream().collect(Collectors.toMap(EntCacheResDto::getId, EntCacheResDto::getFirmName, (k1, k2) -> k1));
        List<GoodsDropList> result = new ArrayList<>();
        list.forEach(e -> {
            GoodsDropList goodsDropList = BeanUtils.copyProperties(e, GoodsDropList.class);
            goodsDropList.setSupplyEnt(entMap.get(e.getSupplyEntId()));
            result.add(goodsDropList);
        });
        return result;
    }

    /**
     * @desc: 根据商品id获取当前企业商品信息
     * @author: yzc
     * @date: 2023-07-05 14:25
     * @Param id:
     * @return: com.sckw.product.model.KwpGoods
     */
    public KwpGoods getGoodsById(Long id) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<KwpGoods> last = wrapper.eq(KwpGoods::getId, id).eq(KwpGoods::getEntId, LoginUserHolder.getEntId())
                .eq(KwpGoods::getDelFlag, Global.NO).last("LIMIT 1");
        return kwpGoodsMapper.selectOne(last);
    }

    /**
     * @desc: 根据商品id获取未删除商品信息
     * @author: yzc
     * @date: 2023-07-13 15:08
     * @Param id:
     * @return: com.sckw.product.model.KwpGoods
     */
    public KwpGoods selectGoodsById(Long id) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<KwpGoods> last = wrapper.eq(KwpGoods::getId, id).eq(KwpGoods::getDelFlag, Global.NO).last("LIMIT 1");
        return kwpGoodsMapper.selectOne(last);
    }

    /**
     * @desc: 根据商品id获取商品信息
     * @author: yzc
     * @date: 2023-07-20 11:16
     * @Param ids:
     * @return: java.util.List<com.sckw.product.model.KwpGoods>
     */
    public KwpGoods selectById(Long id) {
        return kwpGoodsMapper.selectById(id);
    }


    /**
     * @desc: 根据商品ids获取商品信息
     * @author: yzc
     * @date: 2023-07-20 11:16
     * @Param ids:
     * @return: java.util.List<com.sckw.product.model.KwpGoods>
     */
    public List<KwpGoods> selectByIds(List<Long> ids) {
        List<KwpGoods> list = kwpGoodsMapper.selectBatchIds(ids);
        return CollectionUtils.emptyIfNull(list);
    }

    /**
     * @desc: 更新
     * @author: yzc
     * @date: 2023-07-13 15:11
     * @Param goods:
     * @return: void
     */
    public void updateById(KwpGoods goods) {
        kwpGoodsMapper.updateById(goods);
    }
}
