package com.m2pool.lease.service.impl;

import cn.hutool.json.JSONUtil;
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.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.m2pool.common.redis.service.RedisService;
import com.m2pool.common.security.utils.SecurityUtils;
import com.m2pool.lease.constant.BlockInterval;
import com.m2pool.lease.constant.CoinCharge;
import com.m2pool.lease.redis.RedisCoinInfoKey;
import com.m2pool.lease.dto.*;
import com.m2pool.lease.dto.v2.CartMachineInfoDto;
import com.m2pool.lease.dto.v2.ShopCartV2Dto;
import com.m2pool.lease.entity.*;
import com.m2pool.lease.mapper.*;
import com.m2pool.lease.service.LeaseShoppingCartInfoService;
import com.m2pool.lease.service.LeaseShoppingCartService;
import com.m2pool.lease.utils.PowerUnitUtils;
import com.m2pool.lease.vo.BaseVo;
import com.m2pool.lease.vo.PageVo;
import com.m2pool.lease.vo.ProductAndMachineVo;
import com.m2pool.lease.vo.ShoppingCartInfoURDVo;
import com.m2pool.lease.vo.v2.AddGoodsVo;
import com.m2pool.lease.vo.v2.CartInfoVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 购物车表 服务实现类
 * </p>
 *
 * @author yyb
 * @since 2025-07-23
 */
@Service
public class LeaseShoppingCartServiceImpl extends ServiceImpl<LeaseShoppingCartMapper, LeaseShoppingCart> implements LeaseShoppingCartService {


    @Resource
    private LeaseShoppingCartInfoMapper leaseShoppingCartInfoMapper;

    @Resource
    private LeaseShoppingCartInfoService leaseShoppingCartInfoService;

    @Resource
    private LeaseProductMachineMapper leaseProductMachineMapper;

    @Resource
    private LeaseShopMapper leaseShopMapper;

    @Resource
    private LeaseProductMachinePriceMapper leaseProductMachinePriceMapper;

    @Resource
    private RedisService redisService;

    @Resource
    private LeaseMachineMapper leaseMachineMapper;

    @Resource
    private LeaseMachinePriceMapper leaseMachinePriceMapper;

    @Override
    @Transactional
    public Result<String> addGoods(List<ShoppingCartInfoURDVo> shoppingCartInfoURDVoList) {
        String userId = SecurityUtils.getUsername();
        if (shoppingCartInfoURDVoList.isEmpty()) {
            return Result.fail("请选择商品");
        }

        List<Long> machineIds = shoppingCartInfoURDVoList.stream().map(ShoppingCartInfoURDVo::getProductMachineId).collect(Collectors.toList());
        List<LeaseProductMachine> leaseProductMachines = leaseProductMachineMapper.selectList(new LambdaQueryWrapper<LeaseProductMachine>()
                .select(LeaseProductMachine::getId, LeaseProductMachine::getShopId)
                .in(LeaseProductMachine::getId, machineIds));
        Map<Long, Long> collect = leaseProductMachines.stream().collect(Collectors.toMap(LeaseProductMachine::getId, LeaseProductMachine::getShopId));
        //获取用户购物车中所有矿机
        List<LeaseShoppingCartInfo> leaseShoppingCartInfos = leaseShoppingCartInfoMapper
                .selectList(new LambdaQueryWrapper<LeaseShoppingCartInfo>()
                .eq(LeaseShoppingCartInfo::getUserId, userId));

        // 存储需要新增的记录
        List<LeaseShoppingCartInfo> newRecords = shoppingCartInfoURDVoList.stream()
                .filter(vo -> leaseShoppingCartInfos.stream()
                        .noneMatch(info -> info.getProductMachineId().equals(vo.getProductMachineId())))
                .map(shoppingCartInfoURDVo ->
                        LeaseShoppingCartInfo.builder()
                                .userId(userId)
                                .shopId(collect.get(shoppingCartInfoURDVo.getProductMachineId()))
                                .leaseTime(shoppingCartInfoURDVo.getLeaseTime())
                                .productId(shoppingCartInfoURDVo.getProductId())
                                .productMachineId(shoppingCartInfoURDVo.getProductMachineId())
                                .build()
                ).collect(Collectors.toList());

        // 存储需要更新的记录
        Map<Long, ShoppingCartInfoURDVo> voMap = shoppingCartInfoURDVoList.stream()
                .collect(Collectors.toMap(ShoppingCartInfoURDVo::getProductMachineId, vo -> vo));
        List<LeaseShoppingCartInfo> updateList = leaseShoppingCartInfos.stream()
                .peek(info -> {
                    ShoppingCartInfoURDVo vo = voMap.get(info.getProductMachineId());
                    if (vo != null) {
                        info.setLeaseTime(info.getLeaseTime() + vo.getLeaseTime());
                        info.setId(info.getId());
                    }
                })
                .collect(Collectors.toList());

        // 执行更新操作
        if (!updateList.isEmpty()) {
            boolean updateResult = leaseShoppingCartInfoService.updateBatchById(updateList);
            if (!updateResult) {
                return Result.fail("更新购物车租赁时间失败");
            }
        }

        // 执行新增操作
        if (!newRecords.isEmpty()) {
            boolean saveResult = leaseShoppingCartInfoService.saveBatch(newRecords);
            if (!saveResult) {
                return Result.fail("添加新购物车记录失败");
            }
        }

        return Result.success("添加购物车成功");
    }



    @Override
    public PageResult<ShopCartDto> getGoodsList(PageVo pageVo) {
        String userId = SecurityUtils.getUsername();
        //检查购物车中是否存在商品
        List<ShoppingCartInfoDto> cartInfoList = leaseShoppingCartInfoMapper.getProductAndMachineIds(userId,0);
        if (cartInfoList.isEmpty()){
            return PageResult.success(new ArrayList<>());
        }
        List<Long> machineIds = new ArrayList<>();
        Map<Long, Integer> machineMap = new HashMap<>();
        for (ShoppingCartInfoDto shoppingCartInfoDto : cartInfoList) {
            machineIds.add(shoppingCartInfoDto.getProductMachineId());
            machineMap.put(shoppingCartInfoDto.getProductMachineId(), shoppingCartInfoDto.getLeaseTime());
        }
        List<Long> shopIds = leaseShopMapper.getShopIdsByMachineIds(machineIds);
        PageHelper.startPage(pageVo.getPageNum(), pageVo.getPageSize());
        //查询购物车中店铺信息(一层)
        List<LeaseShop> leaseShops = leaseShopMapper.selectList(new LambdaQueryWrapper<LeaseShop>().in(LeaseShop::getId, shopIds));
        //获取商品售价
        List<MachinePayTypeDto> machinePriceByMachineIds = leaseProductMachinePriceMapper.getMachinePriceByMachineIds(machineIds);
        Map<Long, List<MachinePayTypeDto>> machinePriceMap = machinePriceByMachineIds.stream().collect(Collectors.groupingBy(MachinePayTypeDto::getProductMachineId));
        //查询商品中机器详情 + 按照币种分组 (二层)
        List<ProductMachineDto> leaseProductMachines = leaseProductMachineMapper.getMachinesByIds(machineIds);
        //获取实时币价
        List<String> coins = leaseProductMachines.stream().map(ProductMachineDto::getCoin).distinct().collect(Collectors.toList());
        Map<String, BigDecimal> coinPriceMap = new HashMap<>();
        Map<String, BigDecimal> coinRewardMap = new HashMap<>();
        Map<String, BigDecimal> coinMhsMap = new HashMap<>();
        for (String coin : coins) {
            BigDecimal price = redisService.getCacheBigDecimal(RedisCoinInfoKey.getPiceKey(coin));
            BigDecimal reward =redisService.getCacheBigDecimal(RedisCoinInfoKey.getRewardKey(coin));
            BigDecimal mhs = redisService.getCacheBigDecimal(RedisCoinInfoKey.getMhsKey(coin));
            coinMhsMap.put(coin, mhs);
            coinRewardMap.put(coin, reward);
            coinPriceMap.put(coin, price);
        }
        //按币种查询每个矿机的最近一次30分钟的实时算力(后续修改为24小时平均算力)
        List<ProductMachineDto> userMinerPowerList = new ArrayList<>();
        Map<String, List<LeaseProductMachine>> userAndMinerList = leaseProductMachines.stream().map(
                ProductMachineDto ->
                        LeaseProductMachine.builder()
                                .user(ProductMachineDto.getUser())
                                .miner(ProductMachineDto.getMiner())
                                .coin(ProductMachineDto.getCoin())
                                .build()
        ).collect(Collectors.groupingBy(LeaseProductMachine::getCoin));

        userAndMinerList.forEach((coin, userMinerDtos) -> {
            List<ProductMachineDto> recentlyFiveMinutesData = leaseProductMachineMapper.getRecentlyFiveMinutesData(userMinerDtos, coin);
            List<ProductMachineDto> collect = recentlyFiveMinutesData.stream().peek(dto -> {
                dto.setCoin(coin);
            }).collect(Collectors.toList());
            userMinerPowerList.addAll(collect);
        });

        Map<String, ProductMachineDto> realPowerList = userMinerPowerList.stream()
                .collect(Collectors.toMap(
                        dto -> dto.getUser() + "-" + dto.getMiner() + "-" + dto.getCoin(),
                        dto -> dto
                ));
        //为每个矿机设置实时的算力 + 按店铺分组
        Map<Long, List<ProductMachineDto>> shopIdAndMachineInfoMap = leaseProductMachines.stream().peek(productMachineDto -> {
            ProductMachineDto userMinerPowerDto = realPowerList.get(productMachineDto.getUser() + "-" + productMachineDto.getMiner() + "-" + productMachineDto.getCoin());
            List<MachinePayTypeDto> machinePayTypeDtoList = machinePriceMap.get(productMachineDto.getId());
            productMachineDto.setPriceList(machinePayTypeDtoList);
            //理论收益
            BigDecimal singleTheoryMachineIncome;
            BigDecimal computingPower;
            BigDecimal singleTheoryUSDTMachineIncome;
            if (userMinerPowerDto != null) {
                // 矿机算力单位转换 + 计算单矿机平均算力(ComputingPower coin_mhs30m 平均算力)
                computingPower  = PowerUnitUtils.getPower(productMachineDto.getUnit(),
                        userMinerPowerDto.getComputingPower()
                                .multiply(BigDecimal.valueOf(1000 * 1000))
                                .divide(BigDecimal.valueOf(24 * 60 * 60 ), 2, RoundingMode.HALF_UP));
               BigDecimal mhs =  coinMhsMap.get(productMachineDto.getCoin());
                BigDecimal reward = coinRewardMap.get(productMachineDto.getCoin());
                BigDecimal price = coinPriceMap.get(productMachineDto.getCoin());
                if (mhs == null || reward == null || price == null){
                    singleTheoryMachineIncome = productMachineDto.getTheoryIncome();
                    singleTheoryUSDTMachineIncome = singleTheoryMachineIncome.multiply(price);
                }else{
                    //全网算力单位转换
                    BigDecimal power = PowerUnitUtils.getPower(productMachineDto.getUnit(),mhs).multiply(BigDecimal.valueOf(1000 * 1000));
                    //（理论收益 = 矿机算力/全网算力 * 24h /出块间隔秒数 * 单块奖励（redis中nexa:reward））
                    singleTheoryMachineIncome = computingPower.divide( power,6, RoundingMode.HALF_UP)
                            .multiply(BigDecimal.valueOf(24 * 60 * 60)
                                    .divide(BlockInterval.getBlockCountByCoinName(productMachineDto.getCoin()), 6, RoundingMode.HALF_UP)).multiply(reward);
                    singleTheoryUSDTMachineIncome = singleTheoryMachineIncome.multiply(price);
                }
                //单位为MH/s 需要转换成 矿机设定的单位
                productMachineDto.setComputingPower(computingPower);
                productMachineDto.setTheoryIncome(singleTheoryMachineIncome);
                productMachineDto.setTheoryUsdtIncome(singleTheoryUSDTMachineIncome);
            }
        }).collect(Collectors.groupingBy(ProductMachineDto::getShopId));

        //获取商铺钱包配置信息
        List<PayConfigDto> shopWalletInfo = leaseShopMapper.getShopWalletInfoList(shopIds);

        Map<Long, List<PayConfigDto>> payConfigMap = shopWalletInfo.stream()
                .map(payConfigDto->{
                    payConfigDto.setDeductibleAmount(CoinCharge.getDeductibleAmountByChainAndCoin(payConfigDto.getPayChain(), payConfigDto.getPayCoin()));
                    payConfigDto.setFee(CoinCharge.getChargeByChainAndCoin(payConfigDto.getPayChain(), payConfigDto.getPayCoin()));
                   return payConfigDto;
                })
                .collect(Collectors.groupingBy(PayConfigDto::getShopId));
        //组合返回对象
        List<ShopCartDto> shopCartList = leaseShops.stream().map(leaseShop -> {
            List<ProductMachineDto> productMachineList = shopIdAndMachineInfoMap.get(leaseShop.getId());
            return ShopCartDto.builder()
                    .id(leaseShop.getId())
                    .name(leaseShop.getName())
                    .totalMachine(productMachineList != null ? productMachineList.size() : 0)
                    .payConfigList(payConfigMap.get(leaseShop.getId()))
                    .productMachineDtoList(productMachineList)
                    .build();
        }).collect(Collectors.toList());



        //计算不同链和币种对应的总售价
        for (ShopCartDto shopCartDto : shopCartList) {
            //遍历每个商铺下的矿机
            List<ProductMachineDto> productMachineDtoList = shopCartDto.getProductMachineDtoList();
            Map<String, BigDecimal> totalPriceMap = new HashMap<>();
            Map<String, MachineTotalPriceDto> totalPriceDtoMap = new HashMap<>();
            for (ProductMachineDto productMachineDto : productMachineDtoList) {
                Integer leaseTime = machineMap.get(productMachineDto.getId());
                productMachineDto.setLeaseTime(leaseTime);
                List<MachinePayTypeDto> priceList = productMachineDto.getPriceList();
                for (MachinePayTypeDto machinePayTypeDto : priceList) {
                    BigDecimal itemPrice = machinePayTypeDto.getPrice().multiply(new BigDecimal(leaseTime));
                    String key = machinePayTypeDto.getCoin()+"-"+machinePayTypeDto.getChain();
                    totalPriceMap.merge(key, itemPrice, BigDecimal::add);
                    totalPriceDtoMap.put(key,new MachineTotalPriceDto(BigDecimal.ZERO, machinePayTypeDto.getChain(), machinePayTypeDto.getCoin()));
                }
            }
            totalPriceDtoMap.forEach((key, value) -> {
                value.setPrice(totalPriceMap.get(key));
            });

            shopCartDto.setTotalPriceList(new ArrayList<>(totalPriceDtoMap.values()));
        }
        PageInfo<ShopCartDto> pageInfo = new PageInfo<>(shopCartList);
        PageResult<ShopCartDto> success = PageResult.success(shopCartList);
        success.setTotal(pageInfo.getTotal());
        success.setTotalPage(pageInfo.getPages());
        PageHelper.clearPage();
        return success;

    }


    @Override
    @Transactional
    public Result<String> deleteBatchGoods(List<ProductAndMachineVo> baseVoList) {
        List<LeaseShoppingCartInfo> leaseShoppingCartInfos = leaseShoppingCartInfoMapper.selectList(new LambdaQueryWrapper<LeaseShoppingCartInfo>()
                .eq(LeaseShoppingCartInfo::getUserId, SecurityUtils.getUsername())
                .eq(LeaseShoppingCartInfo::getVersion, 0));
        if (leaseShoppingCartInfos.isEmpty()){
            return Result.fail("删除购物车商品失败,购物车中不存在商品");
        }
        List<Long> ids = new ArrayList<>();
        for (LeaseShoppingCartInfo leaseShoppingCartInfo : leaseShoppingCartInfos) {
            for (ProductAndMachineVo baseVo : baseVoList){
                if (leaseShoppingCartInfo.getProductMachineId().equals(baseVo.getMachineId())){
                    ids.add(leaseShoppingCartInfo.getId());
                }
            }
        }
        if (ids.isEmpty()){
            return Result.fail("删除购物车商品失败,购物车中不存在该商品");
        }
        leaseShoppingCartInfoMapper.deleteBatchData(ids);
        return Result.success("删除购物车商品成功");
    }

    @Override
    @Transactional
    public Result<String> deleteGoods(BaseVo baseVo) {
        int delete = leaseShoppingCartInfoMapper.deleteById(baseVo.getId());
        if (delete > 0){
            return Result.success("删除购物车商品成功");
        }
        return Result.fail("删除购物车商品失败");
    }


    @Override
    public Result<String> deleteBatchGoodsForIsDelete() {
        List<LeaseShoppingCartInfo> leaseShoppingCartInfos = leaseShoppingCartInfoMapper.selectList(new LambdaQueryWrapper<LeaseShoppingCartInfo>()
                .eq(LeaseShoppingCartInfo::getUserId, SecurityUtils.getUsername()));

        List<Long> machineIds = leaseShoppingCartInfos.stream().map(LeaseShoppingCartInfo::getProductMachineId)
                .collect(Collectors.toList());
        List<LeaseProductMachine> leaseProductMachines = leaseProductMachineMapper.selectList(new LambdaQueryWrapper<LeaseProductMachine>()
                .in(LeaseProductMachine::getId, machineIds));
        List<Long> delMachineIds = leaseProductMachines.stream().filter(productMachine -> productMachine.getDel() || productMachine.getState() == 1)
                .map(LeaseProductMachine::getId).collect(Collectors.toList());

        if (delMachineIds.isEmpty()){
            return Result.success("删除购物车已下架商品成功");
        }

        int delete = leaseShoppingCartInfoMapper.delete(new LambdaUpdateWrapper<LeaseShoppingCartInfo>()
                .in(LeaseShoppingCartInfo::getProductMachineId, delMachineIds));
        if (delete > 0){
            return Result.success("删除购物车已下架商品成功");
        }
        return Result.fail("删除失败,不存在已下架商品");
    }

    @Override
    public Result<String> addGoodsV2(List<AddGoodsVo> addGoodsVoList) {

        String userId = SecurityUtils.getUsername();
        if (addGoodsVoList.isEmpty()) {
            return Result.fail("请选择商品");
        }

        List<Long> machineIds = addGoodsVoList.stream().map(AddGoodsVo::getId).collect(Collectors.toList());
        List<LeaseMachine> leaseProductMachines = leaseMachineMapper.selectList(new LambdaQueryWrapper<LeaseMachine>()
                .select(LeaseMachine::getId, LeaseMachine::getShopId)
                .in(LeaseMachine::getId, machineIds));
        Map<Long, Long> collect = leaseProductMachines.stream()
                .collect(Collectors.toMap(LeaseMachine::getId, LeaseMachine::getShopId));
        //获取用户购物车中所有矿机
        List<LeaseShoppingCartInfo> leaseShoppingCartInfos = leaseShoppingCartInfoMapper
                .selectList(new LambdaQueryWrapper<LeaseShoppingCartInfo>()
                        .eq(LeaseShoppingCartInfo::getUserId, userId));

        // 存储需要新增的记录
        List<LeaseShoppingCartInfo> newRecords = addGoodsVoList.stream()
                .filter(vo -> leaseShoppingCartInfos.stream()
                        .noneMatch(info -> info.getProductMachineId().equals(vo.getId())))
                .map(shoppingCartInfoURDVo ->
                        LeaseShoppingCartInfo.builder()
                                .userId(userId)
                                .shopId(collect.get(shoppingCartInfoURDVo.getId()))
                                .leaseTime(shoppingCartInfoURDVo.getLeaseTime())
                                .numbers(shoppingCartInfoURDVo.getNumbers())
                                .productMachineId(shoppingCartInfoURDVo.getId())
                                .version(1)
                                .build()
                ).collect(Collectors.toList());

        // 存储需要更新的记录
        Map<Long, AddGoodsVo> voMap = addGoodsVoList.stream()
                .collect(Collectors.toMap(AddGoodsVo::getId, vo -> vo));
        List<LeaseShoppingCartInfo> updateList = leaseShoppingCartInfos.stream()
                .peek(info -> {
                    AddGoodsVo vo = voMap.get(info.getProductMachineId());
                    if (vo != null && vo.getNumbers() != null) {
                        info.setNumbers(info.getNumbers()+vo.getNumbers());
                        info.setLeaseTime(info.getLeaseTime() + vo.getLeaseTime());
                        info.setId(info.getId());
                    }
                })
                .collect(Collectors.toList());

        System.out.println("updateList"+ JSONUtil.toJsonPrettyStr(updateList));
        System.out.println("newRecords"+ JSONUtil.toJsonPrettyStr(newRecords));
        // 执行更新操作
        if (!updateList.isEmpty()) {
            boolean updateResult = leaseShoppingCartInfoService.updateBatchById(updateList);
            if (!updateResult) {
                return Result.fail("更新购物车租赁时间失败");
            }
        }

        // 执行新增操作
        if (!newRecords.isEmpty()) {
            boolean saveResult = leaseShoppingCartInfoService.saveBatch(newRecords);
            if (!saveResult) {
                return Result.fail("添加新购物车记录失败");
            }
        }

        return Result.success("添加购物车成功");
    }

    @Override
    public PageResult<ShopCartV2Dto> getGoodsListV2(PageVo pageVo) {
        String userId = SecurityUtils.getUsername();
        //检查购物车中是否存在商品
        List<ShoppingCartInfoDto> cartInfoList = leaseShoppingCartInfoMapper.getProductAndMachineIds(userId,1);
        if (cartInfoList.isEmpty()){
            return PageResult.success(new ArrayList<>());
        }
        List<Long> machineIds = new ArrayList<>();
        Map<Long, Integer> machineMap = new HashMap<>();
        for (ShoppingCartInfoDto shoppingCartInfoDto : cartInfoList) {
            machineIds.add(shoppingCartInfoDto.getProductMachineId());
            machineMap.put(shoppingCartInfoDto.getProductMachineId(), shoppingCartInfoDto.getLeaseTime());
        }

        List<Long> shopIds = leaseMachineMapper.getShopIdsByMachineIds(machineIds);
        PageHelper.startPage(pageVo.getPageNum(), pageVo.getPageSize());
        //查询购物车中店铺信息(一层)
        List<LeaseShop> leaseShops = leaseShopMapper.selectList(new LambdaQueryWrapper<LeaseShop>()
                .in(LeaseShop::getId, shopIds));

        //获取商品售价
        List<MachinePayTypeDto> machinePriceByMachineIds = leaseMachinePriceMapper.getMachinePriceByMachineIds(machineIds);
        Map<Long, List<MachinePayTypeDto>> machinePriceMap = machinePriceByMachineIds.stream()
                .collect(Collectors.groupingBy(MachinePayTypeDto::getProductMachineId));

        //查询店铺中机器详情
        List<CartMachineInfoDto> leaseProductMachines = leaseMachineMapper.getMachinesByIds(machineIds);
        //获取实时币价 TODO 这里需要新加入一些币种的全网实时算力以及实时币价和报块奖励
        //List<String> coins = leaseProductMachines.stream().map(ProductMachineDto::getCoin).distinct().collect(Collectors.toList());
        //Map<String, BigDecimal> coinPriceMap = new HashMap<>();
        //Map<String, BigDecimal> coinRewardMap = new HashMap<>();
        //Map<String, BigDecimal> coinMhsMap = new HashMap<>();
        //for (String coin : coins) {
        //    BigDecimal price = redisService.getCacheBigDecimal(RedisCoinInfoKey.getPiceKey(coin));
        //    BigDecimal reward =redisService.getCacheBigDecimal(RedisCoinInfoKey.getRewardKey(coin));
        //    BigDecimal mhs = redisService.getCacheBigDecimal(RedisCoinInfoKey.getMhsKey(coin));
        //    coinMhsMap.put(coin, mhs);
        //    coinRewardMap.put(coin, reward);
        //    coinPriceMap.put(coin, price);
        //}

        //设置每个矿机的售价,并按店铺分组
        Map<Long, List<CartMachineInfoDto>> shopIdAndMachineInfoMap = leaseProductMachines.stream()
                .peek(productMachineDto -> {
                        productMachineDto.setPriceList(machinePriceMap.get(productMachineDto.getId()));
                })
                .collect(Collectors.groupingBy(CartMachineInfoDto::getShopId));
        //获取商铺钱包配置信息
        List<PayConfigDto> shopWalletInfo = leaseShopMapper.getShopWalletInfoList(shopIds);
        Map<Long, List<PayConfigDto>> payConfigMap = shopWalletInfo.stream()
                .map(payConfigDto->{
                    payConfigDto.setDeductibleAmount(CoinCharge.getDeductibleAmountByChainAndCoin(payConfigDto.getPayChain(), payConfigDto.getPayCoin()));
                    payConfigDto.setFee(CoinCharge.getChargeByChainAndCoin(payConfigDto.getPayChain(), payConfigDto.getPayCoin()));
                    return payConfigDto;
                })
                .collect(Collectors.groupingBy(PayConfigDto::getShopId));
        //组合返回对象
        List<ShopCartV2Dto> shopCartList = leaseShops.stream().map(leaseShop -> {
            List<CartMachineInfoDto> productMachineList = shopIdAndMachineInfoMap.get(leaseShop.getId());
            return ShopCartV2Dto.builder()
                    .id(leaseShop.getId())
                    .name(leaseShop.getName())
                    .totalMachine(productMachineList != null ? productMachineList.size() : 0)
                    .payConfigList(payConfigMap.get(leaseShop.getId()))
                    .cartMachineInfoDtoList(productMachineList)
                    .build();
        }).collect(Collectors.toList());



        //计算不同链和币种对应的总售价
        for (ShopCartV2Dto shopCartDto : shopCartList) {
            //遍历每个商铺下的矿机
            List<CartMachineInfoDto> productMachineDtoList = shopCartDto.getCartMachineInfoDtoList();
            Map<String, BigDecimal> totalPriceMap = new HashMap<>();
            Map<String, MachineTotalPriceDto> totalPriceDtoMap = new HashMap<>();
            for (CartMachineInfoDto productMachineDto : productMachineDtoList) {
                Integer leaseTime = machineMap.get(productMachineDto.getId());
                productMachineDto.setLeaseTime(leaseTime);
                List<MachinePayTypeDto> priceList = productMachineDto.getPriceList();
                for (MachinePayTypeDto machinePayTypeDto : priceList) {
                    BigDecimal itemPrice = machinePayTypeDto.getPrice().multiply(new BigDecimal(leaseTime));
                    String key = machinePayTypeDto.getCoin()+"-"+machinePayTypeDto.getChain();
                    totalPriceMap.merge(key, itemPrice, BigDecimal::add);
                    totalPriceDtoMap.put(key,new MachineTotalPriceDto(BigDecimal.ZERO, machinePayTypeDto.getChain(), machinePayTypeDto.getCoin()));
                }
            }
            totalPriceDtoMap.forEach((key, value) -> {
                value.setPrice(totalPriceMap.get(key));
            });

            shopCartDto.setTotalPriceList(new ArrayList<>(totalPriceDtoMap.values()));
        }
        PageInfo<ShopCartV2Dto> pageInfo = new PageInfo<>(shopCartList);
        PageResult<ShopCartV2Dto> success = PageResult.success(shopCartList);
        success.setTotal(pageInfo.getTotal());
        success.setTotalPage(pageInfo.getPages());
        PageHelper.clearPage();
        return success;
    }

    @Override
    public Result<String> deleteBatchGoodsV2(List<CartInfoVo> baseVoList) {
        List<Long> ids = baseVoList.stream().map(CartInfoVo::getCartInfoId).collect(Collectors.toList());
        leaseShoppingCartInfoMapper.deleteBatchData(ids);
        return Result.success("删除购物车商品成功");
    }

    @Override
    public Result<String> deleteBatchGoodsForIsDeleteV2() {
        List<LeaseShoppingCartInfo> leaseShoppingCartInfos = leaseShoppingCartInfoMapper.selectList(new LambdaQueryWrapper<LeaseShoppingCartInfo>()
                .eq(LeaseShoppingCartInfo::getUserId, SecurityUtils.getUsername()));

        List<Long> machineIds = leaseShoppingCartInfos.stream().map(LeaseShoppingCartInfo::getProductMachineId).collect(Collectors.toList());
        List<LeaseMachine> leaseMachines = leaseMachineMapper.selectList(new LambdaQueryWrapper<LeaseMachine>()
                .in(LeaseMachine::getId, machineIds));

        List<Long> delMachineIds = leaseMachines.stream().filter(machine -> machine.getDel() || machine.getState())
                .map(LeaseMachine::getId).collect(Collectors.toList());

        if (delMachineIds.isEmpty()){
            return Result.success("删除购物车已下架商品成功");
        }

        int delete = leaseShoppingCartInfoMapper.delete(new LambdaUpdateWrapper<LeaseShoppingCartInfo>()
                .in(LeaseShoppingCartInfo::getProductMachineId, delMachineIds));
        if (delete > 0){
            return Result.success("删除购物车已下架商品成功");
        }
        return Result.fail("删除失败,不存在已下架商品");

    }
}
