package com.gxwebsoft.shop.service.impl;

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.glt.entity.GltTicketOrder;
import com.gxwebsoft.glt.entity.GltTicketTemplate;
import com.gxwebsoft.glt.entity.GltUserTicket;
import com.gxwebsoft.glt.service.GltTicketOrderService;
import com.gxwebsoft.glt.service.GltTicketTemplateService;
import com.gxwebsoft.glt.service.GltUserTicketService;
import com.gxwebsoft.shop.entity.ShopDealerCapital;
import com.gxwebsoft.shop.entity.ShopDealerOrder;
import com.gxwebsoft.shop.entity.ShopDealerUser;
import com.gxwebsoft.shop.entity.ShopGoods;
import com.gxwebsoft.shop.entity.ShopOrder;
import com.gxwebsoft.shop.entity.ShopOrderGoods;
import com.gxwebsoft.shop.mapper.ShopDealerOrderMapper;
import com.gxwebsoft.shop.service.ShopDealerCapitalService;
import com.gxwebsoft.shop.service.ShopDealerOrderService;
import com.gxwebsoft.shop.param.ShopDealerOrderParam;
import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 分销商订单记录表Service实现
 *
 * @author 科技小王子
 * @since 2025-08-12 11:55:18
 */
@Service
@Slf4j
public class ShopDealerOrderServiceImpl extends ServiceImpl<ShopDealerOrderMapper, ShopDealerOrder> implements ShopDealerOrderService {

    private static final int ORDER_STATUS_CONFIRMED_RECEIVE = 1;
    private static final int FLOW_TYPE_COMMISSION = 10;
    private static final int FLOW_TYPE_UNFREEZE = 50;
    private static final int FLOW_TYPE_DELIVERY_REWARD = 60;

    @Resource
    private TransactionTemplate transactionTemplate;

    @Resource
    private com.gxwebsoft.shop.service.ShopOrderService shopOrderService;

    @Resource
    private com.gxwebsoft.shop.service.ShopOrderGoodsService shopOrderGoodsService;

    @Resource
    private com.gxwebsoft.shop.service.ShopGoodsService shopGoodsService;

    @Resource
    private ShopDealerCapitalService shopDealerCapitalService;

    @Resource
    private com.gxwebsoft.shop.service.ShopDealerUserService shopDealerUserService;

    @Resource
    private GltUserTicketService gltUserTicketService;

    @Resource
    private GltTicketOrderService gltTicketOrderService;

    @Resource
    private GltTicketTemplateService gltTicketTemplateService;

    @Override
    public PageResult<ShopDealerOrder> pageRel(ShopDealerOrderParam param) {
        PageParam<ShopDealerOrder, ShopDealerOrderParam> page = new PageParam<>(param);
        page.setDefaultOrder("create_time desc");
        List<ShopDealerOrder> list = baseMapper.selectPageRel(page, param);
        return new PageResult<>(list, page.getTotal());
    }

    @Override
    public List<ShopDealerOrder> listRel(ShopDealerOrderParam param) {
        List<ShopDealerOrder> list = baseMapper.selectListRel(param);
        // 排序
        PageParam<ShopDealerOrder, ShopDealerOrderParam> page = new PageParam<>();
        page.setDefaultOrder("create_time desc");
        return page.sortRecords(list);
    }

    @Override
    public ShopDealerOrder getByIdRel(Integer id) {
        ShopDealerOrderParam param = new ShopDealerOrderParam();
        param.setId(id);
        return param.getOne(baseMapper.selectListRel(param));
    }

    // ==================== 手动解冻 ====================

    @Override
    public String manualUnfreeze(String orderNo, Integer tenantId) {
        StringBuilder result = new StringBuilder();
        result.append("【手动解冻】orderNo=").append(orderNo).append(", tenantId=").append(tenantId).append("\n");

        // 1) 查分销订单
        ShopDealerOrder dealerOrder = this.getOne(
            new LambdaQueryWrapper<ShopDealerOrder>()
                .eq(ShopDealerOrder::getTenantId, tenantId)
                .eq(ShopDealerOrder::getOrderNo, orderNo)
                .last("limit 1")
        );
        if (dealerOrder == null) {
            throw new BusinessException("分销订单不存在: " + orderNo);
        }
        result.append("  分销订单ID=").append(dealerOrder.getId())
              .append(", isSettled=").append(dealerOrder.getIsSettled())
              .append(", isUnfreeze=").append(dealerOrder.getIsUnfreeze()).append("\n");

        if (dealerOrder.getIsSettled() == null || dealerOrder.getIsSettled() != 1) {
            throw new BusinessException("订单未结算，无法解冻");
        }
        if (dealerOrder.getIsUnfreeze() != null && dealerOrder.getIsUnfreeze() == 1) {
            throw new BusinessException("订单已解冻，无需重复操作");
        }

        // 2) 查商城订单，判断解冻前置条件
        ShopOrder shopOrder = shopOrderService.getOne(
            new LambdaQueryWrapper<ShopOrder>()
                .eq(ShopOrder::getTenantId, tenantId)
                .eq(ShopOrder::getDeleted, 0)
                .eq(ShopOrder::getOrderNo, orderNo)
                .last("limit 1")
        );
        if (shopOrder == null) {
            throw new BusinessException("商城订单不存在: " + orderNo);
        }
        result.append("  商城订单: payStatus=").append(shopOrder.getPayStatus())
              .append(", orderStatus=").append(shopOrder.getOrderStatus())
              .append(", formId=").append(shopOrder.getFormId()).append("\n");

        // 3) 加载水票模板 goodsId 集合（用于判断是否送水套餐）
        Set<Integer> waterFormIds = gltTicketTemplateService.list(
            new LambdaQueryWrapper<GltTicketTemplate>()
                .eq(GltTicketTemplate::getTenantId, tenantId)
                .eq(GltTicketTemplate::getDeleted, 0)
                .isNotNull(GltTicketTemplate::getGoodsId)
        ).stream()
            .map(GltTicketTemplate::getGoodsId)
            .collect(Collectors.toSet());
        result.append("  水票模板goodsId集合: ").append(waterFormIds).append("\n");

        boolean isWaterOrder = shopOrder.getFormId() != null && waterFormIds.contains(shopOrder.getFormId());
        result.append("  是否送水套餐: ").append(isWaterOrder).append("\n");

        // 4) 检查解冻前置条件
        if (isWaterOrder) {
            // 送水套餐：至少有一条送水订单 deliveryStatus=40（已完成）
            GltUserTicket userTicket = gltUserTicketService.getOne(
                new LambdaQueryWrapper<GltUserTicket>()
                    .eq(GltUserTicket::getTenantId, tenantId)
                    .eq(GltUserTicket::getDeleted, 0)
                    .eq(GltUserTicket::getOrderNo, orderNo)
                    .last("limit 1")
            );
            if (userTicket == null) {
                // 兜底：通过 orderId 反查
                userTicket = gltUserTicketService.getOne(
                    new LambdaQueryWrapper<GltUserTicket>()
                        .eq(GltUserTicket::getTenantId, tenantId)
                        .eq(GltUserTicket::getDeleted, 0)
                        .eq(GltUserTicket::getOrderId, shopOrder.getOrderId())
                        .last("limit 1")
                );
            }
            if (userTicket == null) {
                throw new BusinessException("未找到关联的水票记录，无法确认送水状态");
            }

            GltTicketOrder firstTicketOrder = gltTicketOrderService.getOne(
                new LambdaQueryWrapper<GltTicketOrder>()
                    .eq(GltTicketOrder::getTenantId, tenantId)
                    .eq(GltTicketOrder::getDeleted, 0)
                    .eq(GltTicketOrder::getUserTicketId, userTicket.getId())
                    .orderByAsc(GltTicketOrder::getId)
                    .last("limit 1")
            );

            boolean firstFinished = firstTicketOrder != null
                && firstTicketOrder.getDeliveryStatus() != null
                && firstTicketOrder.getDeliveryStatus() == GltTicketOrderService.DELIVERY_STATUS_FINISHED;

            result.append("  送水订单检查: userTicketId=").append(userTicket.getId())
                  .append(", firstTicketOrderId=").append(firstTicketOrder != null ? firstTicketOrder.getId() : "null")
                  .append(", deliveryStatus=").append(firstTicketOrder != null ? firstTicketOrder.getDeliveryStatus() : "null")
                  .append(", firstFinished=").append(firstFinished).append("\n");

            if (!firstFinished) {
                throw new BusinessException("送水套餐订单尚未完成第一次配送确认收货，不满足解冻条件");
            }
        } else {
            // 非送水套餐：商城订单 orderStatus=1（已确认收货）
            boolean orderCompleted = shopOrder.getOrderStatus() != null
                && shopOrder.getOrderStatus() == ORDER_STATUS_CONFIRMED_RECEIVE
                && shopOrder.getPayStatus() != null
                && shopOrder.getPayStatus();

            result.append("  非送水订单检查: orderStatus=").append(shopOrder.getOrderStatus())
                  .append(", payStatus=").append(shopOrder.getPayStatus())
                  .append(", completed=").append(orderCompleted).append("\n");

            if (!orderCompleted) {
                throw new BusinessException("订单尚未确认收货，不满足解冻条件 (orderStatus=" + shopOrder.getOrderStatus() + ")");
            }
        }

        // 5) 发放配送奖励（幂等）
        result.append("  开始发放配送奖励...\n");
        try {
            boolean rewarded = settleDeliveryRewardIfNeeded(orderNo, tenantId);
            result.append("  配送奖励结果: ").append(rewarded ? "已发放" : "跳过(无配送员/已发放)").append("\n");
        } catch (Exception e) {
            result.append("  配送奖励异常: ").append(e.getMessage()).append("\n");
            log.warn("手动解冻-配送奖励发放失败 - orderNo={}, error={}", orderNo, e.getMessage(), e);
        }

        // 6) 查询该订单的佣金明细（flowType=10）
        List<ShopDealerCapital> capitals = shopDealerCapitalService.list(
            new LambdaQueryWrapper<ShopDealerCapital>()
                .eq(ShopDealerCapital::getTenantId, tenantId)
                .eq(ShopDealerCapital::getFlowType, FLOW_TYPE_COMMISSION)
                .eq(ShopDealerCapital::getOrderNo, orderNo)
        );
        result.append("  佣金明细(flowType=10)数量: ").append(capitals.size()).append("\n");

        if (capitals.isEmpty()) {
            throw new BusinessException("未找到佣金明细(flowType=10)，无法解冻");
        }

        // 7) 逐条执行解冻
        int unfrozen = 0;
        for (ShopDealerCapital cap : capitals) {
            try {
                boolean ok = unfreezeOneCapitalIfNeeded(cap, tenantId);
                if (ok) {
                    unfrozen++;
                    result.append("  解冻成功: capitalId=").append(cap.getId())
                          .append(", userId=").append(cap.getUserId())
                          .append(", amount=").append(cap.getMoney()).append("\n");
                } else {
                    result.append("  解冻跳过(已解冻/幂等): capitalId=").append(cap.getId()).append("\n");
                }
            } catch (Exception e) {
                result.append("  解冻失败: capitalId=").append(cap.getId())
                      .append(", error=").append(e.getMessage()).append("\n");
                log.error("手动解冻-单条佣金解冻失败 - orderNo={}, capitalId={}, error={}", orderNo, cap.getId(), e.getMessage(), e);
            }
        }

        // 8) 检查是否全部解冻完成
        if (unfrozen > 0) {
            long totalCommissions = shopDealerCapitalService.count(
                new LambdaQueryWrapper<ShopDealerCapital>()
                    .eq(ShopDealerCapital::getTenantId, tenantId)
                    .eq(ShopDealerCapital::getFlowType, FLOW_TYPE_COMMISSION)
                    .eq(ShopDealerCapital::getOrderNo, orderNo)
            );
            long unfrozenMarkers = shopDealerCapitalService.count(
                new LambdaQueryWrapper<ShopDealerCapital>()
                    .eq(ShopDealerCapital::getTenantId, tenantId)
                    .eq(ShopDealerCapital::getFlowType, FLOW_TYPE_UNFREEZE)
                    .eq(ShopDealerCapital::getOrderNo, orderNo)
                    .like(ShopDealerCapital::getComments, "佣金解冻(capitalId=")
            );
            result.append("  解冻进度: ").append(unfrozenMarkers).append("/").append(totalCommissions).append("\n");

            if (unfrozenMarkers >= totalCommissions) {
                LocalDateTime now = LocalDateTime.now();
                boolean updated = this.update(
                    new LambdaUpdateWrapper<ShopDealerOrder>()
                        .eq(ShopDealerOrder::getTenantId, tenantId)
                        .eq(ShopDealerOrder::getOrderNo, orderNo)
                        .set(ShopDealerOrder::getIsUnfreeze, 1)
                        .set(ShopDealerOrder::getUnfreezeTime, now)
                        .set(ShopDealerOrder::getUpdateTime, now)
                );
                result.append("  订单解冻状态更新: ").append(updated ? "成功(isUnfreeze=1)" : "失败").append("\n");
            }
        }

        result.append("【手动解冻完成】共解冻 ").append(unfrozen).append("/").append(capitals.size()).append(" 条佣金");
        return result.toString();
    }

    /**
     * 发放配送奖励（从定时任务复制，支持 tenantId 参数）
     */
    private boolean settleDeliveryRewardIfNeeded(String orderNo, Integer tenantId) {
        if (orderNo == null || orderNo.isBlank() || tenantId == null) {
            return false;
        }

        ShopOrder order = shopOrderService.getOne(
            new LambdaQueryWrapper<ShopOrder>()
                .eq(ShopOrder::getTenantId, tenantId)
                .eq(ShopOrder::getDeleted, 0)
                .eq(ShopOrder::getOrderNo, orderNo)
                .last("limit 1")
        );
        if (order == null) return false;

        Integer riderId = order.getRiderId();
        if (riderId == null || riderId <= 0) return false;

        // 幂等检查
        boolean already = shopDealerCapitalService.count(
            new LambdaQueryWrapper<ShopDealerCapital>()
                .eq(ShopDealerCapital::getTenantId, tenantId)
                .eq(ShopDealerCapital::getFlowType, FLOW_TYPE_DELIVERY_REWARD)
                .eq(ShopDealerCapital::getOrderNo, orderNo)
        ) > 0;
        if (already) return false;

        return Boolean.TRUE.equals(transactionTemplate.execute(status -> {
            LocalDateTime now = LocalDateTime.now();

            // 锁定 marker 幂等
            ShopDealerCapital existedMarker = shopDealerCapitalService.getOne(
                new LambdaQueryWrapper<ShopDealerCapital>()
                    .eq(ShopDealerCapital::getTenantId, tenantId)
                    .eq(ShopDealerCapital::getFlowType, FLOW_TYPE_DELIVERY_REWARD)
                    .eq(ShopDealerCapital::getOrderNo, orderNo)
                    .last("limit 1 for update")
            );
            if (existedMarker != null) return false;

            Integer orderId = order.getOrderId();
            if (orderId == null) return false;

            List<ShopOrderGoods> orderGoodsList = shopOrderGoodsService.list(
                new LambdaQueryWrapper<ShopOrderGoods>()
                    .eq(ShopOrderGoods::getTenantId, tenantId)
                    .eq(ShopOrderGoods::getOrderId, orderId)
            );
            if (orderGoodsList == null || orderGoodsList.isEmpty()) return false;

            List<Integer> goodsIds = orderGoodsList.stream()
                .map(ShopOrderGoods::getGoodsId)
                .filter(Objects::nonNull)
                .distinct()
                .toList();
            if (goodsIds.isEmpty()) return false;

            Map<Integer, BigDecimal> goodsDeliveryMoneyMap = shopGoodsService.list(
                new LambdaQueryWrapper<ShopGoods>()
                    .eq(ShopGoods::getTenantId, tenantId)
                    .in(ShopGoods::getGoodsId, goodsIds)
            ).stream().collect(Collectors.toMap(
                ShopGoods::getGoodsId,
                g -> g.getDeliveryMoney() != null ? g.getDeliveryMoney() : BigDecimal.ZERO,
                (a, b) -> a
            ));

            BigDecimal reward = BigDecimal.ZERO;
            for (ShopOrderGoods og : orderGoodsList) {
                Integer goodsId = og.getGoodsId();
                if (goodsId == null) continue;
                int qty = og.getTotalNum() == null ? 0 : og.getTotalNum();
                if (qty <= 0) continue;
                BigDecimal rawRate = goodsDeliveryMoneyMap.getOrDefault(goodsId, BigDecimal.ZERO);
                BigDecimal rate = normalizeDeliveryRate(rawRate);
                if (rate == null || rate.signum() <= 0) continue;
                BigDecimal unitPrice = og.getPrice() != null ? og.getPrice() : BigDecimal.ZERO;
                if (unitPrice.signum() <= 0) continue;
                BigDecimal lineAmount = unitPrice.multiply(BigDecimal.valueOf(qty));
                reward = reward.add(lineAmount.multiply(rate));
            }

            reward = reward.setScale(2, RoundingMode.HALF_UP);
            if (reward.signum() <= 0) return false;

            // 锁定/创建配送员分销账户
            ShopDealerUser dealerUser = shopDealerUserService.getOne(
                new LambdaQueryWrapper<ShopDealerUser>()
                    .eq(ShopDealerUser::getTenantId, tenantId)
                    .eq(ShopDealerUser::getUserId, riderId)
                    .last("limit 1 for update")
            );
            if (dealerUser == null) {
                ShopDealerUser newDealerUser = new ShopDealerUser();
                newDealerUser.setTenantId(tenantId);
                newDealerUser.setUserId(riderId);
                newDealerUser.setType(0);
                newDealerUser.setIsDelete(0);
                newDealerUser.setSortNumber(0);
                newDealerUser.setFirstNum(0);
                newDealerUser.setSecondNum(0);
                newDealerUser.setThirdNum(0);
                newDealerUser.setMoney(BigDecimal.ZERO);
                newDealerUser.setFreezeMoney(BigDecimal.ZERO);
                newDealerUser.setTotalMoney(BigDecimal.ZERO);
                newDealerUser.setCreateTime(now);
                newDealerUser.setUpdateTime(now);
                shopDealerUserService.save(newDealerUser);
                dealerUser = shopDealerUserService.getOne(
                    new LambdaQueryWrapper<ShopDealerUser>()
                        .eq(ShopDealerUser::getTenantId, tenantId)
                        .eq(ShopDealerUser::getUserId, riderId)
                        .last("limit 1 for update")
                );
                if (dealerUser == null) return false;
            }

            BigDecimal moneyVal = dealerUser.getMoney() != null ? dealerUser.getMoney() : BigDecimal.ZERO;
            BigDecimal totalMoneyVal = dealerUser.getTotalMoney() != null ? dealerUser.getTotalMoney() : BigDecimal.ZERO;
            dealerUser.setMoney(moneyVal.add(reward));
            dealerUser.setTotalMoney(totalMoneyVal.add(reward));
            dealerUser.setUpdateTime(now);
            if (!shopDealerUserService.updateById(dealerUser)) return false;

            ShopDealerCapital cap = new ShopDealerCapital();
            cap.setUserId(riderId);
            cap.setOrderNo(orderNo);
            cap.setFlowType(FLOW_TYPE_DELIVERY_REWARD);
            cap.setMoney(reward);
            cap.setComments("配送奖励");
            cap.setToUserId(order.getUserId());
            cap.setMonth(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM")));
            cap.setTenantId(tenantId);
            cap.setCreateTime(now);
            cap.setUpdateTime(now);
            shopDealerCapitalService.save(cap);

            log.info("手动解冻-配送奖励发放成功 - orderNo={}, riderId={}, reward={}", orderNo, riderId, reward);
            return true;
        }));
    }

    /**
     * 解冻单条佣金（从定时任务复制，支持 tenantId 参数）
     */
    private boolean unfreezeOneCapitalIfNeeded(ShopDealerCapital cap, Integer tenantId) {
        if (cap == null) return false;
        Integer capitalId = cap.getId();
        Integer dealerUserId = cap.getUserId();
        String orderNo = cap.getOrderNo();
        BigDecimal amount = cap.getMoney();
        if (capitalId == null || dealerUserId == null || orderNo == null || orderNo.isBlank() || amount == null || amount.signum() <= 0) {
            return false;
        }

        String markerComment = "佣金解冻(capitalId=" + capitalId + ")";

        // 快速幂等检查
        boolean already = shopDealerCapitalService.count(
            new LambdaQueryWrapper<ShopDealerCapital>()
                .eq(ShopDealerCapital::getTenantId, tenantId)
                .eq(ShopDealerCapital::getFlowType, FLOW_TYPE_UNFREEZE)
                .eq(ShopDealerCapital::getUserId, dealerUserId)
                .eq(ShopDealerCapital::getOrderNo, orderNo)
                .eq(ShopDealerCapital::getComments, markerComment)
        ) > 0;
        if (already) return false;

        return Boolean.TRUE.equals(transactionTemplate.execute(status -> {
            LocalDateTime now = LocalDateTime.now();

            ShopDealerUser dealerUser = shopDealerUserService.getOne(
                new LambdaQueryWrapper<ShopDealerUser>()
                    .eq(ShopDealerUser::getTenantId, tenantId)
                    .eq(ShopDealerUser::getUserId, dealerUserId)
                    .last("limit 1 for update")
            );
            if (dealerUser == null) {
                log.warn("手动解冻失败：未找到分销账户 - orderNo={}, dealerUserId={}, amount={}", orderNo, dealerUserId, amount);
                return false;
            }

            // 二次幂等检查
            ShopDealerCapital existedMarker = shopDealerCapitalService.getOne(
                new LambdaQueryWrapper<ShopDealerCapital>()
                    .eq(ShopDealerCapital::getTenantId, tenantId)
                    .eq(ShopDealerCapital::getFlowType, FLOW_TYPE_UNFREEZE)
                    .eq(ShopDealerCapital::getUserId, dealerUserId)
                    .eq(ShopDealerCapital::getOrderNo, orderNo)
                    .eq(ShopDealerCapital::getComments, markerComment)
                    .last("limit 1 for update")
            );
            if (existedMarker != null) return false;

            BigDecimal freezeMoney = dealerUser.getFreezeMoney() != null ? dealerUser.getFreezeMoney() : BigDecimal.ZERO;
            if (freezeMoney.compareTo(amount) < 0) {
                log.warn("手动解冻失败：冻结金额不足 - orderNo={}, dealerUserId={}, freezeMoney={}, amount={}",
                    orderNo, dealerUserId, freezeMoney, amount);
                return false;
            }

            BigDecimal moneyVal = dealerUser.getMoney() != null ? dealerUser.getMoney() : BigDecimal.ZERO;
            dealerUser.setFreezeMoney(freezeMoney.subtract(amount));
            dealerUser.setMoney(moneyVal.add(amount));
            dealerUser.setUpdateTime(now);
            if (!shopDealerUserService.updateById(dealerUser)) {
                log.warn("手动解冻失败：更新分销账户失败 - orderNo={}, dealerUserId={}, amount={}", orderNo, dealerUserId, amount);
                return false;
            }

            ShopDealerCapital marker = new ShopDealerCapital();
            marker.setUserId(dealerUserId);
            marker.setOrderNo(orderNo);
            marker.setFlowType(FLOW_TYPE_UNFREEZE);
            marker.setMoney(amount);
            marker.setComments(markerComment);
            marker.setToUserId(cap.getToUserId());
            marker.setMonth(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM")));
            marker.setTenantId(tenantId);
            marker.setCreateTime(now);
            marker.setUpdateTime(now);
            shopDealerCapitalService.save(marker);

            log.info("手动解冻成功 - orderNo={}, dealerUserId={}, amount={}, capitalId={}", orderNo, dealerUserId, amount, capitalId);
            return true;
        }));
    }

    private static BigDecimal normalizeDeliveryRate(BigDecimal rawRate) {
        if (rawRate == null || rawRate.signum() <= 0) return null;
        if (rawRate.compareTo(BigDecimal.ONE) >= 0) return rawRate.movePointLeft(2);
        return rawRate;
    }

}
