import { BigNumber } from "bignumber.js";

// 配置BigNumber精度
BigNumber.set({
  DECIMAL_PLACES: 2,
  ROUNDING_MODE: BigNumber.ROUND_DOWN, // 向下取整，符合业务需求
});

/**
 * 购物车订单价格计算公共库
 * 功能：覆盖订单全链路费用计算（商品价格、优惠券、积分、餐位费等），支持策略扩展
 * 小数处理：使用bignumber.js确保精度，统一舍去小数点后两位（如 10.129 → 10.12，15.998 → 15.99）
 * 扩展设计：优惠券/营销活动采用策略模式，新增类型仅需扩展策略，无需修改核心逻辑
 * 关键规则：
 * - 所有优惠券均支持指定门槛商品（后端foods字段：空字符串=全部商品，ID字符串=指定商品ID）
 * - 与限时折扣/会员价同享规则：开启则门槛计算含对应折扣，关闭则用原价/非会员价
 * 字段说明：
 * - BaseCartItem.id：购物车项ID（唯一标识购物车中的条目）
 * - BaseCartItem.product_id：商品ID（唯一标识商品，用于优惠券/活动匹配）
 * - BaseCartItem.skuData.id：SKU ID（唯一标识商品规格）
 */

// ============================ 1. 基础类型定义（核心修正：明确ID含义） ============================
/** 商品类型枚举 */
export enum GoodsType {
  NORMAL = "normal", // 普通商品
  WEIGHT = "weight", // 称重商品
  GIFT = "gift", // 赠菜（继承普通商品逻辑，标记用）
  EMPTY = "", // 空字符串类型（后端未返回时默认归类为普通商品）
  PACKAGE = "package", // 打包商品（如套餐/预打包商品，按普通商品逻辑处理，可扩展特殊规则）
}

/** 优惠券计算结果类型（新增细分字段） */
interface CouponResult {
  deductionAmount: number; // 抵扣金额
  excludedProductIds: string[]; // 不适用商品ID列表（注意：是商品ID，非购物车ID）
  usedCoupon: Coupon | undefined; // 实际使用的优惠券
  productCouponDeduction: number; // 新增：商品优惠券抵扣（兑换券等）
  fullCouponDeduction: number; // 新增：满减优惠券抵扣
}

/** 兑换券计算结果类型（新增细分字段） */
interface ExchangeCalculationResult {
  deductionAmount: number;
  excludedProductIds: string[]; // 不适用商品ID列表（商品ID）
  productCouponDeduction: number; // 新增：兑换券属于商品券，同步记录
}

/** 优惠券类型枚举 */
export enum CouponType {
  FULL_REDUCTION = "full_reduction", // 满减券
  DISCOUNT = "discount", // 折扣券
  SECOND_HALF = "second_half", // 第二件半价券
  BUY_ONE_GET_ONE = "buy_one_get_one", // 买一送一券
  EXCHANGE = "exchange", // 商品兑换券
}

/** 后端返回的优惠券原始字段类型 */
export interface BackendCoupon {
  id?: number; // 自增主键（int64）
  shopId?: number; // 店铺ID（int64）
  syncId?: number; // 同步Id（int64）
  type?: number; // 优惠券类型：1-满减券，2-商品兑换券，3-折扣券，4-第二件半价券，5-消费送券，6-买一送一券，7-固定价格券，8-免配送费券
  name?: string; // 券名称
  useShopType?: string; // 可用门店类型：only-仅本店；all-所有门店，custom-指定门店
  useShops?: string; // 可用门店（逗号分隔字符串，如"1,2,3"）
  useType?: string; // 可使用类型：dine堂食/pickup自取/deliv配送/express快递
  validType?: string; // 有效期类型：fixed（固定时间），custom（自定义时间）
  validDays?: number; // 有效期(天)
  validStartTime?: string; // 有效期开始时间（如"2024-01-01 00:00:00"）
  validEndTime?: string; // 有效期结束时间
  daysToTakeEffect?: number; // 隔天生效
  useDays?: string; // 可用周期（如"周一,周二"）
  useTimeType?: string; // 可用时间段类型：all-全时段，custom-指定时段
  useStartTime?: string; // 可用开始时间（每日）
  useEndTime?: string; // 可用结束时间（每日）
  getType?: string; // 发放设置：不可自行领取/no，可领取/yes
  getMode?: string; // 用户领取方式
  giveNum?: number; // 总发放数量，-10086为不限量
  getUserType?: string; // 可领取用户：全部/all，新用户一次/new，仅会员/vip
  getLimit?: number; // 每人领取限量，-10086为不限量
  useLimit?: number; // 每人每日使用限量，-10086为不限量
  discountShare?: number; // 与限时折扣同享：0-否，1-是
  vipPriceShare?: number; // 与会员价同享：0-否，1-是
  ruleDetails?: string; // 附加规则说明
  status?: number; // 状态：0-禁用，1-启用
  useNum?: number; // 已使用数量
  leftNum?: number; // 剩余数量
  foods?: string; // 指定门槛商品（逗号分隔字符串，如"101,102"，此处为商品ID）
  fullAmount?: number; // 使用门槛：满多少金额（元）
  discountAmount?: number; // 使用门槛：减多少金额（元）
  discountRate?: number; // 折扣%（如90=9折）
  maxDiscountAmount?: number; // 可抵扣最大金额（元）
  useRule?: string; // 使用规则：price_asc-价格低到高，price_desc-高到低
  discountNum?: number; // 抵扣数量
  otherCouponShare?: number; // 与其它优惠共享：0-否，1-是
  createTime?: string; // 创建时间
  updateTime?: string; // 更新时间
}

/** 营销活动类型枚举 */
export enum ActivityType {
  TIME_LIMIT_DISCOUNT = "time_limit_discount", // 限时折扣
}

/** 基础购物车商品项（核心修正：新增product_id，明确各ID含义） */
export interface BaseCartItem {
  id: string | number; // 购物车ID（唯一标识购物车中的条目，如购物车项主键）
  product_id: string | number; // 商品ID（唯一标识商品，用于优惠券/活动匹配，必选）
  salePrice: number; // 商品原价（元）
  number: number; // 商品数量
  product_type: GoodsType; // 商品类型
  is_temporary?: boolean; // 是否临时菜（默认false）
  is_gift?: boolean; // 是否赠菜（默认false）
  returnNum?: number; // 退货数量（历史订单用，默认0）
  memberPrice?: number; // 商品会员价（元，优先级：商品会员价 > 会员折扣）
  discountSaleAmount?: number; // 商家改价后单价（元，优先级最高）
  packFee?: number; // 单份打包费（元，默认0）
  packNumber?: number; // 堂食打包数量（默认0）
  activityInfo?: {
    // 商品参与的营销活动（如限时折扣）
    type: ActivityType;
    discountRate: number; // 折扣率（如0.8=8折）
    vipPriceShare: boolean; // 是否与会员优惠同享（默认false）
  };
  skuData?: {
    // SKU扩展数据（可选）
    id: string | number; // SKU ID（唯一标识商品规格，如颜色/尺寸）
    memberPrice?: number; // SKU会员价
    salePrice?: number; // SKU原价
  };
}

/** 基础优惠券接口（所有券类型继承，包含统一门槛商品字段） */
export interface BaseCoupon {
  id: string | number; // 优惠券ID
  type: CouponType; // 工具库字符串枚举（由后端couponType转换）
  name: string; // 对应后端title
  available: boolean; // 基于BackendCoupon字段计算的可用性
  useShopType?: string; // only-仅本店；all-所有门店，custom-指定门店
  useShops: string[]; // 可用门店ID列表
  discountShare: boolean; // 与限时折扣同享：0-否，1-是（后端字段转换为布尔值）
  vipPriceShare: boolean; // 与会员价同享：0-否，1-是（后端字段转换为布尔值）
  useType?: string[]; // 可使用类型：dine堂食/pickup自取/deliv配送/express快递
  isValid: boolean; // 是否在有效期内
  discountAmount?: number; // 减免金额 (满减券有)
  fullAmount?: number; // 使用门槛：满多少金额
  maxDiscountAmount?: number; // 可抵扣最大金额 元
  applicableProductIds: string[]; // 门槛商品ID列表（空数组=全部商品，非空=指定商品ID）
}

/** 满减券（适配后端字段） */
export interface FullReductionCoupon extends BaseCoupon {
  type: CouponType.FULL_REDUCTION;
  fullAmount: number; // 对应后端fullAmount（满减门槛）
  discountAmount: number; // 对应后端discountAmount（减免金额）
  maxDiscountAmount?: number; // 对应后端maxDiscountAmount（最大减免）
}

/** 折扣券（适配后端字段） */
export interface DiscountCoupon extends BaseCoupon {
  type: CouponType.DISCOUNT;
  discountRate: number; // 后端discountRate（%）转小数（如90→0.9）
  maxDiscountAmount: number; // 对应后端maxDiscountAmount（最大减免）
}

/** 第二件半价券（适配后端字段） */
export interface SecondHalfPriceCoupon extends BaseCoupon {
  type: CouponType.SECOND_HALF;
  maxUseCountPerOrder?: number; // 对应后端useLimit（-10086=不限）
}

/** 买一送一券（适配后端字段） */
export interface BuyOneGetOneCoupon extends BaseCoupon {
  type: CouponType.BUY_ONE_GET_ONE;
  maxUseCountPerOrder?: number; // 对应后端useLimit（-10086=不限）
}

/** 商品兑换券（适配后端字段） */
export interface ExchangeCoupon extends BaseCoupon {
  type: CouponType.EXCHANGE;
  deductCount: number; // 对应后端discountNum（抵扣数量）
  sortRule: "low_price_first" | "high_price_first"; // 后端useRule转换
}

/** 所有优惠券类型联合 */
export type Coupon =
  | FullReductionCoupon
  | DiscountCoupon
  | SecondHalfPriceCoupon
  | BuyOneGetOneCoupon
  | ExchangeCoupon;

/** 营销活动配置（如限时折扣，applicableProductIds为商品ID列表） */
export interface ActivityConfig {
  type: ActivityType;
  applicableProductIds?: string[]; // 适用商品ID列表（与BaseCartItem.product_id匹配）
  discountRate: number; // 折扣率（如0.8=8折）
  vipPriceShare: boolean; // 是否与会员优惠同享
}

/** 积分抵扣规则 */
export interface PointDeductionRule {
  pointsPerYuan: number; // X积分=1元（如100=100积分抵1元）
  maxDeductionAmount?: number; // 最大抵扣金额（元，默认不限）
}

/** 餐位费配置 */
export interface SeatFeeConfig {
  pricePerPerson: number; // 每人餐位费（元）
  personCount: number; // 用餐人数（默认1）
  isEnabled: boolean; // 是否启用餐位费（默认false）
}
/** 商家减免类型枚举 */
export enum MerchantReductionType {
  FIXED_AMOUNT = "fixed_amount", // 固定金额减免（如直接减 10 元）
  DISCOUNT_RATE = "discount_rate", // 比例折扣减免（如打 9 折，即减免 10%）
}

/** 商家减免配置（新增，替代原单一金额字段） */
export interface MerchantReductionConfig {
  type: MerchantReductionType; // 减免类型（二选一）
  fixedAmount?: number; // 固定减免金额（元，仅 FIXED_AMOUNT 生效，≥0）
  discountRate?: number; // 折扣率（%，仅 DISCOUNT_RATE 生效，0-100，如 90 代表 9 折）
}
/** 订单额外费用配置 */
export interface OrderExtraConfig {
  // merchantReduction: number;        // 商家减免金额（元，默认0）
  // 替换原单一金额字段，支持两种减免形式
  merchantReduction: MerchantReductionConfig;
  additionalFee: number; // 附加费（元，如余额充值、券包，默认0）
  pointDeductionRule: PointDeductionRule; // 积分抵扣规则
  seatFeeConfig: SeatFeeConfig; // 餐位费配置
  currentStoreId: string; // 当前门店ID（用于验证优惠券适用门店）
  userPoints: number; // 用户当前积分（用于积分抵扣）
  isMember: boolean; // 用户是否会员（用于会员优惠）
  memberDiscountRate?: number; // 会员折扣率（如0.95=95折，无会员价时用）
  newUserDiscount?: number; // 新用户减免金额（元，默认0）
}

/** 订单费用汇总（修改：补充商家减免类型和明细） */
export interface OrderCostSummary {
  // 商品总件数
  goodsTotal: number;
  totalDiscountAmount: number,
  goodsRealAmount: number; // 商品真实原价总和
  goodsOriginalAmount: number; // 商品原价总和
  goodsDiscountAmount: number; // 商品折扣金额
  couponDeductionAmount: number; // 优惠券总抵扣
  productCouponDeduction: number; // 商品优惠券抵扣
  fullCouponDeduction: number; // 满减优惠券抵扣
  pointDeductionAmount: number; // 积分抵扣金额
  seatFee: number; // 餐位费
  packFee: number; // 打包费
  // 新增：商家减免明细
  merchantReduction: {
    type: MerchantReductionType; // 实际使用的减免类型
    originalConfig: MerchantReductionConfig; // 原始配置（便于前端展示）
    actualAmount: number; // 实际减免金额（计算后的值，≥0）
  };
  additionalFee: number; // 附加费
  finalPayAmount: number; // 最终实付金额
  couponUsed?: Coupon; // 实际使用的优惠券
  pointUsed: number; // 实际使用的积分
  newUserDiscount: number; // 新用户减免金额（元，默认0）
  dinnerType?: "dine-in" | "take-out"; // 就餐类型（堂食/自取/配送/快递）
  config: OrderExtraConfig; // 订单额外费用配置
  //满减活动
  fullReduction: {
    usedActivity?: FullReductionActivity; // 实际使用的满减活动
    usedThreshold?: FullReductionThreshold; // 实际使用的满减阈值（多门槛中选最优）
    actualAmount: number; // 满减实际减免金额（元）
  };
}


/** 满减活动阈值（单条满减规则：满X减Y）- 对应 MkDiscountThresholdInsertGroupDefaultGroup */
export interface FullReductionThreshold {
  activityId?: number; // 关联满减活动ID
  fullAmount?: number; // 满多少金额（元，必填）
  discountAmount?: number; // 减多少金额（元，必填）
}

/** 满减活动主表 - 对应 Request 接口（后端真实字段） */
export interface FullReductionActivity {
  id?: number; // 自增主键（后端字段：id）
  shopId?: number; // 店铺ID（后端字段：shopId）
  status?: number; // 活动状态：1=未开始，2=进行中，3=已结束（后端字段：status）
  sort?: number; // 排序值（越大优先级越高，后端字段：sort）
  createTime?: string; // 创建时间（后端字段：createTime，格式如"2025-10-14 13:56:07"）
  updateTime?: string; // 最新修改时间（后端字段：updateTime，用于优先级排序）
  validStartTime?: string; // 有效期开始时间（后端字段：validStartTime，格式如"2025-10-14"）
  validEndTime?: string; // 有效期结束时间（后端字段：validEndTime，格式如"2025-12-14"）
  useType?: string; // 可使用类型（后端字段：useType，如"dine,pickup,deliv,express"）
  useDays?: string; // 可用周期（后端字段：useDays，如"周一,周二,周三,周四,周五,周六,周日"）
  useTimeType?: string; // 可用时间段类型（后端字段：useTimeType，all=全时段，custom=指定时段）
  useStartTime?: string; // 每日可用开始时间（后端字段：useStartTime，如"09:00:00"，仅custom时有效）
  useEndTime?: string; // 每日可用结束时间（后端字段：useEndTime，如"22:00:00"，仅custom时有效）
  couponShare?: number; // 与优惠券同享：0=否，1=是（后端字段：couponShare）
  discountShare?: number; // 与限时折扣同享：0=否，1=是（后端字段：discountShare）
  vipPriceShare?: number; // 与会员价同享：0=否，1=是（后端字段：vipPriceShare）
  pointsShare?: number; // 与积分抵扣同享：0=否，1=是（后端字段：pointsShare）
  thresholds?: FullReductionThreshold[]; // 满减阈值列表（多门槛，后端字段：thresholds）
  isDel?: boolean; // 是否删除：0=否，1=是（后端字段：isDel，默认false）
}

// ============================ 扩展：订单配置与费用汇总（加入后端满减类型） ============================
/** 扩展订单额外配置：使用后端满减活动类型 */
export interface OrderExtraConfig {
  // ... 原有字段不变 ...
  fullReductionActivities: FullReductionActivity[]; // 当前店铺的满减活动列表（后端返回结构）
  currentDinnerType: "dine" | "pickup" | "deliv" | "express"; // 当前就餐类型（匹配useType）
}



// 辅助枚举：星期映射（用于useDays校验）
const WEEKDAY_MAP = {
  "周一": 1,
  "周二": 2,
  "周三": 3,
  "周四": 4,
  "周五": 5,
  "周六": 6,
  "周日": 0 // JS中getDay()返回0=周日
};

/**
 * 辅助：校验当前时间是否在活动的「每日可用时段」内
 * @param activity 满减活动
 * @param currentTime 当前时间
 * @returns 是否在时段内
 */
function isInDailyTimeRange(activity: FullReductionActivity, currentTime: Date): boolean {
  // 全时段无需校验
  if (activity.useTimeType === "all") return true;
  // 无时段配置则不通过
  if (!activity.useStartTime || !activity.useEndTime) return false;

  const [startHour, startMinute] = activity.useStartTime.split(":").map(Number);
  const [endHour, endMinute] = activity.useEndTime.split(":").map(Number);
  const currentHour = currentTime.getHours();
  const currentMinute = currentTime.getMinutes();

  // 转换为分钟数比较
  const startTotalMin = startHour * 60 + startMinute;
  const endTotalMin = endHour * 60 + endMinute;
  const currentTotalMin = currentHour * 60 + currentMinute;

  // 处理跨天场景（如23:00-02:00）
  if (startTotalMin <= endTotalMin) {
    return currentTotalMin >= startTotalMin && currentTotalMin <= endTotalMin;
  } else {
    return currentTotalMin >= startTotalMin || currentTotalMin <= endTotalMin;
  }
}

/**
 * 辅助：校验当前时间是否在活动的「可用周期」内（如周一至周日）
 * @param activity 满减活动
 * @param currentTime 当前时间
 * @returns 是否在周期内
 */
function isInWeeklyCycle(activity: FullReductionActivity, currentTime: Date): boolean {
  // 无周期配置则不通过
  if (!activity.useDays) return false;
  const currentWeekday = currentTime.getDay(); // 0=周日，1=周一...6=周六
  const allowedWeekdays = activity.useDays.split(",").map(day => WEEKDAY_MAP[day as keyof typeof WEEKDAY_MAP]);
  return allowedWeekdays.includes(currentWeekday);
}

/**
 * 辅助：校验当前就餐类型是否在活动的「可用类型」内（如堂食/自取）
 * @param activity 满减活动
 * @param currentDinnerType 当前就餐类型
 * @returns 是否匹配
 */
function isDinnerTypeMatch(activity: FullReductionActivity, currentDinnerType: string): boolean {
  if (!activity.useType) return false;
  const allowedTypes = activity.useType.split(",");
  return allowedTypes.includes(currentDinnerType);
}
/**
 * 筛选最优满减活动（对齐后端逻辑：状态→时间→周期→时段→就餐类型→排序→修改时间）
 * @param activities 后端返回的满减活动列表
 * @param currentShopId 当前店铺ID
 * @param currentDinnerType 当前就餐类型（dine/pickup等）
 * @param currentTime 当前时间（默认当前时间）
 * @returns 最优满减活动（无符合条件则返回undefined）
 */
export function filterOptimalFullReductionActivity(
  activities: FullReductionActivity[],
  currentShopId: number,
  currentDinnerType: string,
  currentTime: Date = new Date()
): FullReductionActivity | undefined {
  if (!activities.length) return undefined;

  // 第一步：基础筛选（未删除+当前店铺+活动进行中+就餐类型匹配）
  const baseEligible = activities.filter(activity => {
    return (
      activity.isDel !== true && // 未删除
      activity.shopId === currentShopId && // 当前店铺
      activity.status === 2 && // 状态=2（进行中）
      isDinnerTypeMatch(activity, currentDinnerType) && // 就餐类型匹配
      activity.thresholds?.length // 至少有一个满减阈值
    );
  });

  if (!baseEligible.length) return undefined;

  // 第二步：时间筛选（有效期内+周期内+时段内）
  const timeEligible = baseEligible.filter(activity => {
    // 1. 校验有效期（validStartTime ~ validEndTime）
    if (!activity.validStartTime || !activity.validEndTime) return false;
    const startDate = new Date(activity.validStartTime);
    const endDate = new Date(activity.validEndTime);
    // 处理有效期结束日期的23:59:59
    endDate.setHours(23, 59, 59, 999);
    if (currentTime < startDate || currentTime > endDate) return false;

    // 2. 校验可用周期（如周一至周日）
    if (!isInWeeklyCycle(activity, currentTime)) return false;

    // 3. 校验每日可用时段（如09:00-22:00）
    if (!isInDailyTimeRange(activity, currentTime)) return false;

    return true;
  });

  if (!timeEligible.length) return undefined;

  // 第三步：按优先级排序（需求规则）
  return timeEligible.sort((a, b) => {
    // 1. 先比排序值：排序值大的优先
    if ((a.sort || 0) !== (b.sort || 0)) {
      return (b.sort || 0) - (a.sort || 0);
    }
    // 2. 再比修改时间：最新修改的优先（时间戳降序）
    const aUpdateTime = a.updateTime ? new Date(a.updateTime).getTime() : 0;
    const bUpdateTime = b.updateTime ? new Date(b.updateTime).getTime() : 0;
    return bUpdateTime - aUpdateTime;
  })[0]; // 取最优活动
}
/**
 * 折扣率格式化：后端discountRate（%）→ 工具库小数（如90→0.9）
 */
export function formatDiscountRate(backendDiscountRate?: number): number {
  if (!backendDiscountRate || backendDiscountRate <= 0) return 1; // 默认无折扣（1=100%）
  // 后端若为百分比（如90=9折），除以100；若已为小数（如0.9）直接返回
  return backendDiscountRate >= 1
    ? backendDiscountRate / 100
    : backendDiscountRate;
}

/**
 * 统一小数处理：舍去小数点后两位以后的数字（解决浮点数精度偏差）
 * 如 10.129 → 10.12，1.01 → 1.01，1.0100000001 → 1.01
 * @param num 待处理数字
 * @returns 处理后保留两位小数的数字
 */
export function truncateToTwoDecimals(num: number | string): number {
  return new BigNumber(num).decimalPlaces(2, BigNumber.ROUND_DOWN).toNumber();
}

/**
 * 判断商品是否为临时菜（临时菜不参与优惠券门槛和折扣计算）
 * @param goods 商品项
 * @returns 是否临时菜
 */
export function isTemporaryGoods(goods: BaseCartItem): boolean {
  return !!goods.is_temporary;
}

/**
 * 判断商品是否为赠菜（赠菜不计入优惠券活动，但计打包费）
 * @param goods 商品项
 * @returns 是否赠菜
 */
export function isGiftGoods(goods: BaseCartItem): boolean {
  return !!goods.is_gift;
}

/**
 * 计算单个商品的会员价（优先级：SKU会员价 > 商品会员价 > 会员折扣率）
 * @param goods 商品项
 * @param isMember 是否会员
 * @param memberDiscountRate 会员折扣率（如0.95=95折）
 * @returns 会员价（元）
 */
export function calcMemberPrice(
  goods: BaseCartItem,
  isMember: boolean,
  memberDiscountRate?: number
): number {
  if (!isMember) return truncateToTwoDecimals(goods.salePrice);

  // 优先级：SKU会员价 > 商品会员价 > 商品原价（无会员价时用会员折扣）
  const basePrice =
    goods.skuData?.memberPrice ?? goods.memberPrice ?? goods.salePrice;

  // 仅当无SKU会员价、无商品会员价时，才应用会员折扣率
  if (memberDiscountRate && !goods.skuData?.memberPrice && !goods.memberPrice) {
    return truncateToTwoDecimals(
      new BigNumber(basePrice).multipliedBy(memberDiscountRate).toNumber()
    );
  }

  return truncateToTwoDecimals(basePrice);
}

/**
 * 过滤可参与优惠券计算的商品（排除临时菜、赠菜、已用兑换券的商品）
 * @param goodsList 商品列表
 * @param excludedProductIds 需排除的商品ID列表（商品ID，非购物车ID）
 * @returns 可参与优惠券计算的商品列表
 */
export function filterCouponEligibleGoods(
  goodsList: BaseCartItem[],
  excludedProductIds: string[] = []
): BaseCartItem[] {
  return goodsList.filter(
    (goods) =>
      !isTemporaryGoods(goods) &&
      !isGiftGoods(goods) &&
      !excludedProductIds.includes(String(goods.product_id)) // 核心修正：用商品ID排除
  );
}

/**
 * 统一筛选门槛商品的工具函数（所有券类型复用，按商品ID匹配）
 * @param baseEligibleGoods 基础合格商品（已排除临时菜/赠菜/已抵扣商品）
 * @param applicableProductIds 优惠券指定的门槛商品ID数组
 * @returns 最终参与优惠券计算的商品列表
 */
export function filterThresholdGoods(
  baseEligibleGoods: BaseCartItem[],
  applicableProductIds: string[]
): BaseCartItem[] {
  // 空数组=全部基础合格商品；非空=仅商品ID匹配的商品（转字符串兼容类型）
  return applicableProductIds.length === 0
    ? baseEligibleGoods
    : baseEligibleGoods.filter((goods) =>
      applicableProductIds.includes(String(goods.product_id))
    ); // 核心修正：用商品ID匹配
}

/**
 * 商品排序（用于商品兑换券：按价格/数量/加入顺序排序，按商品ID分组去重）
 * @param goodsList 商品列表
 * @param sortRule 排序规则（low_price_first/high_price_first）
 * @param cartOrder 商品加入购物车的顺序（key=购物车ID，value=加入时间戳）
 * @returns 排序后的商品列表
 */
export function sortGoodsForCoupon(
  goodsList: BaseCartItem[],
  sortRule: "low_price_first" | "high_price_first",
  cartOrder: Record<string, number> = {}
): BaseCartItem[] {
  return [...goodsList].sort((a, b) => {
    // 1. 按商品单价排序（优先级最高）
    const priceA = a.skuData?.salePrice ?? a.salePrice;
    const priceB = b.skuData?.salePrice ?? b.salePrice;
    if (priceA !== priceB) {
      return sortRule === "low_price_first" ? priceA - priceB : priceB - priceA;
    }

    // 2. 同价格按商品数量排序（降序，多的优先）
    if (a.number !== b.number) {
      return b.number - a.number;
    }

    // 3. 同价格同数量按加入购物车顺序（早的优先，用购物车ID匹配）
    const orderA = cartOrder[String(a.id)] ?? Infinity;
    const orderB = cartOrder[String(b.id)] ?? Infinity;
    return orderA - orderB;
  });
}

/**
 * 计算优惠券门槛金额（根据同享规则，按商品ID匹配限时折扣）
 * @param eligibleGoods 可参与优惠券的商品列表（已过滤临时菜/赠菜）
 * @param coupon 优惠券（含discountShare/vipPriceShare配置）
 * @param config 订单配置（会员信息）
 * @param activities 全局营销活动（限时折扣，applicableProductIds为商品ID）
 * @returns 满足优惠券门槛的金额基数
 */
export function calcCouponThresholdAmount(
  eligibleGoods: BaseCartItem[],
  coupon: BaseCoupon,
  config: Pick<OrderExtraConfig, "isMember" | "memberDiscountRate">,
  activities: ActivityConfig[] = []
): number {
  let total = new BigNumber(0);

  for (const goods of eligibleGoods) {
    const availableNum = Math.max(0, goods.number - (goods.returnNum || 0));
    if (availableNum <= 0) continue;

    // 1. 基础金额：默认用商品原价（SKU原价优先）
    const basePrice = new BigNumber(
      goods.skuData?.salePrice ?? goods.salePrice
    );
    let itemAmount = basePrice.multipliedBy(availableNum);

    // 2. 处理「与会员价/会员折扣同享」规则：若开启，用会员价计算
    if (coupon.vipPriceShare) {
      const memberPrice = new BigNumber(
        calcMemberPrice(goods, config.isMember, config.memberDiscountRate)
      );
      itemAmount = memberPrice.multipliedBy(availableNum);
    }

    // 3. 处理「与限时折扣同享」规则：若开启，叠加限时折扣（按商品ID匹配活动）
    if (coupon.discountShare) {
      const activity =
        goods.activityInfo ??
        activities.find(
          (act) =>
            act.type === ActivityType.TIME_LIMIT_DISCOUNT &&
            (act.applicableProductIds || []).includes(String(goods.product_id)) // 核心修正：用商品ID匹配活动
        );

      if (activity) {
        itemAmount = itemAmount.multipliedBy(activity.discountRate); // 叠加限时折扣
      }
    }

    total = total.plus(itemAmount);
  }

  return truncateToTwoDecimals(total.toNumber());
}

// ============================ 3. 商品核心价格计算（核心修正：按商品ID匹配营销活动） ============================
/**
 * 计算单个商品的实际单价（整合商家改价、会员优惠、营销活动折扣，按商品ID匹配活动）
 * @param goods 商品项
 * @param config 订单额外配置（含会员、活动信息）
 * @returns 单个商品实际单价（元）
 */
export function calcSingleGoodsRealPrice(
  goods: BaseCartItem,
  config: Pick<OrderExtraConfig, "isMember" | "memberDiscountRate"> & {
    activity?: ActivityConfig; // 商品参与的营销活动（如限时折扣，按商品ID匹配）
  }
): number {
  const { isMember, memberDiscountRate, activity } = config;

  //如果是增菜价格为0
  if (goods.is_gift) {
    return 0;
  }

  // 1. 优先级1：商家改价（改价后单价>0才生效）
  if (goods.discountSaleAmount && goods.discountSaleAmount > 0) {
    return truncateToTwoDecimals(goods.discountSaleAmount);
  }

  // 2. 优先级2：会员价（含会员折扣率，SKU会员价优先）
  const memberPrice = new BigNumber(
    calcMemberPrice(goods, isMember, memberDiscountRate)
  );

  // 3. 优先级3：营销活动折扣（如限时折扣，需按商品ID匹配活动）
  const isActivityApplicable = activity
    ? (activity.applicableProductIds || []).includes(String(goods.product_id)) // 核心修正：用商品ID匹配活动
    : false;
  if (!activity || !isActivityApplicable) {
    return memberPrice.toNumber();
  }

  // 处理活动与会员的同享/不同享逻辑
  if (activity.vipPriceShare) {
    // 同享：会员价基础上叠加工活动折扣
    return truncateToTwoDecimals(
      memberPrice.multipliedBy(activity.discountRate).toNumber()
    );
  } else {
    // 不同享：取会员价和活动价的最小值（活动价用SKU原价计算）
    const basePriceForActivity = new BigNumber(
      goods.skuData?.salePrice ?? goods.salePrice
    );
    const activityPrice = basePriceForActivity.multipliedBy(
      activity.discountRate
    );

    return truncateToTwoDecimals(
      memberPrice.isLessThanOrEqualTo(activityPrice)
        ? memberPrice.toNumber()
        : activityPrice.toNumber()
    );
  }
}

/**
 * 计算商品原价总和（所有商品：原价*数量，含临时菜、赠菜，用SKU原价优先）
 * @param goodsList 商品列表
 * @returns 商品原价总和（元）
 */
export function calcGoodsOriginalAmount(goodsList: BaseCartItem[]): number {
  let total = new BigNumber(0);

  for (const goods of goodsList) {
    const availableNum = Math.max(0, goods.number - (goods.returnNum || 0));
    let basePrice = new BigNumber(0);
    if (goods.is_temporary) {
      basePrice = new BigNumber(goods?.discountSaleAmount ?? 0);
    } else if (goods.is_gift) {
      basePrice = new BigNumber(0);
    }
    else {
      basePrice = new BigNumber(
        goods.skuData?.salePrice ?? goods.salePrice
      ); // SKU原价优先
    }

    total = total.plus(basePrice.multipliedBy(availableNum));
  }

  return truncateToTwoDecimals(total.toNumber());
}

/**
 * 计算商品实际总价（所有商品：实际单价*数量，含临时菜、赠菜，按商品ID匹配活动）
 * @param goodsList 商品列表
 * @param config 订单额外配置（含会员、活动信息）
 * @param activities 全局营销活动列表（如限时折扣，applicableProductIds为商品ID）
 * @returns 商品实际总价（元）
 */
export function calcGoodsRealAmount(
  goodsList: BaseCartItem[],
  config: Pick<OrderExtraConfig, "isMember" | "memberDiscountRate">,
  activities: ActivityConfig[] = []
): number {
  let total = new BigNumber(0);

  for (const goods of goodsList) {
    const availableNum = Math.max(0, goods.number - (goods.returnNum || 0));
    if (availableNum <= 0) continue;

    // 匹配商品参与的营销活动（按商品ID匹配，优先商品自身配置）
    const activity =
      goods.activityInfo ??
      activities.find(
        (act) =>
          (act.applicableProductIds || []).includes(String(goods.product_id)) // 核心修正：用商品ID匹配活动
      );

    const realPrice = new BigNumber(
      calcSingleGoodsRealPrice(goods, { ...config, activity })
    );
    total = total.plus(realPrice.multipliedBy(availableNum));
  }

  return truncateToTwoDecimals(total.toNumber());
}

/**
 * 计算商品折扣总金额（商品原价总和 - 商品实际总价）
 * @param goodsOriginalAmount 商品原价总和
 * @param goodsRealAmount 商品实际总价
 * @returns 商品折扣总金额（元，≥0）
 */
export function calcGoodsDiscountAmount(
  goodsOriginalAmount: number,
  goodsRealAmount: number
): number {
  const original = new BigNumber(goodsOriginalAmount);
  const real = new BigNumber(goodsRealAmount);
  const discount = original.minus(real);

  return truncateToTwoDecimals(Math.max(0, discount.toNumber()));
}
/**
 * 从满减活动的多门槛中，选择最优阈值（满金额最小且减免金额最大）
 * @param thresholds 满减阈值列表（多门槛）
 * @param baseAmount 满减计算基数（新客立减后的金额）
 * @param goodsOriginalAmount 商品原价总和（discountShare=0时用）
 * @param goodsRealAmount 商品折扣后总和（discountShare=1时用）
 * @param discountShare 与限时折扣同享：0=否，1=是
 * @returns 最优阈值（无符合条件则返回undefined）
 */
export function selectOptimalThreshold(
  thresholds: FullReductionThreshold[] = [],
  baseAmount: number,
  goodsOriginalAmount: number,
  goodsRealAmount: number,
  discountShare: number = 0
): FullReductionThreshold | undefined {
  if (!thresholds.length) return undefined;

  // 第一步：确定满减门槛基数（根据discountShare规则）
  const thresholdBase = discountShare === 1 
    ? new BigNumber(goodsRealAmount) // 与限时折扣同享→用折扣后金额
    : new BigNumber(goodsOriginalAmount); // 不同享→用原价

  // 第二步：筛选「满金额≤基数」且「减免金额>0」的有效阈值
  const validThresholds = thresholds.filter(threshold => {
    const fullAmount = new BigNumber(threshold.fullAmount || 0);
    const discountAmount = new BigNumber(threshold.discountAmount || 0);
    return fullAmount.isLessThanOrEqualTo(thresholdBase) && discountAmount.isGreaterThan(0);
  });

  if (!validThresholds.length) return undefined;

  // 第三步：选择最优阈值（优先级：1.满金额最小 → 2.减免金额最大）
  return validThresholds.sort((a, b) => {
    const aFull = new BigNumber(a.fullAmount || 0);
    const bFull = new BigNumber(b.fullAmount || 0);
    const aDiscount = new BigNumber(a.discountAmount || 0);
    const bDiscount = new BigNumber(b.discountAmount || 0);

    // 先比满金额：越小越优先（满1减10 比 满100减20 更优）
    if (!aFull.isEqualTo(bFull)) {
      return aFull.comparedTo(bFull) || 0; // Ensure a number is always returned
    }
    // 再比减免金额：越大越优先
    return bDiscount.comparedTo(aDiscount) || 0; // Ensure a number is always returned
  })[0];
}

/**
 * 计算满减实际减免金额（适配多门槛、同享规则）
 * @param optimalActivity 最优满减活动
 * @param optimalThreshold 最优满减阈值
 * @param baseAmount 计算基数（新客立减后的金额）
 * @returns 实际减免金额（元，未达门槛则0）
 */
export function calcFullReductionAmount(
  baseAmount: number,
  optimalActivity?: FullReductionActivity,
  optimalThreshold?: FullReductionThreshold,
): number {
  if (!optimalActivity || !optimalThreshold) return 0;

  const baseAmountBn = new BigNumber(baseAmount);
  const discountAmountBn = new BigNumber(optimalThreshold.discountAmount || 0);

  // 1. 基数必须为正（避免减免后为负）
  if (baseAmountBn.isLessThanOrEqualTo(0)) return 0;

  // 2. 减免金额不能超过基数（避免减成负数）
  const maxReducible = baseAmountBn;
  const actualReduction = discountAmountBn.isLessThanOrEqualTo(maxReducible)
    ? discountAmountBn
    : maxReducible;

  return truncateToTwoDecimals(actualReduction.toNumber());
}


// ------------------------------ 策略辅助函数 ------------------------------
/**
 * 根据优惠券useShops列表判断门店是否匹配（适配BaseCoupon的useShops字段）
 */
function isStoreMatchByList(
  useShops: string[],
  currentStoreId: string
): boolean {
  // 适用门店为空数组 → 无限制（所有门店适用）
  if (useShops.length === 0) return true;
  // 匹配当前门店ID（字符串比较，避免类型问题）
  return useShops.includes(currentStoreId);
}



/**
 * 计算优惠券抵扣金额（处理互斥逻辑，选择最优优惠券，按商品ID排除，新增细分统计）
 * @param backendCoupons 后端优惠券列表
 * @param goodsList 商品列表
 * @param config 订单配置（含就餐类型）
 * @returns 最优优惠券的抵扣结果（含商品券/满减券细分）
 */
export function calcCouponDeduction(
  backendCoupons: BackendCoupon[],
  goodsList: BaseCartItem[],
  config: Pick<
    OrderExtraConfig,
    "currentStoreId" | "isMember" | "memberDiscountRate"
  > & {
    activities: ActivityConfig[];
    cartOrder: Record<string, number>;
    dinnerType: "dine-in" | "take-out";
    currentTime?: Date;
  }
): {
  deductionAmount: number;
  productCouponDeduction: number; // 新增：商品优惠券抵扣（兑换券/折扣券/买一送一等）
  fullCouponDeduction: number; // 新增：满减优惠券抵扣
  usedCoupon?: Coupon;
  excludedProductIds: string[]; // 排除的商品ID列表（商品ID）
} {
  const goodsCoupon = backendCoupons.filter((v) => v.type == 2);
  const discountCoupon = backendCoupons.filter((v) => v.type != 2);

  // 3. 计算非兑换券最优抵扣（传递已抵扣商品ID，避免重复，统计细分字段）
  let nonExchangeResult: CouponResult = {
    deductionAmount: discountCoupon.reduce((prve, cur): number => {
      return prve + (cur.discountAmount || 0);
    }, 0),
    excludedProductIds: [],
    usedCoupon: undefined,
    productCouponDeduction: 0,
    fullCouponDeduction: 0,
  };

  // 4. 计算兑换券抵扣（排除非兑换券已抵扣的商品ID，统计商品券细分）
  let exchangeResult: ExchangeCalculationResult = {
    deductionAmount: goodsCoupon.reduce((prve, cur): number => {
      return prve + (cur.discountAmount || 0);
    }, 0),
    excludedProductIds: [],
    productCouponDeduction: 0,
  };

  // 5. 汇总结果：兑换券与非兑换券不可同时使用，取抵扣金额大的
  const exchangeBn = new BigNumber(exchangeResult.deductionAmount);
  const nonExchangeBn = new BigNumber(nonExchangeResult.deductionAmount);
  const isExchangeBetter = exchangeBn.isGreaterThan(nonExchangeBn);

  return {
    deductionAmount: exchangeBn.plus(nonExchangeBn).toNumber(),
    productCouponDeduction: exchangeResult.deductionAmount,
    fullCouponDeduction: nonExchangeResult.deductionAmount, // 兑换券与满减券互斥，满减券抵扣置0
    usedCoupon: isExchangeBetter ? undefined : nonExchangeResult.usedCoupon,
    excludedProductIds: isExchangeBetter
      ? exchangeResult.excludedProductIds
      : nonExchangeResult.excludedProductIds,
  };
}

// ============================ 5. 其他费用计算（无ID依赖，逻辑不变） ============================
/**
 * 计算总打包费（赠菜也计算，称重商品打包数量≤1）
 * @param goodsList 商品列表
 * @param dinnerType 就餐类型（堂食dine-in/外卖take-out）
 * @returns 总打包费（元）
 */
export function calcTotalPackFee(
  goodsList: BaseCartItem[],
  dinnerType: "dine-in" | "take-out"
): number {
  // if (dinnerType !== "take-out") return 0;
  let total = new BigNumber(0);

  for (const goods of goodsList) {
    const packNumber = goods.packNumber ? goods.packNumber * 1 : 0;
    let availableNum = Math.max(0, goods.number - (goods.returnNum || 0));
    availableNum = Math.min(availableNum, packNumber);

    if (availableNum === 0) continue;

    // 计算单个商品打包数量（外卖全打包，堂食按配置，称重商品≤1）
    let packNum = availableNum;
    if (goods.product_type === GoodsType.WEIGHT) {
      packNum = Math.min(packNum, 1);
    }

    total = total.plus(new BigNumber(goods.packFee || 0).multipliedBy(packNum));
  }

  return truncateToTwoDecimals(total.toNumber());
}

/**
 * 计算餐位费（按人数，不参与营销活动）
 * @param config 餐位费配置
 * @returns 餐位费（元，未启用则0）
 */
export function calcSeatFee(config: SeatFeeConfig): number {
  if (!config.isEnabled || config.personCount == 0) return 0;
  const personCount = Math.max(1, config.personCount); // 至少1人
  return truncateToTwoDecimals(
    new BigNumber(config.pricePerPerson).multipliedBy(personCount).toNumber()
  );
}

/**
 * 计算积分抵扣金额（按X积分=1元，不超过最大抵扣和用户积分）
 * @param userPoints 用户当前积分
 * @param rule 积分抵扣规则
 * @param maxDeductionLimit 最大抵扣上限（通常为订单金额，避免超扣）
 * @returns 积分抵扣金额 + 实际使用积分
 */
export function calcPointDeduction(
  userPoints: number,
  rule: PointDeductionRule,
  maxDeductionLimit: number
): {
  deductionAmount: number;
  usedPoints: number;
} {
  if (rule.pointsPerYuan <= 0 || userPoints <= 0) {
    return { deductionAmount: 0, usedPoints: 0 };
  }

  const userPointsBn = new BigNumber(userPoints);
  const pointsPerYuanBn = new BigNumber(rule.pointsPerYuan);
  const maxLimitBn = new BigNumber(maxDeductionLimit);

  // 最大可抵扣金额（积分可抵金额 vs 规则最大 vs 订单上限）
  const maxDeductByPoints = userPointsBn.dividedBy(pointsPerYuanBn);
  const maxDeductAmount = maxDeductByPoints.isLessThan(
    rule.maxDeductionAmount ?? Infinity
  )
    ? maxDeductByPoints
    : new BigNumber(rule.maxDeductionAmount || Infinity).isLessThan(maxLimitBn)
      ? maxDeductByPoints
      : maxLimitBn;

  // 实际使用积分 = 抵扣金额 * 积分兑换比例
  const usedPoints = maxDeductAmount.multipliedBy(pointsPerYuanBn);

  return {
    deductionAmount: truncateToTwoDecimals(maxDeductAmount.toNumber()),
    usedPoints: truncateToTwoDecimals(
      Math.min(usedPoints.toNumber(), userPoints)
    ), // 避免积分超扣
  };
}

// ============================ 6. 订单总费用汇总与实付金额计算（核心入口，补充细分字段） ============================
/**
 * 计算订单所有费用子项并汇总（核心入口函数）
 * @param goodsList 购物车商品列表
 * @param dinnerType 就餐类型
 * @param backendCoupons 后端优惠券列表
 * @param activities 全局营销活动列表
 * @param config 订单额外配置（会员、积分、餐位费等）
 * @param cartOrder 商品加入购物车顺序（key=购物车ID，value=时间戳）
 * @param currentTime 当前时间（用于优惠券有效期判断）
 * @returns 订单费用汇总（含所有子项和实付金额，新增商品券/满减券细分）
 */
export function calculateOrderCostSummary(
  goodsList: BaseCartItem[],
  dinnerType: "dine-in" | "take-out", // 前端就餐类型
  backendCoupons: BackendCoupon[] = [],
  activities: ActivityConfig[] = [],
  config: OrderExtraConfig, // 含后端满减活动、currentDinnerType
  cartOrder: Record<string, number> = {},
  currentTime: Date = new Date()
): OrderCostSummary {
  // ------------------------------ 1. 基础费用计算 ------------------------------
  const goodsOriginalAmount = calcGoodsOriginalAmount(goodsList); // 商品原价总和
  const goodsRealAmount = calcGoodsRealAmount( // 商品折扣后总和
    goodsList,
    { isMember: config.isMember, memberDiscountRate: config.memberDiscountRate },
    activities
  );
  const goodsDiscountAmount = calcGoodsDiscountAmount(goodsOriginalAmount, goodsRealAmount); // 商品折扣金额
  const newUserDiscount = config.newUserDiscount || 0; // 新客立减

  // ------------------------------ 2. 满减活动计算（核心步骤） ------------------------------
  let usedFullReductionActivity: FullReductionActivity | undefined;
  let usedFullReductionThreshold: FullReductionThreshold | undefined;
  let fullReductionAmount = 0;

  // 2.1 筛选最优满减活动（后端活动列表、当前店铺、就餐类型、时间）
  usedFullReductionActivity = filterOptimalFullReductionActivity(
    config.fullReductionActivities,
    Number(config.currentStoreId), // 转换为数字（后端shopId是number）
    config.currentDinnerType, // 后端useType匹配的就餐类型（如"dine"）
    currentTime
  );

  // 2.2 计算满减基数（先扣新客立减）
  const baseAfterNewUserDiscount = new BigNumber(goodsRealAmount)
    .minus(newUserDiscount)
    .isGreaterThan(0) 
    ? new BigNumber(goodsRealAmount).minus(newUserDiscount).toNumber() 
    : 0;

  // 2.3 选择最优满减阈值（多门槛场景）
  if (usedFullReductionActivity) {
    usedFullReductionThreshold = selectOptimalThreshold(
      usedFullReductionActivity.thresholds,
      baseAfterNewUserDiscount,
      goodsOriginalAmount,
      goodsRealAmount,
      usedFullReductionActivity.discountShare || 0 // 与限时折扣同享规则
    );

    // 2.4 计算满减实际减免金额
    fullReductionAmount = calcFullReductionAmount(
      baseAfterNewUserDiscount,
      usedFullReductionActivity,
      usedFullReductionThreshold,
    );
  }

  // ------------------------------ 3. 优惠券抵扣（适配满减同享规则） ------------------------------
  let couponDeductionAmount = 0;
  let productCouponDeduction = 0;
  let fullCouponDeduction = 0;
  let usedCoupon: Coupon | undefined;
  let excludedProductIds: string[] = [];

  // 若满减与优惠券同享（couponShare=1），才计算优惠券；否则优惠券抵扣为0
  if (usedFullReductionActivity?.couponShare === 1) {
    const couponResult = calcCouponDeduction( // 原有优惠券计算函数
      backendCoupons,
      goodsList,
      {
        currentStoreId: config.currentStoreId,
        isMember: config.isMember,
        memberDiscountRate: config.memberDiscountRate,
        activities,
        cartOrder,
        dinnerType,
        currentTime
      }
    );
    couponDeductionAmount = couponResult.deductionAmount;
    productCouponDeduction = couponResult.productCouponDeduction;
    fullCouponDeduction = couponResult.fullCouponDeduction;
    usedCoupon = couponResult.usedCoupon;
    excludedProductIds = couponResult.excludedProductIds;
  }

  // ------------------------------ 4. 积分抵扣（适配满减同享规则） ------------------------------
  let pointDeductionAmount = 0;
  let usedPoints = 0;

  // 计算积分抵扣基数（商品折扣后 - 新客立减 - 满减 - 优惠券）
  const maxPointDeductionLimit = new BigNumber(goodsRealAmount)
    .minus(newUserDiscount)
    .minus(fullReductionAmount)
    .minus(couponDeductionAmount)
    .isGreaterThan(0)
    ? new BigNumber(goodsRealAmount).minus(newUserDiscount).minus(fullReductionAmount).minus(couponDeductionAmount).toNumber()
    : 0;

  // 若满减与积分同享（pointsShare=1），才计算积分；否则积分抵扣为0
  if ((usedFullReductionActivity?.pointsShare === 1) && maxPointDeductionLimit > 0) {
    const pointResult = calcPointDeduction(
      config.userPoints,
      config.pointDeductionRule,
      maxPointDeductionLimit
    );
    pointDeductionAmount = pointResult.deductionAmount;
    usedPoints = pointResult.usedPoints;
  }

  // ------------------------------ 5. 其他费用计算（原有逻辑不变） ------------------------------
  const packFee = calcTotalPackFee(goodsList, dinnerType); // 打包费
  let seatFee = calcSeatFee(config.seatFeeConfig); // 餐位费
  seatFee = dinnerType === "dine-in" ? seatFee : 0; // 外卖不收餐位费
  const additionalFee = Math.max(0, config.additionalFee); // 附加费

  // 商家减免计算（原有逻辑不变）
  const merchantReductionConfig = config.merchantReduction;
  let merchantReductionActualAmount = 0;
  const maxMerchantReductionLimit = new BigNumber(goodsRealAmount)
    .minus(newUserDiscount)
    .minus(fullReductionAmount)
    .minus(couponDeductionAmount)
    .minus(pointDeductionAmount)
    .plus(seatFee)
    .plus(packFee)
    .isGreaterThan(0)
    ? new BigNumber(goodsRealAmount).minus(newUserDiscount).minus(fullReductionAmount).minus(couponDeductionAmount).minus(pointDeductionAmount).plus(seatFee).plus(packFee).toNumber()
    : 0;

  switch (merchantReductionConfig.type) {
    case MerchantReductionType.FIXED_AMOUNT:
      merchantReductionActualAmount = Math.min(
        merchantReductionConfig.fixedAmount || 0,
        maxMerchantReductionLimit
      );
      break;
    case MerchantReductionType.DISCOUNT_RATE:
      const validRate = Math.max(0, Math.min(100, merchantReductionConfig.discountRate || 0)) / 100;
      merchantReductionActualAmount = maxMerchantReductionLimit * (1 - validRate);
      break;
  }
  merchantReductionActualAmount = Math.max(0, truncateToTwoDecimals(merchantReductionActualAmount));

  // ------------------------------ 6. 最终实付金额计算 ------------------------------
  const finalPayAmountBn = new BigNumber(goodsRealAmount)
    .minus(newUserDiscount)
    .minus(fullReductionAmount)
    .minus(couponDeductionAmount)
    .minus(pointDeductionAmount)
    .minus(merchantReductionActualAmount)
    .plus(seatFee)
    .plus(packFee)
    .plus(additionalFee);
  const finalPayAmount = Math.max(0, truncateToTwoDecimals(finalPayAmountBn.toNumber()));

  // ------------------------------ 7. 总优惠金额计算 ------------------------------
  const totalDiscountAmount = truncateToTwoDecimals(
    new BigNumber(goodsDiscountAmount)
      .plus(newUserDiscount)
      .plus(fullReductionAmount)
      .plus(couponDeductionAmount)
      .plus(pointDeductionAmount)
      .plus(merchantReductionActualAmount)
      .toNumber()
  );
  // 积分可抵扣最大金额

  // ------------------------------ 8. 返回完整结果 ------------------------------
  return {
    goodsTotal: goodsList.reduce((sum, g) => sum + Math.max(0, g.number - (g.returnNum || 0)), 0),
    goodsRealAmount,
    goodsOriginalAmount,
    goodsDiscountAmount,
    couponDeductionAmount,
    productCouponDeduction,
    fullCouponDeduction,
    pointDeductionAmount,
    seatFee,
    packFee,
    totalDiscountAmount,
    // 满减活动明细（后端字段）
    fullReduction: {
      usedActivity: usedFullReductionActivity,
      usedThreshold: usedFullReductionThreshold,
      actualAmount: truncateToTwoDecimals(fullReductionAmount)
    },
    merchantReduction: {
      type: merchantReductionConfig.type,
      originalConfig: merchantReductionConfig,
      actualAmount: merchantReductionActualAmount
    },
    additionalFee,
    finalPayAmount,
    couponUsed: usedCoupon,
    pointUsed: usedPoints,
    newUserDiscount,
    dinnerType,
    config
  };
}

export function isWeightGoods(goods: BaseCartItem): boolean {
  return goods.product_type === GoodsType.WEIGHT;
}

// ============================ 7. 对外暴露工具库 ============================
export const OrderPriceCalculator = {
  // 基础工具
  truncateToTwoDecimals,
  isTemporaryGoods,
  isGiftGoods,
  formatDiscountRate,
  filterThresholdGoods,
  isWeightGoods,
  // 商品价格计算
  calcSingleGoodsRealPrice,
  calcGoodsOriginalAmount,
  calcGoodsRealAmount,
  calcGoodsDiscountAmount,
  //满减活动工具
  filterOptimalFullReductionActivity,
  // 优惠券计算
  calcCouponDeduction,
  // 其他费用计算
  calcTotalPackFee,
  calcSeatFee,
  calcPointDeduction,
  // 核心入口
  calculateOrderCostSummary,
  // 枚举导出
  Enums: {
    GoodsType,
    CouponType,
    ActivityType,
    WEEKDAY_MAP,
  },
};

export default OrderPriceCalculator;
