package com.gingersoft.gsa.delivery_pick_mode.data

import com.gingersoft.gsa.cloud.common.utils.gson.GsonUtils
import com.gingersoft.gsa.cloud.common.utils.other.TextUtil
import com.gingersoft.gsa.cloud.common.core.delivery.OrderDetails
import com.gingersoft.gsa.delivery_pick_mode.data.model.bean.ThirdItem
import com.gingersoft.gsa.delivery_pick_mode.data.model.bean.UpdateOrderStatusBean
import com.gingersoft.gsa.delivery_pick_mode.data.network.CoolWeatherNetwork
import com.google.gson.Gson
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.FormBody
import okhttp3.MediaType
import okhttp3.RequestBody
import kotlin.Pair as Pair1

class WeatherRepository private constructor(private val network: CoolWeatherNetwork) {


    suspend fun requestOrderList(restaurantId: String, status: String, type: String, page: String, orderNo: String, phone: String, appointmentType: Int) = withContext(Dispatchers.IO) {
        val requestBody = FormBody.Builder()
                .add("restaurantId", restaurantId)
                .add("page", page)
                .add("status", status)
                .add("orderNo", orderNo)
                .add("phone", phone)
                .add("type", type)
                .add("appointmentType", appointmentType.toString())
                .build()
        val heWeather = network.fetchOrderList(requestBody)
        heWeather
    }

    suspend fun getOrderGroup(restaurantId: String) = withContext(Dispatchers.IO) {
        val requestBody = FormBody.Builder()
                .add("restId", restaurantId)
                .build()
        network.getOrderGroupNum(requestBody)
    }

    suspend fun updateRestOpenStatus(state: Int, restaurantId: String) = withContext(Dispatchers.IO) {
        val requestBody = FormBody.Builder()
                .add("restId", restaurantId)
                .add("openStatus", state.toString())
                .build()
        val data = network.updateRestOpenStatus(requestBody)
        data
    }

    suspend fun getOrderInfo(orderId: String) = withContext(Dispatchers.IO) {
        val requestBody = FormBody.Builder()
                .add("orderId", orderId)
                .build()
        val data = network.getOrderInfo(requestBody)
        data
    }

    suspend fun getShipanyOrderTime(restaurantId: String, orderId: String, type: Int) = withContext(Dispatchers.IO) {
        val requestBody = FormBody.Builder()
                .add("orderId", orderId)
                .add("restaurantId", restaurantId)
                .add("type", type.toString())//1、預計整張訂單完成時間2、預計配送員接單時間3、預計配送員到店時間4、配送員預計送達時間
                .build()
        network.getShipanyOrderTime(requestBody)
    }


//    suspend fun updateOrderStatus(orderId: String, selfOrderId: String?, status: Int, mobile: String?, sender: String?, isPush: Int, orderType: Int) = withContext(Dispatchers.IO) {
//        val requestBody = FormBody.Builder()
//                .add("orderId", orderId)
//                .add("selfOrderId", selfOrderId)
//                .add("status", status.toString())
//                .add("mobile", mobile)
//                .add("sender", sender)
//                .add("isPush", isPush.toString())//1送貨  2確認訂單  結賬傳0
//                .add("orderType", orderType.toString())
//                .build()
//        val data = network.updateOrderStatus(requestBody)
//        data
//    }


    suspend fun gsUpdateOrderStatus(orderId: Int, status: Int, orderType: Int, type: Int, sendDate: String = "",
                                    sender: String = "", sendmobile: String = "", reasonId: String = "", reasonDesc: String = "",
                                    confirmationType: Int = 1, orderFrom: Int = 0) = withContext(Dispatchers.IO) {
        val requestBody = FormBody.Builder()
                .add("orderId", orderId.toString())//訂單id
                .add("status", status.toString())//订单状态#0:未支付;1:待確認(已支付, 待餐廳確認);2:制作中（餐廳确認）;3:派送中;4:确認收貨（完成）;5:是否評論;6:取消;
                .add("orderType", orderType.toString())//訂單類型#1:餐廳訂單;2:線上外賣訂單3:扫码点餐;4固定二维码订单;5:预点餐;6:積分訂單;7:自取订单'
                .add("type", type.toString())//通知類型：1.未定，2:外賣
                .add("sendDate", sendDate)//餐厅送达描述
                .add("sender", sender)//送餐員名字
                .add("sendmobile", sendmobile)//送餐員電話
                .add("reasonId", reasonId)//原因id
                .add("reasonDesc", reasonDesc)//原因描敘
                .add("confirmationType", confirmationType.toString())//接單類型，1 手動接單  2，自動接單
                .add("orderFrom", orderFrom.toString())//订单来源#1:ios;2:安卓;3:gspos;4:web;5:第三方POS A;6:第三方POS B;
                .build()
        network.gsUpdateOrderStatus(requestBody)
    }

    suspend fun updateOrderPay(orderId: Int, status: Int, orderType: Int, type: Int, sendDate: String = "",
                               sender: String = "", sendmobile: String = "", reasonId: String = "", reasonDesc: String = "",
                               confirmationType: Int = 1, orderFrom: Int = 0, orderPayInfoVO: List<OrderDetails.DataBean.PayMultiple>? = null) = withContext(Dispatchers.IO) {
        val updateOrderStatusBean = UpdateOrderStatusBean(orderFrom, orderId, orderPayInfoVO, sendDate, sender, sendmobile, status, type, orderType, reasonId, reasonDesc, confirmationType)
        val payRequest = GsonUtils.GsonString(updateOrderStatusBean)
        val requestBody = RequestBody.create(MediaType.parse("application/json"), payRequest)
        network.updateOrderPay(requestBody)
    }

    suspend fun updateIsRead(orderId: String) = withContext(Dispatchers.IO) {
        network.updateIsRead(getBody("id" to orderId))
    }


    suspend fun thirdDelivery(orderId: String, trafficType: String = "", thirdItem: ThirdItem) = withContext(Dispatchers.IO) {
        val requestBody = FormBody.Builder()
                .add("orderId", orderId)
                .add("items", Gson().toJson(thirdItem))
        if (TextUtil.isNotEmptyOrNullOrUndefined(trafficType)) {
            requestBody.add("trafficType", trafficType)//運輸類型 1摩托車 2麵包車 3卡車
        }
        network.thirdDelivery(requestBody.build())
    }

    suspend fun updateSelfOrderStatus(ids: String, status: String, restaurantId: String) = withContext(Dispatchers.IO) {
        val requestBody = FormBody.Builder()
                .add("ids", ids)
                .add("status", status)
                .add("restaurantId", restaurantId)
                .build()
        val data = network.updateSelfOrderStatus(requestBody)
        data
    }

    suspend fun getTransportationConfig(restaurantId: String) = withContext(Dispatchers.IO) {
        network.getTransportationConfig(restaurantId)
    }


    suspend fun additionalServiceCharge(uid: String, orderId: String, paymentValue: Int) = withContext(Dispatchers.IO) {
        network.additionalServiceCharge(getBody("uid" to uid, "orderId" to orderId, "paymentValue" to paymentValue.toString()))
    }

    suspend fun getBanlance(brandId: String) = withContext(Dispatchers.IO) {
        network.getBanlance(brandId)
    }

    suspend fun getActualAmount(orderId: String, uid: String, restaurantId: String) = withContext(Dispatchers.IO) {
        network.getActualAmount(orderId, uid, restaurantId)
    }

    suspend fun getDeliveryInfo(restId: String, userId: String) = withContext(Dispatchers.IO) {
        val requestBody = FormBody.Builder()
                .add("restId", restId)
                .add("userId", userId)
                .build()
        val data = network.getDeliveryInfo(requestBody)
        data
    }

    suspend fun getDeliveryConfigDTO(restaurantId: String) = withContext(Dispatchers.IO) {
        val requestBody = FormBody.Builder()
                .add("restaurantId", restaurantId)
                .build()
        network.getDeliveryConfigDTO(requestBody)
    }

    suspend fun cancelLogistics(restaurantId: String, orderId: String, reasonId: String, reasonDesc: String) = withContext(Dispatchers.IO) {
        network.cancelLogistics(getBody("restaurantId" to restaurantId, "orderId" to orderId, "reasonId" to reasonId, "reasonDesc" to reasonDesc))
    }

    suspend fun updateOrderStates(memberId: String, orderId: String, status: String, updateBy: String, reasonId: String, reasonDesc: String) = withContext(Dispatchers.IO) {
        network.cancelOrder(getBody("memberId" to memberId, "orderId" to orderId, "status" to status, "type" to "2", "updateBy" to updateBy, "reasonId" to reasonId, "reasonDesc" to reasonDesc))
    }

    suspend fun getCancelReason(brandId: Int, restaurantId: Int, type: Int) = withContext(Dispatchers.IO) {
        //        val requestBody = FormBody.Builder()
//                .add("brandId", brandId)
//                .add("restaurantId", restaurantId)
//                .add("type", type)//取消原因類型，1食品取消，2，物流取消，3，訂單取消
//                .build()
        network.getCancelReason(brandId, restaurantId, type)
    }

    suspend fun getPayMethod(brandId: Int, restaurantId: Int, payType: Int) = withContext(Dispatchers.IO) {
        network.getPayMethod(brandId, restaurantId, payType)
    }

    suspend fun addPrj(orderId: String, restaurantId: String, orderDetailsIds: String) = withContext(Dispatchers.IO) {
        network.addPrj(getBody("orderId" to orderId, "restaurantId" to restaurantId, "orderDetailsIds" to orderDetailsIds))
    }

    suspend fun getAdditionalByOrderId(orderId: String, deletes: String) = withContext(Dispatchers.IO) {
        network.getAdditionalByOrderId(orderId, deletes)
    }

    fun getBody(vararg pair: Pair1<String, String>): RequestBody {
        val requestBody = FormBody.Builder()
        requestBody.apply {
            pair.forEach {
                requestBody.add(it.first, it.second)
            }
        }
        return requestBody.build()
    }

    companion object {
        private lateinit var instance: WeatherRepository

        fun getInstance(network: CoolWeatherNetwork): WeatherRepository {
            if (!::instance.isInitialized) {
                synchronized(WeatherRepository::class.java) {
                    if (!::instance.isInitialized) {
                        instance = WeatherRepository(network)
                    }
                }
            }
            return instance
        }

    }

}