package es.verdnatura.presentation.view.feature.inventario.fragment

import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.map
import com.google.gson.JsonObject
import es.verdnatura.MobileApplication
import es.verdnatura.domain.SalixCallback
import es.verdnatura.domain.userCases.GetItemFromBarcodeUseCase
import es.verdnatura.presentation.base.BaseViewModel
import es.verdnatura.presentation.common.Event
import es.verdnatura.presentation.common.ItemDiscardSalixShortage
import es.verdnatura.presentation.view.feature.calidad.model.BuyerListVO
import es.verdnatura.presentation.view.feature.calidad.model.BuyerVO
import es.verdnatura.presentation.view.feature.inventario.model.InventaryListVO
import es.verdnatura.presentation.view.feature.inventario.model.InventoryParkingList
import es.verdnatura.presentation.view.feature.inventario.model.ItemInventaryVO
import es.verdnatura.presentation.view.feature.inventario.model.ItemInventoryParking
import es.verdnatura.presentation.view.feature.ubicador.model.ItemUbicador
import es.verdnatura.presentation.view.feature.workermistake.model.DepartmentMistake
import es.verdnatura.presentation.view.feature.workermistake.model.DepartmentMistakeList
import es.verdnatura.presentation.view.feature.workermistake.model.ExpeditionMistakeSalix
import es.verdnatura.presentation.view.feature.workermistake.model.MistakeType
import es.verdnatura.presentation.view.feature.workermistake.model.WorkerFromMistake
import es.verdnatura.presentation.view.feature.workermistake.model.WorkerFromMistakeList
import es.verdnatura.presentation.view.feature.workermistake.model.WorkerMistakeSalix
import es.verdnatura.presentation.view.feature.workermistake.model.WorkerMistakeTypeList
import retrofit2.Response

class InventaryViewModel(val context: Context) : BaseViewModel(context) {
    private val getItemFromBarcodeUseCase = GetItemFromBarcodeUseCase(salix)
    private val _inventaryList by lazy { MutableLiveData<InventaryListVO>() }
    val inventaryList: LiveData<InventaryListVO>
        get() = _inventaryList

    private val _response by lazy { MutableLiveData<Boolean>() }
    val response: LiveData<Boolean>
        get() = _response

    private val _responseReset by lazy { MutableLiveData<String>() }
    val responseReset: LiveData<String>
        get() = _responseReset

    private val _buyersList by lazy { MutableLiveData<BuyerListVO>() }
    val buyersList: LiveData<BuyerListVO>
        get() = _buyersList

    private val _mistakeDepartmentList by lazy { MutableLiveData<DepartmentMistakeList>() }
    val mistakeDepartmentList: LiveData<DepartmentMistakeList>
        get() = _mistakeDepartmentList

    private val _workerFromMistakeList by lazy { MutableLiveData<WorkerFromMistakeList>() }
    val workerFromMistakeList: LiveData<WorkerFromMistakeList>
        get() = _workerFromMistakeList

    private val _mistakeWorkerList by lazy { MutableLiveData<WorkerMistakeTypeList>() }
    val mistakeWorkerList: LiveData<WorkerMistakeTypeList>
        get() = _mistakeWorkerList

    private val _inventoryListParking by lazy { MutableLiveData<InventoryParkingList>() }
    val inventoryListParking: LiveData<InventoryParkingList>
        get() = _inventoryListParking
    val loadInventaryParkingList: LiveData<Event<InventoryParkingList>> =
        _inventoryListParking.map { Event(it) }

    private val _responseCode by lazy { MutableLiveData<Int?>() }
    val responseCode: LiveData<Int?>
        get() = _responseCode
    val loadReponseCode: LiveData<Event<Int?>> = _responseCode.map { Event(it) }

    //sergio para obtener comprador
    fun itemShelvingBuyerGet() {
        salix.getBuyers("""{"order":"nickname"}""")
            .enqueue(object : SalixCallback<List<BuyerVO>>(context) {
                override fun onSuccess(response: Response<List<BuyerVO>>) {
                    _buyersList.value = response.body()?.let { BuyerListVO(it) }
                }

            })
    }

    val loadInventaryList: LiveData<Event<InventaryListVO>> = _inventaryList.map { Event(it) }

    fun getInventory(buyerFk: Int, warehouseFk: Int) {
        salix.itemShelvingFilterBuyer(params = arrayListOf(buyerFk, warehouseFk))
            .enqueue(object : SalixCallback<List<ItemInventaryVO>>(context) {
                override fun onSuccess(response: Response<List<ItemInventaryVO>>) {
                    _inventaryList.value = response.body()?.let { InventaryListVO(it) }
                }

            })
    }

    fun itemShelvingUpdate(
        itemShelvingFk: Long,
        params: Any,

        ) {

        salix.itemShelvingUpdate(itemShelvingFk, params)
            .enqueue(object : SalixCallback<ItemUbicador?>(context) {
                override fun onSuccess(response: Response<ItemUbicador?>) {
                    _responseReset.value = response.message()
                    super.onSuccess(response)
                }

            })
    }

    fun itemShelvingsReset(
        where: JsonObject,
        params: Any,

        ) {

        salix.itemShelvingsUpdate(where, params).enqueue(object : SalixCallback<Any>(context) {

            override fun onSuccess(response: Response<Any>) {
                _responseReset.value = response.message()
                super.onSuccess(response)
            }

        })
    }

    fun itemSetVisibleDiscard(
        itemFk: Int, warehouseFk: Int, newValue: Int
    ) {

        salix.setVisibleDiscard(ItemDiscardSalixShortage(itemFk, warehouseFk, newValue, null))
            .enqueue(object : SalixCallback<Any>(context) {
                override fun onSuccess(response: Response<Any>) {
                    _response.value = true
                }
            })
    }

    fun departmentGetHasMistake() {
        salix.departmentGetHasMistake()
            .enqueue(object : SalixCallback<List<DepartmentMistake>>(context) {
                override fun onSuccess(response: Response<List<DepartmentMistake>>) {
                    _mistakeDepartmentList.value =
                        response.body()?.let { DepartmentMistakeList(it) }
                }
            })
    }

    fun workerGetFromHasMistake(departmentFk: Int) {
        salix.workerGetFromHasMistake(arrayListOf(departmentFk))
            .enqueue(object : SalixCallback<List<WorkerFromMistake>>(context) {
                override fun onSuccess(response: Response<List<WorkerFromMistake>>) {
                    _workerFromMistakeList.value =
                        response.body()?.let { WorkerFromMistakeList(it) }
                }

            })
    }

    fun workerMistakeTypeGet() {
        salix.workerMistakesTypes().enqueue(object : SalixCallback<List<MistakeType>>(context) {

            override fun onSuccess(response: Response<List<MistakeType>>) {
                _mistakeWorkerList.value = response.body()?.let { WorkerMistakeTypeList(it) }

            }

        })
    }

    fun workerMistakeAdd(
        vUserFk: Int, vTypeFk: String
    ) {
        salix.workerMistakesAdd(WorkerMistakeSalix(vUserFk, vTypeFk))
            .enqueue(object : SalixCallback<Any>(context) {})
    }

    fun expeditionMistakeAdd(
        vExpeditionFk: Int,
        vTypeFk: String,
    ) {
        salix.expeditionMistakesAdd(
            ExpeditionMistakeSalix(
                expeditionFk = vExpeditionFk,
                typeFk = vTypeFk,
                workerFk = (context as MobileApplication).userId!!
            )
        ).enqueue(object : SalixCallback<Any>(context) {
        })
    }

    fun getInventoryParking(
        vParkingFrom: String, vParkingTo: String
    ) {

        salix.getInventoryParking(vParkingFrom, vParkingTo)
            .enqueue(object : SalixCallback<List<ItemInventoryParking>>(context) {

                override fun onSuccess(response: Response<List<ItemInventoryParking>>) {

                    _inventoryListParking.value =
                        response.body()?.let { InventoryParkingList(it) }

                }

            })
    }

    fun expeditionMistakeTypeGet() {
        salix.getExpeditionMistakeTypes()
            .enqueue(object : SalixCallback<List<MistakeType>>(context) {

                override fun onSuccess(response: Response<List<MistakeType>>) {
                    _mistakeWorkerList.value =
                        response.body()?.let { WorkerMistakeTypeList(it) }
                }

            })
    }

    fun getIdFromCodeSalix(code: String) {
        getItemFromBarcodeUseCase.execute(code)
            .enqueue(object : SalixCallback<Int?>(context) {
                override fun onSuccess(response: Response<Int?>) {
                    _responseCode.value =
                        response.body()
                }
            })
    }
}
