package com.za.net

import android.content.Context
import android.graphics.BitmapFactory
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.ImageUtils
import com.za.base.Const
import com.za.bean.ImageBean
import com.za.bean.JpushBean
import com.za.bean.NewOrderRequestBean
import com.za.bean.db.ele.EleCarDamagePhotoBean
import com.za.bean.db.ele.EleWorkOrderBean
import com.za.bean.db.order.OrderInfo
import com.za.bean.db.order.PhotoTemplateInfo
import com.za.bean.request.ElectronOrderResponse
import com.za.bean.request.GeneralInfoRequest
import com.za.bean.request.OrderListRequest
import com.za.bean.request.PhotoTemplateRequest
import com.za.bean.request.QueryEleOrderRequest
import com.za.bean.request.UpdateTaskBean
import com.za.bean.request.UpdateTaskRequest
import com.za.bean.request.UploadGpsRequest
import com.za.common.GlobalData
import com.za.common.log.LogUtil
import com.za.common.util.DeviceUtil
import com.za.ext.toJson
import com.za.offline.OfflineManager
import com.za.room.RoomHelper
import com.za.room.db.user.DriverInfoBean
import com.za.ui.new_order.NewOrderActivity
import com.za.ui.order_report.ReportFloatingManager
import com.za.water_marker.WaterMarkerTemplateManager
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observer
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.schedulers.Schedulers
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.asRequestBody
import java.io.File

object CommonMethod {
	fun uploadGps(uploadGpsRequest : UploadGpsRequest,
		success : () -> Unit = {},
		failed : (String?) -> Unit = {}) {
		RetrofitHelper.getDefaultService().uploadGps(uploadGpsRequest).subscribeOn(Schedulers.io())
			.observeOn(AndroidSchedulers.mainThread()).subscribe(object : BaseObserver<String>() {
				override fun doSuccess(it : String?) {
					success()
					LogUtil.print("uploadGps", uploadGpsRequest.toString())
				}

				override fun doFailure(code : Int, msg : String?) {
					failed(msg)
					LogUtil.print("uploadGps", "failed==$msg")
				}
			})
	}

	fun uploadImage(file : File,
		preview : () -> Unit = {},
		success : (String?) -> Unit = {},
		failed : (String?) -> Unit = {}) {
		file.writeBytes(ImageUtils.compressByQuality(BitmapFactory.decodeStream(file.inputStream()),
			Const.Image_Max_length,
			true))
		val requestFile = file.asRequestBody("image/*".toMediaTypeOrNull())
		val body = MultipartBody.Part.createFormData("file", file.name, requestFile)
		preview()
		RetrofitHelper.getDefaultService().uploadImage(body).subscribeOn(Schedulers.io())
			.observeOn(AndroidSchedulers.mainThread()).subscribe(object : Observer<ImageBean> {
				override fun onSubscribe(d : Disposable) {

				}

				override fun onError(e : Throwable) {
					failed(e.message)
					LogUtil.print("uploadImage", e)
				}

				override fun onComplete() {

				}

				override fun onNext(t : ImageBean) {
					if (t.isOk()) {
						success(t.data)
						return
					}
					failed(t.msg)
					LogUtil.print("uploadImage failed", t.toJson() ?: "")
				}
			})
	}

	//更新订单状态
	fun updateTask(taskRequest : UpdateTaskRequest,
		success : (UpdateTaskBean?) -> Unit,
		failed : (String?, Int) -> Unit) {

		RetrofitHelper.getDefaultService().updateTask(taskRequest).subscribeOn(Schedulers.io())
			.observeOn(AndroidSchedulers.mainThread())
			.subscribe(object : BaseObserver<UpdateTaskBean>() {
				override fun doSuccess(it : UpdateTaskBean?) {
					success(it)
					LogUtil.print("updateTask", "success=$it  request=${taskRequest.toJson()}")
				}

				override fun doFailure(code : Int, msg : String?) {
					failed(msg, code)
					LogUtil.print("updateTask", "doFailure=$msg  request=${taskRequest.toJson()}")
				}
			})
	}


	private var lastFetchGenerateInfoTime : Long = 0L
	fun getGenerateInfo(vehicleId : Int? = null,
		userId : Int? = null,
		success : (DriverInfoBean) -> Unit = {},
		failed : (String?) -> Unit = {}) {
		val generalInfoRequest =
			GeneralInfoRequest(vehicleId = vehicleId ?: GlobalData.driverInfoBean?.vehicleId,
				driverId = userId ?: GlobalData.driverInfoBean?.userId,
				deviceId = DeviceUtil.getAndroidId(ActivityUtils.getTopActivity()))
		RetrofitHelper.getDefaultService().generalInfo(generalInfoRequest)
			.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
			.subscribe(object : BaseObserver<DriverInfoBean>() {
				override fun doSuccess(it : DriverInfoBean?) {
					if (it == null) {
						failed("获取车辆信息失败")
						LogUtil.print("getGenerateInfo", "获取车辆信息失败")
						return
					}
					if (GlobalData.driverInfoBean != null && (System.currentTimeMillis() - lastFetchGenerateInfoTime < 1000 * 10)) {
						LogUtil.print("getGenerateInfo",
							"获取车辆信息成功，但是时间间隔小于10秒，不更新车辆信息")
						success(it)
						return
					}
					GlobalData.driverInfoBean = it
					lastFetchGenerateInfoTime = System.currentTimeMillis()
					LogUtil.print("GlobalData.driverInfoBean",
						"${GlobalData.driverInfoBean?.toJson()}}")

					success(it)
				}

				override fun doFailure(code : Int, msg : String?) {
					failed(msg)
					LogUtil.print("getGenerateInfo",
						"doFailure=$msg  request=${generalInfoRequest.toJson()}")
				}
			})
	}

	fun getNewOrder(context : Context) {
		val newOrderRequestBean = NewOrderRequestBean(GlobalData.driverInfoBean?.vehicleId)
		RetrofitHelper.getDefaultService().getNewOrder(newOrderRequestBean)
			.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
			.subscribe(object : BaseObserver<JpushBean>() {
				override fun doSuccess(order : JpushBean?) {
					if (order == null) {
						return
					}
					NewOrderActivity.goNewOrderActivity(context,
						jpushBean = JpushBean(taskId = order.taskId,
							taskCode = order.taskCode,
							customerName = order.customerName,
							customerPhone = order.customerPhone,
							carBrand = order.carBrand,
							carModel = order.carModel,
							carNo = order.carNo,
							taskState = order.taskState,
							address = order.address,
							addressProperty = order.addressProperty,
							hotline = order.hotline,
							expectArriveTime = order.expectArriveTime,
							serviceTypeName = order.serviceTypeName,
							dispatchTime = order.dispatchTime,
							lat = order.lat,
							lng = order.lng,
							distLat = order.distLat,
							distLng = order.distLng,
							importantTip = order.importantTip,
							hasReplaceBatteryCapable = order.hasReplaceBatteryCapable,
							distAddress = order.distAddress,
							distAddressRemark = order.distAddressRemark,
							addressRemark = order.addressRemark,
							voiceType = order.voiceType))
				}

				override fun doFailure(code : Int, msg : String?) {

				}
			})
	}

	fun queryOrderList(context : Context? = null,
		success : (OrderInfo?, List<OrderInfo>?) -> Unit,
		failed : (String?) -> Unit) {
		RetrofitHelper.getDefaultService()
			.queryOrderList(OrderListRequest(vehicleId = GlobalData.driverInfoBean?.vehicleId,
				deviceId = DeviceUtil.getAndroidId(ActivityUtils.getTopActivity())))
			.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
			.subscribe(object : BaseObserver<List<OrderInfo>?>() {
				override fun doSuccess(it : List<OrderInfo>?) {
					LogUtil.print("queryOrderList", "${it.toJson()}")
					if (it.isNullOrEmpty()) {
						GlobalData.clearAllOrderCache()
						ReportFloatingManager.stopService()
						success(null, null)
						return
					}

					val inServicingOrder = it.find { it.isCurrent == true }
					val waitServiceOrders =
						it.filter { it.isCurrent == false && it.taskState != "ACCEPT" }

					if (inServicingOrder == null) {
						success(null, waitServiceOrders)
						return
					}

					GlobalData.currentOrder = inServicingOrder
					it.forEach {
						if (RoomHelper.db?.orderDao()
								?.getOrderInfoFromTaskId(it.taskId ?: 0) != null
						) {
							RoomHelper.db?.orderDao()?.update(orderInfo = it)
						} else {
							RoomHelper.db?.orderDao()?.insertOrder(orderInfo = it)
						}
					}
					fetchPhotoTemplate(inServicingOrder)
					queryElectronOrder(orderInfo = inServicingOrder)
					WaterMarkerTemplateManager.fetchWaterTemplate(inServicingOrder.taskCode ?: "",
						taskId = inServicingOrder.taskId ?: 0,
						inServicingOrder.userOrderId ?: 0)
					OfflineManager.start(GlobalData.currentOrder?.taskId)

					context?.let {
						ReportFloatingManager.startService(it)
					}

					success(inServicingOrder, waitServiceOrders)
				}

				override fun doFailure(code : Int, msg : String?) {
					val list = RoomHelper.db?.orderDao()?.getAllOrder()
					val inServicingOrder = list?.find { it.isCurrent == true }
					val waitServiceOrders = list?.filter { it.isCurrent == false }
					GlobalData.currentOrder = inServicingOrder
					success(inServicingOrder, waitServiceOrders)
					OfflineManager.start(GlobalData.currentOrder?.taskId)
					LogUtil.print("queryOrderList", "queryOrderList failed 是用离线数据==$msg")
				}
			})
	}

	fun fetchPhotoTemplate(orderInfo : OrderInfo?,
		success : () -> Unit = {},
		failed : (String?) -> Unit = {}) {
		val photoTemplateRequest = PhotoTemplateRequest(orderInfo?.userOrderId)
		RetrofitHelper.getDefaultService().fetchPhotoTemplate(photoTemplateRequest)
			.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
			.subscribe(object : BaseObserver<List<PhotoTemplateInfo>>() {
				override fun doSuccess(it : List<PhotoTemplateInfo>?) {
					if (it.isNullOrEmpty()) {
						LogUtil.print("fetchPhotoTemplate",
							"模板为null ${photoTemplateRequest.toJson()}")
						failed("未找到模版")
						return
					}

					val listData = RoomHelper.db?.photoTemplateDao()
						?.queryCurrentOrderHasTaskNode(orderInfo?.userOrderId ?: 0)
					if (! listData.isNullOrEmpty()) {
						LogUtil.print("queryPhotoTemplate", "模板已经存在==${listData.toJson()}")
						success()
						return
					}

					it.forEachIndexed { _, item ->
						val photoTemplateInfo = item.copy(userOrderId = orderInfo?.userOrderId,
							taskCode = orderInfo?.taskCode,
							myCustomPhotoType = Const.PhotoType.InServicing,
							advanceTime = orderInfo?.advanceTime,
							taskId = orderInfo?.taskId,
							needWaterMarker = orderInfo?.needWaterMarker,
							needShowPhoneBrand = orderInfo?.needShowPhoneBrand,
							photoSource = 0)
						RoomHelper.db?.photoTemplateDao()?.insert(photoTemplateInfo)
					}
					LogUtil.print("fetchPhotoTemplate", " ${it.toJson()}")
					success()
				}

				override fun doFailure(code : Int, msg : String?) {
					LogUtil.print("fetchPhotoTemplate", "err==$msg")
					failed(msg)
				}
			})
	}

	fun queryElectronOrder(orderInfo : OrderInfo?,
		success : (EleWorkOrderBean) -> Unit = {},
		failed : (String?) -> Unit = {}) {
		val ele = RoomHelper.db?.eleWorkOrderDao()?.getEleWorkOrder(taskId = orderInfo?.taskId ?: 0)
		if (ele != null) {
			success(ele)
			return
		}
		val queryEleOrderRequest = QueryEleOrderRequest(taskOrderId = orderInfo?.taskId,
			userOrderId = orderInfo?.userOrderId)
		RetrofitHelper.getDefaultService().queryElectronOrder(queryEleOrderRequest)
			.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
			.subscribe(object : BaseObserver<ElectronOrderResponse>() {
				override fun doSuccess(it : ElectronOrderResponse?) {
					val temp = EleWorkOrderBean(orderId = orderInfo?.taskId ?: 0,
						userOrderId = it?.userOrderId,
						date = it?.createTime,
						orderWorkStatus = it?.state,
						hasBad = it?.hasDamage == 1,
						serverCustomSignPath = it?.customerSignPath,
						carNO = it?.plateNumberBean?.value,
						carVin = it?.vinNo,
						serviceContent = it?.serviceTerm,
						serverAcceptCarSignPath = it?.recipientSignPath,
						serverServicePeopleSignPath = it?.waitstaffSignPath,
						orderType = it?.serviceName)
					it?.damageFileList?.forEach { item ->
						val damagePhotoBean = EleCarDamagePhotoBean(userOrderId = it.userOrderId,
							orderId = orderInfo?.taskId,
							isPhoto = true,
							uploadStatus = 1,
							serverPath = item)
						RoomHelper.db?.eleCarDamagePhotoDao()?.insert(damagePhotoBean)
					}
					RoomHelper.db?.eleWorkOrderDao()?.insertEleWorkOrder(temp)
					success(temp)
				}

				override fun doFailure(code : Int, msg : String?) {
					failed(msg)
				}
			})
	}

}