package com.za.ui.servicing.ele_check

import com.blankj.utilcode.util.TimeUtils
import com.blankj.utilcode.util.ToastUtils
import com.za.base.Const
import com.za.base.IServicingVm
import com.za.base.view.LoadingManager
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.request.SaveEleOrderRequest
import com.za.bean.request.UpdateTaskBean
import com.za.common.GlobalData
import com.za.common.log.LogUtil
import com.za.ext.toJson
import com.za.net.BaseObserver
import com.za.net.CommonMethod
import com.za.net.RetrofitHelper
import com.za.offline.OfflineUpdateTaskBean
import com.za.room.RoomHelper
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.flow.MutableStateFlow
import java.io.File
import java.util.Date

class EleSignCheckVm : IServicingVm<EleSignCheckVm.Action, EleSignCheckVm.UiState>() {
    private val _uiState = MutableStateFlow(UiState())
    val uiState get() = _uiState
    override fun updateState(uiState: UiState) {
        _uiState.value = uiState
    }

    override fun dispatch(action: Action) {
        when (action) {
            is Action.Init -> init()
            is Action.UpdateState -> updateState(action.uiState)
            is Action.ChangeDamageState -> changeDamageState(action.hasDamage)
            is Action.AddDamagePhoto -> addDamagePhoto(action.path)
            is Action.ReUploadPhoto -> reUploadPhoto(action.eleCarDamagePhotoBean)
            is Action.Upload -> upload()
            is Action.UploadOffline -> uploadOffline()
        }
    }


    private fun uploadOffline() {
        val eleWorkOrderBean = RoomHelper.db?.eleWorkOrderDao()?.getEleWorkOrder(GlobalData.currentOrder?.taskId
            ?: 0)
        if (eleWorkOrderBean == null) {
            ToastUtils.showLong("数据获取失败，请返回首页重试！")
            return
        }
        val photos = RoomHelper.db?.eleCarDamagePhotoDao()?.getEleCarDamagePhotos(GlobalData.currentOrder?.taskId
            ?: 0)

        var list: ArrayList<String?>? = null
        if (!photos.isNullOrEmpty()) {
            list = arrayListOf()
            photos.forEachIndexed { index, eleCarDamagePhotoBean ->
                if (eleCarDamagePhotoBean.serverPath.isNullOrBlank() && !eleCarDamagePhotoBean.path.isNullOrBlank()) {
                    val offlineUpdateTaskBean = OfflineUpdateTaskBean(
                        imageLocalPath = eleCarDamagePhotoBean.path,
                        imageIndex = index, eleState = 1,
                        userOrderId = GlobalData.currentOrder?.userOrderId,
                        taskId = getCurrentOrder()?.taskId,
                        taskCode = getCurrentOrder()?.taskCode,
                        offlineTitle = "损伤照片-$index",
                        offlineType = 4)
                    insertOfflineTask(offlineUpdateTaskBean)
                    list.add(null)
                } else {
                    list.add(eleCarDamagePhotoBean.serverPath)
                }
            }
        }

        val offlineEleWorkOrderBean = OfflineUpdateTaskBean(eleState = 1,
            userOrderId = getCurrentOrder()?.userOrderId,
            taskId = getCurrentOrder()?.taskId,
            damageFileList = list,
            hasDamage = if (uiState.value.eleWorkOrderBean?.hasBad == true) {
                1
            } else {
                2
            },
            offlineType = 3,
            offlineTitle = "现场验车-电子工单损伤照片")
        insertOfflineTask(offlineEleWorkOrderBean)

        val ele = eleWorkOrderBean.copy(orderWorkStatus = 1)
        RoomHelper.db?.eleWorkOrderDao()?.update(ele)
        updateState(uiState.value.copy(goNextPage = UpdateTaskBean(GlobalData.currentOrder?.taskState)))
    }

    private fun upload() {
        val eleWorkOrderBean = RoomHelper.db?.eleWorkOrderDao()?.getEleWorkOrder(GlobalData.currentOrder?.taskId
            ?: 0)
        if (eleWorkOrderBean == null) {
            ToastUtils.showLong("数据获取失败，请返回首页重试！")
            return
        }
        val photos = RoomHelper.db?.eleCarDamagePhotoDao()?.getEleCarDamagePhotos(GlobalData.currentOrder?.taskId
            ?: 0)

        if (eleWorkOrderBean.hasBad == true && photos.isNullOrEmpty()) {
            ToastUtils.showLong("请先拍摄损伤照片！")
            return
        }
        var list: ArrayList<String>? = null
        if (!photos.isNullOrEmpty()) {
            list = arrayListOf()
            photos.forEach {
                if (!it.serverPath.isNullOrBlank()) {
                    list.add(it.serverPath)
                }
            }
        }

        val saveEleOrderRequest = SaveEleOrderRequest(
            state = 1,
            userOrderId = GlobalData.currentOrder?.userOrderId,
            taskOrderId = GlobalData.currentOrder?.taskId,
            damageFileList = list,
            hasDamage = if (uiState.value.eleWorkOrderBean?.hasBad == true) {
                1
            } else {
                2
            },
        )

        if (!getCurrentOrderOfflineTask().isNullOrEmpty()) {
            uploadOffline()
            return
        }

        LoadingManager.showLoading()
        LogUtil.print("eleSign_check upload request", saveEleOrderRequest.toJson() ?: "")
        RetrofitHelper.getDefaultService().saveElectronOrder(saveEleOrderRequest)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : BaseObserver<String>() {
                override fun doSuccess(it: String?) {
                    LoadingManager.hideLoading()
                    updateCurrentEleWorkOrder(eleWorkOrderBean.copy(orderWorkStatus = 1))
                    updateState(uiState.value.copy(goNextPage = UpdateTaskBean(getCurrentOrder()?.taskState), orderInfo = getCurrentOrder()))
                }

                override fun doFailure(code: Int, msg: String?) {
                    LoadingManager.hideLoading()
                    ToastUtils.showLong(msg)
                    if (code == Const.NetWorkException) {
                        updateState(uiState.value.copy(showOfflineDialog = true))
                    }
                    LogUtil.print("eleSign_check upload failed", msg ?: "")
                }
            })
    }

    private fun reUploadPhoto(eleCarDamagePhotoBean: EleCarDamagePhotoBean) {
        if (eleCarDamagePhotoBean.path.isNullOrBlank()) {
            RoomHelper.db?.eleCarDamagePhotoDao()?.insert(eleCarDamagePhotoBean.copy(path = null, uploadStatus = null, serverPath = null))
            return
        }
        RoomHelper.db?.eleCarDamagePhotoDao()?.insert(eleCarDamagePhotoBean)
        updateState(uiState.value.copy(damagePhoto = RoomHelper.db?.eleCarDamagePhotoDao()
            ?.getEleCarDamagePhotos(GlobalData.currentOrder?.taskId ?: 0)))
        CommonMethod.uploadImage(file = File(eleCarDamagePhotoBean.path),
            success = {
                RoomHelper.db?.eleCarDamagePhotoDao()?.update(eleCarDamagePhotoBean.copy(uploadStatus = 1, serverPath = it))
                updateState(uiState.value.copy(damagePhoto = RoomHelper.db?.eleCarDamagePhotoDao()
                    ?.getEleCarDamagePhotos(GlobalData.currentOrder?.taskId ?: 0)))
            }, failed = {
                RoomHelper.db?.eleCarDamagePhotoDao()?.update(eleCarDamagePhotoBean.copy(uploadStatus = 3))
                updateState(uiState.value.copy(damagePhoto = RoomHelper.db?.eleCarDamagePhotoDao()
                    ?.getEleCarDamagePhotos(GlobalData.currentOrder?.taskId ?: 0)))
                LogUtil.print("addDamagePhoto failed", it ?: "")
            })
    }

    private fun addDamagePhoto(localPath: String) {
        val eleCarDamagePhotoBean = EleCarDamagePhotoBean(
            path = localPath,
            orderId = GlobalData.currentOrder?.taskId,
            uploadStatus = 2,
            userOrderId = GlobalData.currentOrder?.userOrderId,
            isPhoto = true)
        var list = uiState.value.damagePhoto
        if (list.isNullOrEmpty()) {
            list = arrayListOf(eleCarDamagePhotoBean)
        } else {
            list.plus(eleCarDamagePhotoBean)
        }
        updateState(uiState.value.copy(damagePhoto = list))
        CommonMethod.uploadImage(file = File(localPath),
            success = {
                RoomHelper.db?.eleCarDamagePhotoDao()?.insert(eleCarDamagePhotoBean.copy(uploadStatus = 1, serverPath = it))
                updateState(uiState.value.copy(damagePhoto = RoomHelper.db?.eleCarDamagePhotoDao()
                    ?.getEleCarDamagePhotos(GlobalData.currentOrder?.taskId ?: 0)))
            }, failed = {
                RoomHelper.db?.eleCarDamagePhotoDao()?.insert(eleCarDamagePhotoBean.copy(uploadStatus = 3))
                updateState(uiState.value.copy(damagePhoto = RoomHelper.db?.eleCarDamagePhotoDao()
                    ?.getEleCarDamagePhotos(GlobalData.currentOrder?.taskId ?: 0)))
                LogUtil.print("addDamagePhoto failed", it ?: "")
            })
    }

    private fun changeDamageState(hasDamage: Boolean?) {
        uiState.value.eleWorkOrderBean?.copy(hasBad = hasDamage)?.let {
            updateState(uiState.value.copy(eleWorkOrderBean = it))
            RoomHelper.db?.eleWorkOrderDao()?.update(it)
        }
    }

    private fun init() {
        val eleWorkOrderDao = RoomHelper.db?.eleWorkOrderDao()
        var eleWorkOrderBean = eleWorkOrderDao?.getEleWorkOrder(GlobalData.currentOrder?.taskId
            ?: 0)
        val photoList = RoomHelper.db?.eleCarDamagePhotoDao()?.getEleCarDamagePhotos(GlobalData.currentOrder?.taskId
            ?: 0)

        if (eleWorkOrderBean == null) {
            try {
                var carVin = GlobalData.currentOrder?.carVin ?: ""
                if (carVin.length > 6) {
                    carVin = carVin.substring(carVin.length - 6)
                }
                eleWorkOrderBean = EleWorkOrderBean(
                    orderId = GlobalData.currentOrder?.taskId ?: 0,
                    userOrderId = GlobalData.currentOrder?.userOrderId,
                    carNO = GlobalData.currentOrder?.carNo,
                    date = TimeUtils.date2String(Date(), "yyyy-MM-dd"),
                    carVin = carVin,
                    orderType = GlobalData.currentOrder?.serviceTypeName)
                eleWorkOrderDao?.insertEleWorkOrder(eleWorkOrderBean)
                updateState(uiState.value.copy(eleWorkOrderBean = eleWorkOrderBean, damagePhoto = photoList, orderInfo = getCurrentOrder()))
                LogUtil.print("EleSignCheckVm init 电子表单创建成功", "eleWorkOrderBean==$eleWorkOrderBean")
            } catch (e: Exception) {
                LogUtil.print("EleSignCheckVm init 电子表单创建异常", e)
            }
        } else {
            updateState(uiState.value.copy(eleWorkOrderBean = eleWorkOrderBean, damagePhoto = photoList, orderInfo = getCurrentOrder()))
            LogUtil.print("电子表单更新车辆损伤状况", "eleWorkOrderBean==$eleWorkOrderBean")
        }
    }

    sealed class Action {
        data object Init : Action()
        data class ChangeDamageState(val hasDamage: Boolean) : Action()
        data class UpdateState(val uiState: UiState) : Action()
        data class AddDamagePhoto(val path: String) : Action()
        data class ReUploadPhoto(val eleCarDamagePhotoBean: EleCarDamagePhotoBean) : Action()
        data object Upload : Action()
        data object UploadOffline : Action()
    }

    data class UiState(
        val orderInfo: OrderInfo? = null,
        val eleWorkOrderBean: EleWorkOrderBean? = null,
        val goNextPage: UpdateTaskBean? = null,
        val isGoNextPageDialog: Boolean? = null,
        val showCallPhoneDialog: Boolean? = null,
        val showOfflineDialog: Boolean? = null,
        val damagePhoto: List<EleCarDamagePhotoBean>? = null,
    )
}