package com.market.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
 * 深度数据价格聚合工具类
 *
 * @author system
 * @date 2026-05-07
 */
public final class DepthPriceUtil {

    private static final Logger log = LoggerFactory.getLogger(DepthPriceUtil.class);

    private DepthPriceUtil() {}

    /**
     * 根据精度聚合价格（用于订单簿分档展示）
     * <p>
     * 将相同精度归类的价格合并，累加对应数量。
     * 例如 precision=2 时，88.123 和 88.156 均归类到 88.12。
     *
     * @param data         原始深度数据 [[price, amount], ...]
     * @param decimalPlaces 保留小数位数
     * @param limit        返回最大条数，0 表示不限
     * @return 聚合后的数据
     */
    public static List<List<String>> accumulateByPrice(List<List<String>> data,
                                                       int decimalPlaces,
                                                       int limit) {
        if (data == null || data.isEmpty()) {
            return data;
        }
        try {
            Map<String, BigDecimal> priceMap = new LinkedHashMap<>();
            for (List<String> item : data) {
                BigDecimal price = new BigDecimal(item.get(0));
                BigDecimal quantity = new BigDecimal(item.get(1));
                String priceKey = price.setScale(decimalPlaces, RoundingMode.DOWN).toPlainString();
                priceMap.merge(priceKey, quantity, BigDecimal::add);
            }
            List<List<String>> result = new ArrayList<>();
            for (Map.Entry<String, BigDecimal> entry : priceMap.entrySet()) {
                result.add(Arrays.asList(entry.getKey(), entry.getValue().toPlainString()));
            }
            if (limit > 0 && limit < result.size()) {
                result = result.subList(0, limit);
            }
            return result;
        } catch (Exception e) {
            log.error("按价格聚合失败: decimalPlaces={}, limit={}", decimalPlaces, limit, e);
            return (limit > 0 && limit < data.size()) ? data.subList(0, limit) : data;
        }
    }

    /**
     * 按价格排序
     *
     * @param data  深度数据
     * @param isAsk true=卖盘升序，false=买盘降序
     * @return 排序后的数据
     */
    public static List<List<String>> sortByPrice(List<List<String>> data, boolean isAsk) {
        if (data == null || data.size() <= 1) {
            return data;
        }
        try {
            return data.stream()
                    .sorted((a, b) -> {
                        BigDecimal pa = new BigDecimal(a.get(0));
                        BigDecimal pb = new BigDecimal(b.get(0));
                        return isAsk ? pa.compareTo(pb) : pb.compareTo(pa);
                    })
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("按价格排序失败", e);
            return data;
        }
    }
}
