package com.yhy.module.core.service.workbench;

import com.yhy.module.core.controller.admin.quota.vo.QuotaFeeItemWithRateRespVO;
import com.yhy.module.core.controller.admin.workbench.vo.price.CategoryPriceSum;
import com.yhy.module.core.controller.admin.workbench.vo.price.FeeItemPriceResult;
import com.yhy.module.core.controller.admin.workbench.vo.price.QuotaUnitPriceResult;
import com.yhy.module.core.controller.admin.workbench.vo.price.ResourcePriceDetail;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 定额单价计算服务
 * 
 * 设计原则：
 * 1. 复用后台已有的工料机合价计算逻辑
 * 2. 新增分类汇总和取费计算逻辑
 * 3. 工作台和后台共用此服务
 * 4. 支持分层验证和调试
 * 
 * @author yhy
 */
public interface QuotaPriceCalculatorService {

    // ========== 主计算接口 ==========

    /**
     * 计算定额单价（简洁版，仅返回最终结果）
     * 
     * @param quotaItemId 定额基价ID（后台用）
     * @param divisionId 分部分项定额节点ID（工作台用，可选）
     * @return 定额单价计算结果
     */
    QuotaUnitPriceResult calculateQuotaUnitPrice(Long quotaItemId, Long divisionId);

    /**
     * 计算定额单价（调试版，返回完整计算过程）
     * 
     * @param quotaItemId 定额基价ID
     * @param divisionId 分部分项定额节点ID
     * @param debug 是否返回调试信息
     * @return 定额单价计算结果（含调试信息）
     */
    QuotaUnitPriceResult calculateQuotaUnitPrice(Long quotaItemId, Long divisionId, boolean debug);

    /**
     * 批量计算定额单价
     * 
     * @param divisionIds 分部分项定额节点ID列表
     * @return 定额单价计算结果Map，key=divisionId
     */
    Map<Long, QuotaUnitPriceResult> batchCalculateQuotaUnitPrices(List<Long> divisionIds);

    // ========== 分层验证接口（单独测试每一层） ==========

    /**
     * 【第3层】按机类分类汇总
     * 
     * @param resourceDetails 工料机价格明细列表
     * @return 分类汇总Map，key=categoryId
     */
    Map<Long, CategoryPriceSum> calculateCategorySums(List<ResourcePriceDetail> resourceDetails);

    /**
     * 【第4层】解析计算基数公式
     * 
     * @param calcBase 计算基数配置
     * @param categorySums 分类汇总
     * @return 公式计算结果
     */
    BigDecimal evaluateCalcBaseFormula(Map<String, Object> calcBase, Map<Long, CategoryPriceSum> categorySums);

    /**
     * 【第5层】计算单个取费项的子单价
     * 
     * @param feeItem 取费项（含计算基数）
     * @param categorySums 分类汇总
     * @return 子单价计算结果
     */
    FeeItemPriceResult calculateFeeItemPrice(QuotaFeeItemWithRateRespVO feeItem, Map<Long, CategoryPriceSum> categorySums);

    /**
     * 【第5层】批量计算取费项的子单价
     * 
     * @param feeItems 取费项列表
     * @param categorySums 分类汇总
     * @return 子单价计算结果列表
     */
    List<FeeItemPriceResult> calculateFeeItemPrices(List<QuotaFeeItemWithRateRespVO> feeItems, Map<Long, CategoryPriceSum> categorySums);

    /**
     * 【第6层】计算综合单价（定额单价）
     * 
     * @param feeItemResults 取费项计算结果列表
     * @return 综合单价
     */
    BigDecimal calculateTotalPrice(List<FeeItemPriceResult> feeItemResults);

    // ========== 统一取费父定额单价计算 ==========

    /**
     * 计算统一取费父定额的单价
     * 
     * 计算流程：
     * 1. 获取母定额列表（汇总来源的quota节点）
     * 2. 对每个母定额：
     *    a. 获取母定额的工料机分类合价（CategoryPriceSum）
     *    b. 获取统一取费单价的取费项配置
     *    c. 用母定额的分类合价替换取费项的calcBase变量
     *    d. 计算子定额的综合单价B
     *    e. B × 母定额的工程量 = 该母定额贡献的单价
     * 3. 父定额单价C = SUM(各母定额贡献的单价)
     * 
     * @param divisionId 统一取费节点ID（nodeType='unified_fee'）
     * @return 父定额单价
     */
    BigDecimal calculateUnifiedFeeParentPrice(Long divisionId);

    /**
     * 计算统一取费父定额的单价（调试版）
     * 
     * @param divisionId 统一取费节点ID
     * @param debug 是否返回调试信息
     * @return 父定额单价计算结果（含调试信息）
     */
    QuotaUnitPriceResult calculateUnifiedFeeParentPrice(Long divisionId, boolean debug);

    /**
     * 获取统一取费节点的分类合价（用于基数范围汇总）
     * 
     * 计算逻辑：
     * 1. 获取母定额列表（通过 motherQuotaIds）
     * 2. 对每个母定额获取工料机分类合价（CategoryPriceSum）
     * 3. 遍历子费用的子目工料机：
     *    - %工料机：用 calcBase 公式引用母定额分类合价计算实际合价
     *    - 普通工料机：用单价 × 消耗量
     * 4. 按工料机的 categoryId 汇总四个合价字段
     * 
     * @param divisionId 统一取费节点ID（nodeType='unified_fee'）
     * @return 分类合价Map，key=categoryId；如果节点无效或无数据返回空Map
     */
    Map<Long, CategoryPriceSum> getUnifiedFeeCategorySums(Long divisionId);

    // ========== 未来快照功能预留 ==========

    // /**
    //  * 创建定额单价快照
    //  * @param divisionId 定额节点ID
    //  * @return 快照数据（JSON格式）
    //  */
    // Map<String, Object> createPriceSnapshot(Long divisionId);

    // /**
    //  * 基于快照计算定额单价（用于历史版本查看）
    //  * @param snapshotJson 快照数据
    //  * @return 定额单价计算结果
    //  */
    // QuotaUnitPriceResult calculateFromSnapshot(Map<String, Object> snapshotJson);

    // /**
    //  * 对比当前值与快照值
    //  * @param divisionId 定额节点ID
    //  * @return 差异列表
    //  */
    // List<PriceDiffItem> compareWithSnapshot(Long divisionId);
}
