// 商品价格计算相关
import { times, plus, minus, divide } from 'number-precision'

// 价格格式化
export function formatPrice(value, needSymbol = true) {
  // 不能在最后一步显示之前格式化999 111, 否则可能出现单价1买999个得到999价格被格式化成poa的情况
  if (value === 0) {
    return needSymbol ? '$0.00' : '0.00'
  } else {
    return needSymbol ? `$${value}` : `${value}`
  }
}

// 简单的乘法换算
function multiply(value, ratio = 100) {
  return parseFloat((value * ratio).toPrecision(12))
}
// 小数处理, 四舍五入, 为toFixed做准备
export function round(number, ratio = 100) {
  return Math.round(multiply(number, ratio)) / ratio
}

/**
 * 将字符串简单转换成数字, 并可数倍转换. 注意, 这个适用于整数倍(商品件数), 非整数的不能用这个处理小数.
 * @param {*} value 目标值
 * @param {*} ratio 倍数, 默认1
 * @returns number | origin, 转换后的数字, 无法转成数字的返回原值
 */
export function transformNumber(value, ratio = 1) {
  const v = Number(value)
  if (Number.isNaN(v)) {
    return value
  } else {
    // 保留两位小数
    return divide(Math.trunc(times(times(v, ratio), 100)), 100)
  }
}

// unit 单个商品的, 没有乘数量. 因为含有111 999 这些极端值, 没有格式化输出之前直接乘回出问题的.
export const getUnit = function (buyNum, index, attributeList, basePriceList) {
  // 算出购买数量位于 价格阶梯的 哪个区间
  const candidate = Object.entries(attributeList).filter(
    item => buyNum >= item[1]
  )

  let key = 'website_qty1'
  if (candidate.length) {
    key = candidate.pop()[0]
  }

  return transformNumber(basePriceList[index][key], buyNum)
}

// 打印和附加价格 的steup之和. 商品基础价格现在没有setup了.
export const getSetup = function (buyNum, form, additionList) {
  const sum = Object.entries(form).reduce((total, current) => {
    let s = 0
    // 打印服务表单的数据跟附加服务表单的数据结构不一致, 以数字id字符串键名的是打印服务的数据
    if (/\d+/.test(current[0]) && current[1].enable) {
      const temp = current[1].colorForm.filter(
        i => i.id === current[1].printService
      )
      let colorNumber = 1
      if (temp.length) {
        colorNumber = temp[0].colorNumber
      }

      const decoration = current[1].decorationList.filter(
        i => i.id === current[1].printService
      )
      let setup = 0
      if (decoration.length) {
        setup = plus(
          Number(decoration[0].website_setup),
          times(Number(decoration[0].supplier_setup), colorNumber - 1)
        )
      }
      s = plus(s, setup)
    } else if (current[1].length) {
      // 附加服务的表单数据, 有值说明该项有选中了附加服务
      const addition = additionList[current[0]].filter(addition =>
        current[1].includes(addition.id)
      )

      if (addition.length) {
        const temp = addition.reduce((t, c) => {
          let value = Number(c.website_setup)
          if ([5, 6].includes(c.website_setup_id)) {
            // 5是poa, 6是waived. 这种情况一般setup是留空的, 不留空大概是异常数据, 重置0保险一点.
            value = 0
          }
          return plus(t, Number.isNaN(value) ? 0 : value)
        }, 0)

        s = plus(s, temp)
      }
    }

    total = plus(total, s)
    return total
  }, 0)
  return transformNumber(sum)
}

// 打印价格的 阶梯基础价*购买数量.
export const getPrint = function (buyNum, form, attributeList) {
  // 算出购买数量位于 价格阶梯的 哪个区间
  const candidate = Object.entries(attributeList).filter(
    item => buyNum >= item[1]
  )
  const key = `website_qty${candidate.length}`
  const key2 = `supplier_qty${candidate.length}`

  // 如果其中一项为POA, 则‘和’都是POA
  const result = Object.entries(form).reduce((total, current) => {
    if (total === 'POA') {
      return total
    }
    let sum = 0
    if (/\d+/.test(current[0]) && current[1].enable) {
      const temp = current[1].colorForm.filter(
        i => i.id === current[1].printService
      )
      let colorNumber = 1
      if (temp.length) {
        colorNumber = temp[0].colorNumber
      }

      const decoration = current[1].decorationList.filter(
        i => i.id === current[1].printService
      )
      // 打印价格的基础价. 其中数字111(代表'-') 和999(代表'POA')
      const p1 = transformNumber(decoration[0][key])
      if (p1 === 999 || p1 === 111 || typeof p1 !== 'number') {
        return 'POA'
      }
      // 打印价格的附加价
      const p2 = transformNumber(decoration[0][key2])
      if (p2 === 999 || p2 === 111 || typeof p2 !== 'number') {
        return 'POA'
      }
      let price = 0
      if (decoration.length) {
        price = plus(p1, times(p2, colorNumber - 1))
      }
      sum = plus(sum, price)
    }
    total = plus(total, sum)
    return total
  }, 0)

  return transformNumber(result, buyNum)
}
// 附加服务除了packing之外的总价
export const getAddon = function (buyNum, form, attributeList, additionList) {
  // 算出购买数量位于 价格阶梯的 哪个区间
  const candidate = Object.entries(attributeList).filter(
    item => buyNum >= item[1]
  )
  const key = `website_qty${candidate.length}`
  const result = Object.entries(form).reduce((total, current) => {
    if (total === 'POA') {
      return total
    }

    let sum = 0
    if (!/\d+/.test(current[0]) && current[0] !== 'packaging') {
      sum = additionList[current[0]]
        .filter(item => current[1].includes(item.id))
        .reduce((t, c) => {
          if (t === 'POA') {
            return t
          }
          let temp = transformNumber(c[key])
          if (temp === 999 || temp === 111 || typeof temp !== 'number') {
            temp = 0
            return 'POA'
          }
          t = plus(t, temp)
          return t
        }, 0)
    }
    return plus(total, sum)
  }, 0)

  return transformNumber(result, buyNum)
}
// 附加服务中 packing 的价格
export const getPackaging = function (
  buyNum,
  form,
  attributeList,
  additionList
) {
  // 算出购买数量位于 价格阶梯的 哪个区间
  const candidate = Object.entries(attributeList).filter(
    item => buyNum >= item[1]
  )
  const key = `website_qty${candidate.length}`
  const result = Object.entries(form).reduce((total, current) => {
    if (total === 'POA') {
      return total
    }

    let sum = 0
    if (!/\d+/.test(current[0]) && current[0] === 'packaging') {
      sum = additionList[current[0]]
        .filter(item => current[1].includes(item.id))
        .reduce((t, c) => {
          if (t === 'POA') {
            return t
          }
          let temp = transformNumber(c[key])
          if (temp === 999 || temp === 111 || typeof temp !== 'number') {
            temp = 0
            return 'POA'
          }
          t = plus(t, temp)
          return t
        }, 0)
    }
    return plus(total, sum)
  }, 0)

  return transformNumber(result, buyNum)
}

// 运费计算. 从product页面抄过来的逻辑. +号是隐式类型转换
export const getFright = function (buyNum, config, freight, weight, ratio = 1) {
  // 单独批次数量的总重
  const totalWeight = Math.ceil(times(+weight.unit_w_local, buyNum))

  const expressFactor = plus(
    1,
    divide(plus(+config.express_freight, +config.fuel), 100)
  )

  const AAEFactor = plus(
    1,
    divide(plus(+config.bag_freight, +config.fuel), 100)
  )
  let frightCost = 0

  if (freight.type === 1) {
    if (totalWeight > 20) {
      const a1 = minus(totalWeight, 20)
      const a2 = times(a1, +freight.basic)
      const a3 = plus(+freight.pickup, a2)
      frightCost = times(a3, expressFactor)
    } else {
      frightCost = times(+freight.pickup, expressFactor)
    }
  } else if (freight.type === 2) {
    const a1 = times(totalWeight, +freight.basic)
    const a2 = plus(+freight.pickup, a1)
    frightCost = times(a2, AAEFactor)
  } else {
    frightCost = 0
  }
  return transformNumber(frightCost, ratio)
}
