package com.yidian.shenghuoquan.buserorder.viewmodel

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.google.gson.Gson
import com.yidian.bcommon.mvvm.BaseViewModel
import com.yidian.bcommon.mvvm.ErrorInfo
import com.yidian.bcommon.utils.CPointUtils
import com.yidian.shenghuoquan.buserorder.dto.*
import com.yidian.shenghuoquan.buserorder.http.OrderRemoteDataSource
import org.json.JSONArray
import org.json.JSONObject


class ConfirmOrderViewModel : BaseViewModel() {

  private var marketingInfo: MarketingInfo? = null
  private var payOrderId: String? = null
  private lateinit var currentParamsJson: JSONObject// 当前订单的请求参数
  private var originalAmount: Double = 0.00// 原价总和
  var couponAmount: Double = 0.00// 优惠券金额
  var couponAmountValue = MutableLiveData(0.00)
  var couponNameValue = MutableLiveData("红包/优惠券")

  var selectedPickUpPoint = MutableLiveData<Shipping?>()// 自提点
  var receivingName = MutableLiveData<String>()// 收货人姓名
  var receivingPhone = MutableLiveData<String>()//收货人电话
  var marketingName = MutableLiveData<String>()//活动名称
  var selectedCouponList = MutableLiveData<MutableList<CouponDto>?>()// 选中的优惠券
  var couponsAvailableList = MutableLiveData<List<CouponDto>?>()// 可用优惠券列表
  var couponsAvailableNum = MutableLiveData<String>()// 可用优惠券数量提示
  var totalAmount = MutableLiveData(0.00)// 合计金额 = 原价 - 优惠
  var remark = MutableLiveData<String>()

  /**
   * 商品列表成功 Event
   */
  private val _goodsSuccessEvent = MutableLiveData<List<GoodsDto>?>()
  val goodsSuccessEvent: LiveData<List<GoodsDto>?> = _goodsSuccessEvent

  /**
   * 选择自提点 Event
   */
  private val _choosePointEvent = MutableLiveData<Long?>()
  val choosePointEvent: LiveData<Long?> = _choosePointEvent

  /**
   * 选择优惠券 Event
   */
  private val _chooseCouponEvent = MutableLiveData<List<CouponDto>?>()
  val chooseCouponEvent: LiveData<List<CouponDto>?> = _chooseCouponEvent

  /**
   * 选择自提点 Event
   */
  private val _toOrderDetailEvent = MutableLiveData<String?>()
  val toOrderDetailEvent: LiveData<String?> = _toOrderDetailEvent

  /**
   * 调起支付 Event
   */
  private val _toPaymentEvent = MutableLiveData<String>()
  val toPaymentEvent: LiveData<String> = _toPaymentEvent

  /**
   * 立即支付按钮是否可用 Event
   */
  private val _payEnableEvent = MutableLiveData<Boolean>()
  val payEnableEvent: LiveData<Boolean> = _payEnableEvent

  /**
   * 请求订单信息
   */
  fun requestConfirmOrderInfo(paramsJson: JSONObject) {
    OrderRemoteDataSource.requestOrderConfirm(paramsJson) {
      if (it == null) {
        return@requestOrderConfirm
      }
      currentParamsJson = paramsJson
      selectedPickUpPoint.value = it.shipping
      receivingName.value = it.shipping?.receiverName ?: ""
      receivingPhone.value = it.shipping?.receiverMobile ?: ""
      marketingInfo = it.marketingInfo
      marketingName.value = marketingInfo?.marketingName ?: ""
      _goodsSuccessEvent.value = it.goodsList
      calculateOriginalAmount(it.goodsList)
      couponsAvailableList.value = it.couponList
      calculateCouponsAvailableNum(it.couponList)
      // 上传页面埋点信息
      commitPageBuriedPoint()
    }
  }

  private fun calculateCouponsAvailableNum(couponList: List<CouponDto>?) {
    if (couponList.isNullOrEmpty()) {
      couponsAvailableNum.value = "当前暂无可使用优惠券"
    } else {
      couponsAvailableNum.value = "${couponList.size} 张优惠券可用"
    }
  }

  /**
   * 计算商品原价 = 数量 * 单价
   */
  private fun calculateOriginalAmount(goodsDto: List<GoodsDto>?) {
    if (goodsDto.isNullOrEmpty()) {
      return
    }
    goodsDto.forEach {
      originalAmount = originalAmount.plus(it.price * it.goodsNum)
    }
    // 计算出合计
    calculateTotalAmount()
  }

  /**
   * 计算商品合计 = 原价 - 优惠
   */
  private fun calculateTotalAmount() {
    var total = originalAmount - couponAmount
    if (total < 0) {
      total = 0.00
    }
    totalAmount.value = total
  }

  /**
   * 选择自提点，如果有上次选中的带过去自提点id
   */
  fun choosePickUpPoint() {
    // 带过去当前选中自提点id
    _choosePointEvent.value = selectedPickUpPoint.value?.takePlaceId
  }

  fun choosePickUpPointSuccess(point: PickupPoint) {
    selectedPickUpPoint.value = Shipping(
      takePlaceId = point.takePlaceId,
      takePlaceName = point.takePlaceName,
      contactName = point.contactName,
      phone = point.phone,
      address = point.address
    )
  }

  /**
   * 选择代金券, 如果有上次选中的带过去最新的列表
   */
  fun chooseVoucher() {
    //选择之前先将上次的金额清零
    couponAmount = 0.00
    _chooseCouponEvent.value = couponsAvailableList.value
  }

  /**
   * 选择的优惠券金额已支持多选，⚠️ ：名称和UI暂不支持
   */
  fun chooseVoucherSuccess(indexList: List<Int>) {
    // 获取选中的优惠券
    val list = mutableListOf<CouponDto>()
    indexList.forEach {
      val coupon = couponsAvailableList.value?.get(it)
      coupon?.let { couponDto ->
        // 累加优惠券金额
        couponAmount += couponDto.amount?.toDouble() ?: 0.00
        list.add(couponDto)
      }
    }
    selectedCouponList.value = list
    // 更新优惠券总金额
    couponAmountValue.value = couponAmount
    // 更新选择优惠券名称
    couponNameValue.value = couponsAvailableList.value?.get(0)?.name
    // 重新计算相关金额
    calculateTotalAmount()
  }

  /**
   * 创建订单
   */
  fun createOrder() {
    if (selectedPickUpPoint.value?.takePlaceId == null) {
      postErrorEvent(ErrorInfo(message = "请选择自提点"))
      return
    }
    if (receivingName.value.isNullOrBlank()) {
      postErrorEvent(ErrorInfo(message = "请输入收货人姓名"))
      return
    }
    if (receivingName.value?.length == 1) {
      postErrorEvent(ErrorInfo(message = "姓名必须为2到10个字符"))
      return
    }
    if (receivingPhone.value.isNullOrBlank()) {
      postErrorEvent(ErrorInfo(message = "请输入手机号码"))
      return
    }
    if (receivingPhone.value?.length != 11) {
      postErrorEvent(ErrorInfo(message = "请输入11位手机号码"))
      return
    }
    // 防止重复多次点击立即支付按钮
    paymentEnable(false)
    if (!selectedCouponList.value.isNullOrEmpty()) {// 添加上选中的优惠券
      currentParamsJson.put("coupon_list", JSONArray(selectedCouponList.value))
    }
    currentParamsJson.put("take_place_id", selectedPickUpPoint.value?.takePlaceId)
    currentParamsJson.put("receiver_name", receivingName.value)
    currentParamsJson.put("receiver_mobile", receivingPhone.value)
    currentParamsJson.put("comment", remark.value)
    OrderRemoteDataSource.requestCreateOrder(currentParamsJson) {
      if (it == null) {
        paymentEnable(true)
      } else {
        if (it.payment == 0) {// 0元单不用支付直接进订单详情
          _toOrderDetailEvent.value = it.orderId
        } else {
          toGetCharge(it.orderId)
        }
      }
    }
    commitClickBuriedPoint(3)
  }

  /**
   * 获取charge并进行支付
   */
  private fun toGetCharge(orderId: String?) {
    payOrderId = orderId
    val requestParams = HashMap<String, String?>()
    requestParams["order_id"] = orderId
    requestParams["pay_method_id"] = "105"// 微信 App 支付
    OrderRemoteDataSource.requestPayOrder(requestParams) {
      if (it == null) {
        paymentEnable(true)
      } else {
        // 调起支付
        _toPaymentEvent.value = Gson().toJson(it[0].v)
      }
    }
  }

  /**
   * 支付失败进行再次支付，需要使用上次的订单id,再次获取charge然后调用ping++
   */
  fun againToGetCharge() {
    toGetCharge(payOrderId)
  }

  /**
   * 支付结果
   */
  fun paymentSuccess() {
    // 支付成功打开订单详情
    _toOrderDetailEvent.value = payOrderId
  }

  /**
   * 立即支付按钮状态
   */
  fun paymentEnable(enable: Boolean) {
    _payEnableEvent.value = enable
  }

  /**
   * 页面浏览的埋点
   * 页面可见且有业务数据时上传
   */
  private fun commitPageBuriedPoint() {
    // 遍历商品列表
    val skuIdText = StringBuilder()
    val skuNameText = StringBuilder()
    val value = _goodsSuccessEvent.value
    value?.forEachIndexed { index, s ->
      skuIdText.append(s.goodsSkuId)
      skuNameText.append(s.goodsName)
      if (index < value.size - 1) {
        skuIdText.append(",")
        skuNameText.append(",")
      }
    }

    // 埋点数据包装
    val jsonObject = JSONObject()
    jsonObject.put("eventName", "EXPOSE_PAGE")
    val contextJsonObject = JSONObject()
    contextJsonObject.put("page", "ORDER_CONFIRMATION_PAGE")
    val smallOrderInfoJsonObject = JSONObject()
    smallOrderInfoJsonObject.put("marketing_id", marketingInfo?.marketingId)
    smallOrderInfoJsonObject.put("marketing_name", marketingInfo?.marketingName)
    smallOrderInfoJsonObject.put("marketing_type", "SPELL_MEAL")
    smallOrderInfoJsonObject.put("goods_sku_id", skuIdText.toString())
    smallOrderInfoJsonObject.put("goods_sku_name", skuNameText.toString())
    contextJsonObject.put("small_order_info", smallOrderInfoJsonObject)
    jsonObject.put("contextMap", contextJsonObject)
    val propertiesJsonObject = JSONObject()
    propertiesJsonObject.put("event_id", "SHQNG_R_1628749670667")
    jsonObject.put("propertiesMap", propertiesJsonObject)
    jsonObject.put("logType", 1)
    CPointUtils.performCommitLog(jsonObject)
  }

  /**
   * 点击按钮的埋点
   *
   * 点击： 1.返回按钮，则上报return_key; 2.选择自提点，则上报self_pick_up_site; 3.立即支付，则上报immediate_payment
   */
  fun commitClickBuriedPoint(weightKey: Int) {
    val jsonObject = JSONObject()
    jsonObject.put("eventName", "CLICK_WIDGET")
    val contextJsonObject = JSONObject()
    contextJsonObject.put("page", "ORDER_CONFIRMATION_PAGE")
    val smallOrderInfoJsonObject = JSONObject()
    smallOrderInfoJsonObject.put("marketing_id", marketingInfo?.marketingId)
    smallOrderInfoJsonObject.put("marketing_name", marketingInfo?.marketingName)
    smallOrderInfoJsonObject.put("marketing_type", "SPELL_MEAL")
    contextJsonObject.put("small_order_info", smallOrderInfoJsonObject)
    jsonObject.put("contextMap", contextJsonObject)
    val entitiesJsonObject = JSONObject()
    val widgetInfoJsonObject = JSONObject()
    widgetInfoJsonObject.put("widget_type", "BUTTON")
    var weightName = ""
    when (weightKey) {
      1 -> weightName = "return_key"
      2 -> weightName = "self_pick_up_site"
      3 -> weightName = "immediate_payment"
    }
    widgetInfoJsonObject.put("widget_name", weightName)
    entitiesJsonObject.put("widget_info", widgetInfoJsonObject)
    jsonObject.put("entitiesMap", entitiesJsonObject)
    val propertiesJsonObject = JSONObject()
    propertiesJsonObject.put("event_id", "SHQNG_R_1628749896356")
    jsonObject.put("propertiesMap", propertiesJsonObject)
    jsonObject.put("logType", 1)
    CPointUtils.performCommitLog(jsonObject)
  }

}
