/**
 * 安全金额计算工具
 * ==================
 * 强制使用 decimal.js 高精度运算，杜绝浮点数精度问题。
 * 所有金额计算必须通过此模块，禁止直接用 `*` `/` `+` `-` 操作价格字段。
 *
 * 未来计划：数据库字段全面迁移为整数（分）存储，届时增加 toCents()/fromCents()。
 */
const Decimal = require('decimal.js');
Decimal.set({ precision: 20, rounding: Decimal.ROUND_HALF_UP });

function $(value) {
  if (value instanceof Decimal) return value;
  return new Decimal(value || 0);
}

/** 乘法（单价×数量），返回数字 */
function mul(price, quantity) {
  return $(price).mul($(quantity)).toNumber();
}

/** 加法 */
function add(a, b) { return $(a).add($(b)).toNumber(); }

/** 减法 */
function sub(a, b) { return $(a).sub($(b)).toNumber(); }

/** 折扣额（减免额）：total × (1 - discountRate) */
function discountAmt(total, discountRate) {
  return new Decimal($(total).mul($(1).sub($(discountRate))).toFixed(2)).toNumber();
}

/** 折扣后应付金额：total × discountRate */
function afterDiscount(total, discountRate) {
  return new Decimal($(total).mul($(discountRate)).toFixed(2)).toNumber();
}

/** 优惠券后金额 */
function afterCoupon(amount, couponValue, couponType) {
  if (couponType === 'fixed' || couponType === 'cash') {
    return new Decimal($(amount).sub($(couponValue)).toFixed(2)).toNumber();
  }
  return new Decimal($(amount).mul($(1).sub($(couponValue).div(100))).toFixed(2)).toNumber();
}

/** 格式化输出字符串（保留2位小数） */
function fmt(value) {
  return $(value).toFixed(2);
}

/** 转为保留2位小数的数字 */
function toNum(value) {
  return new Decimal($(value).toFixed(2)).toNumber();
}

module.exports = { $, mul, add, sub, discountAmt, afterDiscount, afterCoupon, fmt, toNum };
