package com.ypsx.yppos.viewmodel.request

import androidx.lifecycle.MutableLiveData
import com.elvishew.xlog.XLog
import com.ypsx.base.base.viewmodel.BaseViewModel
import com.ypsx.base.ext.launch
import com.ypsx.base.ext.request
import com.ypsx.base.ext.requestNoCheck
import com.ypsx.base.ext.util.toJson
import com.ypsx.base.network.AppException
import com.ypsx.yppos.http.apiService
import com.ypsx.yppos.http.data.bean.*
import com.ypsx.yppos.http.data.entity.PosPayMethod
import com.ypsx.yppos.http.data.entity.ProductActivityType
import com.ypsx.yppos.http.data.request.*
import com.ypsx.yppos.http.repository.request.HttpRequestCoroutine
import com.ypsx.yppos.http.state.UpdateUiState
import com.ypsx.yppos.room.entity.PosBuyPart
import com.ypsx.yppos.room.entity.PosConfig
import com.ypsx.yppos.room.entity.PosProduct
import com.ypsx.yppos.room.repository.PosBuyRepository
import com.ypsx.yppos.room.repository.PosConfigRepository
import com.ypsx.yppos.room.repository.PosProductRepository
import com.ypsx.yppos.utils.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap

/**
 * 本地扫描条码，如果是称重码，则搜索称重码商品，
 */
class RequestMainViewModel : BaseViewModel() {

    //    var productPromotionRequest = MutableLiveData<ProductPromotionRequest>()
    var productItemData = MutableLiveData<ProductItem>()
    var productPromotionsResponse = MutableLiveData<ProductPromotionsResponse>()
    var posBuyPartData = MutableLiveData<List<PosBuyPart>>()
    var posBuyPartList = MutableLiveData<MutableList<InsertOrderProductDTO>>()
    var payAmountBean = MutableLiveData<PayAmountBean>()
    var map = HashMap<String, String>()
    var posConfig: PosConfig? = null
    var orderPromotions: List<OrderActivityResponse>? = null
    var payState = MutableLiveData<UpdateUiState<UploadOrderResponse>>()

    val paySuccessState = MutableLiveData<UpdateUiState<String>>()


    init {
        launch({ PosConfigRepository.getInstance().loadConfig() }, {
            posConfig = it
        })
    }


    fun getPlu(barCode: String) {
        val plu = barCode.substring(2, 7)
        val weight = barCode.substring(7, 12)
        val weightCode: Double = weight.toDouble().div(1000)
        val mnemonicCode = plu.toInt().toString()
        "$mnemonicCode $weightCode".dXLog()

        launch({ PosProductRepository.getInstance().queryByMnemonicCode(mnemonicCode) }, {
            if (it == null) {
                "没找到该商品".toastSign()
            } else {
                it.toJson().dXLog()
                map[it.id] = barCode
                val productItem = ProductItem(it.merchantItemId!!, it.id, weightCode, it.sellPrice)
                productItem.toJson().dXLog()

                productItemData.postValue(productItem)
            }
        }, {

        })
    }

    fun getKeyWords(key: String) {
        if (key.isEmpty()) {
            "搜索商品条码/PLU".toast()
            return
        }
        launch({ PosProductRepository.getInstance().queryKeyWords(key) }, {
            if (it == null) {
                "没找到该商品".toastSign()
            } else {
                it.toJson().dXLog()
                val productItem =
                    ProductItem(it.merchantItemId!!, it.id, it.spec.toDouble(), it.sellPrice)
                productItem.toJson().dXLog()
                productItemData.postValue(productItem)
            }
        }, {

        }

        )
    }

    fun request(request: ProductPromotionRequest) {
        request({ apiService.getProductPromotions(request) }, {
            "操作成功".toastSuccess()
            productPromotionsResponse.postValue(it)
        }, {
            it.errorMsg.toastFailed()
            orderPromotions = null
            errorAllIn(request)
        })
    }

    private fun errorAllIn(request: ProductPromotionRequest) {
        val products = request.products
        val list = ArrayList<String>(products.size)
        for (item in products) {
            list.add(item.productId)
        }

        launch({ PosProductRepository.getInstance().queryAllIn(list) }, {
            var list = mutableListOf<InsertOrderProductDTO>()
            var posProduct: PosProduct? = null

            var amountTotal = 0.0 //总价值
            for (product in products) {
                for (item in it) {
                    if (product.productId == item.id) {
                        posProduct = item
                        break
                    }
                }
                val amount: Double = product.price.times(product.quantity) ?: 0.0
                amountTotal = BigDecimalUtils.forPlus(amountTotal.plus(amount))


                val posBuyPart = InsertOrderProductDTO(
                    activitys = null,
                    activityPrice = 0.0,
                    amount = amount ?: 0.0,
                    discountTotal = 0.0,
                    memberPrice = 0.0,
                    barCode = posProduct?.barCode!!,
                    cardNumber = null,
                    conversionRatio = posProduct.conversionRatio,
                    deleted = false,
                    priceType = "SALE_TYPE",
                    productId = posProduct.id,
                    price = product.price ?: 0.0,
                    quantity = product.quantity ?: 0.0,
                    tailAmount = 0,
                    weightCode = map[posProduct.id],
                    name = posProduct.name,
                    spec = posProduct.spec,
                    unit = posProduct.unit,
                    style = posProduct.style,
                    pluLevel = posProduct.pluLevel,
                    merchantItemId = posProduct.merchantItemId,
                    productNumber = posProduct.productNumber
                )
                posBuyPart.toJson().dXLog()
                list.add(posBuyPart)
            }
            posBuyPartList.postValue(list)
            payAmountBean.postValue(
                PayAmountBean(
                    payApportionAmount = amountTotal,
                    amount = amountTotal
                )
            )
        })
    }

    fun queryAllIn(productPromotionsResponse: ProductPromotionsResponse) {
        orderPromotions = productPromotionsResponse.orderPromotions

        var discountTotal = 0.0
        var payApportionAmount = 0.0
        var discountMoney = 0.0 //满减促销
        var discountTime = 0.0//分时促销
        var discountSpecial = 0.0//特价促销
        var amount = 0.0 //总价值

        productPromotionsResponse.orderPromotions?.forEach { item ->
            discountMoney += item.discountMoney
        }
        productPromotionsResponse.productPromotions.forEach { item ->
            amount = amount.plus(item.price.times(item.quantity))
            payApportionAmount = payApportionAmount.plus(item.payApportionAmount)
            if (item.activityInfo != null) {
                if (item.activityInfo?.activityType == ProductActivityType.TIMESHARE_ACTIVITY.name) {
                    discountTime += item.discountTotal
                } else {
                    if (item.activityInfo?.activityPrice!! > 0.0) {
                        discountSpecial += item.discountTotal
                    }
                }
            }
        }
        discountTotal = discountMoney + discountSpecial + discountTime
        payAmountBean.postValue(
            PayAmountBean(
                BigDecimalUtils.forPlus(discountTotal),
                BigDecimalUtils.forPlus( payApportionAmount),
                BigDecimalUtils.forPlus(discountMoney),
                BigDecimalUtils.forPlus(discountTime),
                BigDecimalUtils.forPlus(discountSpecial),
                BigDecimalUtils.forPlus(amount)
            )
        )
        val productPromotions = productPromotionsResponse.productPromotions
        val list = ArrayList<String>(productPromotions.size)
        for (item in productPromotions) {
            list.add(item.productId)
        }
        launch({ PosProductRepository.getInstance().queryAllIn(list) }, {
            var list = mutableListOf<InsertOrderProductDTO>()
            XLog.d("数量大小：${list.size}")
            var posProduct: PosProduct? = null
            for (product in productPromotions) {
                for (item in it) {
                    if (product.productId == item.id) {
                        posProduct = item
                        break
                    }
                }
                var isPromotion = false
                if (!orderPromotions.isNullOrEmpty()) {
                    for (orderPromotion in orderPromotions!!) {
                        for (productPromotionDetailDTO in orderPromotion.productIds) {
                            if (productPromotionDetailDTO.productId == product.productId) {
                                isPromotion = true
                                break
                            }
                        }
                    }

                }
                var activityInfo = product.activityInfo
                var activitys:ArrayList<ActivityInfoDTO> = arrayListOf()
                if (activityInfo != null) {
                    activitys.add(activityInfo)
                }
                var activityPrice = activityInfo?.activityPrice ?: 0.0
                val posBuyPart = InsertOrderProductDTO(
                    activitys = activitys,
                    activityPrice = activityPrice,
                    amount = product.payApportionAmount ?: 0.0,
                    discountTotal = product.discountTotal ?: 0.0,
                    discountPrice = product.discountTotal.div(product.quantity),
                    memberPrice = product.memberPrice ?: 0.0,
                    barCode = posProduct?.barCode!!,
                    cardNumber = null,
                    conversionRatio = posProduct.conversionRatio,
                    deleted = false,
                    priceType = product.priceType ?: "SALE_TYPE",
                    productId = posProduct.id,
                    price = product.price ?: 0.0,
                    quantity = product.quantity ?: 0.0,
                    tailAmount = 0,
                    weightCode = map[posProduct.id],
                    name = posProduct.name,
                    spec = posProduct.spec,
                    unit = posProduct.unit,
                    style = posProduct.style,
                    pluLevel = posProduct.pluLevel,
                    merchantItemId = posProduct.merchantItemId,
                    productNumber = posProduct.productNumber,
                    payApportionAmount = product.payApportionAmount,
                    isPromotion = isPromotion,
                    isVirtual = posProduct.isVirtual
                )
                posBuyPart.toJson().dXLog()
                list.add(posBuyPart)
            }
            posBuyPartList.postValue(list)
        })
    }

    /**
     * 创建订单并支付
     */
    fun createOrder(
        orderNo: String,
        totalAmount: Double,
        payAmount: Double,
        promotionOnSaleTotal: Double,
        discountTotal: Double,
        productList: List<InsertOrderProductDTO>,
        payMethod: PosPayMethod,
        barcode: String
    ) {
        val loginResponse = CacheUtil.getLoginResponse()
        val insertOrderRequest = InsertOrderRequest(
            activitys = orderPromotions,
            createTime = DateUtil.getTodayDateTime(),
            creatorId = loginResponse!!.loginUser.username ?: "",
            creatorName = loginResponse.loginUser.realName ?: "",
            orderNo = orderNo,
            einvoiceQrcodeUrl = "",
            memberId = "",
            mobile = "",
            posId = posConfig?.id ?: "",
            storeId = posConfig?.storeId ?: "",
            status = "CREATED",
            products = productList,
            totalAmount = totalAmount,
            promotionOnSaleTotal = promotionOnSaleTotal,
            discountTotal = discountTotal,
            payAmount = payAmount,
        )
        requestNoCheck({
            HttpRequestCoroutine.createOrder(insertOrderRequest, barcode, payMethod)
        }, {
            val uiState = UpdateUiState(isSuccess = true, it)
            payState.postValue(uiState)
        }, {
            val uiState = UpdateUiState(isSuccess = false, data = "", it.errorMsg)
            paySuccessState.postValue(uiState)
        })
    }

    /**
     * 每隔2s轮询一次，获取支付订单状态
     */
    fun getStateByOrderId(orderId: String, totalAmount: Double, authCode: String) {
        request({ HttpRequestCoroutine.getOrderStatusById(orderId) }, {
            getOrderDetailById(orderId, authCode)
            val uiState = UpdateUiState(isSuccess = true, totalAmount.toString())
            paySuccessState.postValue(uiState)
        }, {
            if (it.errCode == 100001) {
                //付款超时
                return@request
            }
            val uiState = UpdateUiState(isSuccess = false, data = "", errorMsg = it.errorMsg)
            paySuccessState.postValue(uiState)
        })
    }


    /**
     * 获取订单详情，并保存数据库打印小票
     */
    private fun getOrderDetailById(orderId: String, authCode: String) {
        request({ apiService.getOrderDetailById(orderId) }, {
            "${CacheUtil.getRealName()}付款成功，保存数据库并打印".dXLog()
            launch({
                PrintUtils.print(posConfig!!, it)
                PosBuyRepository.getInstance().savePosBuy(it, authCode)
            }, {
                "打印完成".dXLog()
                "打印完成".toastSuccess()
            })

        })
    }


    /**
     * 获取阿里云配置
     */
    fun getOptions() {
        request({ apiService.getOptionsByKeys() }, {
            for (optionsResponse in it) {
                CacheUtil.setAliYunKey(optionsResponse.key, optionsResponse.value)
            }
        }, {
            CacheUtil.setAliYunKey(dfs_aliyunAccessKeyId, "")
            CacheUtil.setAliYunKey(dfs_aliyunAccessKeySecret, "")
            CacheUtil.setAliYunKey(dfs_aliyunBucketName, "")
            CacheUtil.setAliYunKey(dfs_aliyunDomain, "")
            CacheUtil.setAliYunKey(dfs_aliyunEndPoint, "")
            CacheUtil.setAliYunKey(dfs_aliyunPrefix, "")
        })
    }





}