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

import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import com.google.gson.JsonObject
import es.verdnatura.R
import es.verdnatura.domain.SalixCallback
import es.verdnatura.domain.SilexCallback
import es.verdnatura.presentation.base.BaseViewModel
import es.verdnatura.presentation.base.getMessageFromAllResponse
import es.verdnatura.presentation.base.nameofFunction
import es.verdnatura.presentation.common.Event
import es.verdnatura.presentation.common.ItemShelvingSalix
import es.verdnatura.presentation.common.ResponseItemVO
import es.verdnatura.presentation.view.feature.reubication.model.Reubication
import es.verdnatura.presentation.view.feature.reubication.model.ReubicationList
import es.verdnatura.presentation.view.feature.ubicador.model.ItemUbicadorListVO
import es.verdnatura.presentation.view.feature.ubicador.model.ItemUbicadorVO
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class UbicadorViewModel(val context: Context) : BaseViewModel(context) {

    private val _shelvingList by lazy { MutableLiveData<ItemUbicadorListVO>() }

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

    private val _responsepriority by lazy { MutableLiveData<ResponseItemVO>() }
    val responsepriority: LiveData<ResponseItemVO>
        get() = _responsepriority

    private val _responseMake by lazy { MutableLiveData<ResponseItemVO>() }
    val responseMake: LiveData<ResponseItemVO>
        get() = _responseMake

    val loadShelvingList = Transformations.map(_shelvingList) { Event(it) }


    private val _reubicationList by lazy { MutableLiveData<ReubicationList>() }
    val loadReubicationList = Transformations.map(_reubicationList) { Event(it) }

    private val _responseCode by lazy { MutableLiveData<ResponseItemVO>() }
    val responseCode: LiveData<ResponseItemVO>
        get() = _responseCode

    val loadResponseCode = Transformations.map(_responseCode) { Event(it) }

    private val _responseAddList by lazy { MutableLiveData<ResponseItemVO>() }
    val responseAddList: LiveData<ResponseItemVO> = _responseAddList

    val loadAddList = Transformations.map(_responseAddList) { Event(it) }

    private val _responseLog by lazy { MutableLiveData<ResponseItemVO>() }
    val responseLog: LiveData<ResponseItemVO>
        get() = _responseLog

    fun itemShelvingList(
        vShelvingFk: String
    ) {
        silex.itemShelvingList(vShelvingFk.uppercase())
            .enqueue(object :
                SilexCallback<List<ItemUbicadorVO>>(context) {
                override fun onError(t: Throwable) {
                    val listError: ArrayList<ItemUbicadorVO> = ArrayList()
                    listError.add(
                        ItemUbicadorVO(
                            0,
                            isError = true,
                            errorMessage = getMessageFromAllResponse(
                                nameofFunction(this),
                                t.message!!
                            )
                        )
                    )
                    _shelvingList.value = ItemUbicadorListVO(listError)
                }

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

                    if (response.body() != null) {
                        _shelvingList.value = response.body()?.let { ItemUbicadorListVO(it) }
                    } else {
                        val listError: ArrayList<ItemUbicadorVO> = ArrayList()
                        listError.add(
                            ItemUbicadorVO(
                                0,
                                isError = true,
                                errorMessage = getMessageFromAllResponse(
                                    nameofFunction(this),
                                    response.message()
                                )
                            )
                        )
                        _shelvingList.value = ItemUbicadorListVO(listError)
                    }
                }

            })
    }

    fun shelvingPriorityUpdate(
        priority: Int,
        shelving: String

    ) {
        salix.updateShelvingPriority(
            where = JsonObject().apply { addProperty("code", shelving) },
            params = hashMapOf("priority" to priority)).enqueue(object : SalixCallback<Any>(context) {
                override fun onError(t: Throwable) {
                    _responsepriority.value = ResponseItemVO(
                        isError = true,
                        errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                    )
                }

                override fun onSuccess(response: Response<Any>) {
                    _responsepriority.value =
                        ResponseItemVO(isError = false, response = response.message())
                }
            })
    }

    fun itemShelving_addList(
        shelving: String,
        items: Any,
        isChecking: Boolean,
        warehouse: Int
    ) {
        silex.itemShelving_addList(
            shelving,
            items,
            isChecking,
            warehouse
        ).enqueue(object :
            SilexCallback<Any>(context) {
            override fun onError(t: Throwable) {
                _responseAddList.value = ResponseItemVO(
                    isError = true, errorMessage = getMessageFromAllResponse(
                        nameofFunction(this), t.message!!
                    )
                )
            }

            override fun onSuccess(response: Response<Any>) {
                _responseAddList.value =
                    ResponseItemVO(isError = false, response = response.message()!!)

            }
        })
    }

    fun itemShelvingMake(
        shelving: String,
        item: Number,
        quantity: Int,
        packing: Int?,
        warehouse: Int,
        grouping: Int?
    ) {
        silex.itemShelvingMake(
            shelving,
            item,
            quantity,
            packing,
            warehouse,
            grouping
        ).enqueue(object : SilexCallback<Any>(context) {
            override fun onError(t: Throwable) {
                _responseMake.value = ResponseItemVO(
                    isError = true,
                    errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                )
            }

            override fun onResponse(call: Call<Any>, response: Response<Any>) {
                _responseMake.value =
                    ResponseItemVO(isError = false, response = response.message()!!)
            }

        })
    }

    fun itemShelvingMakeEdit(
        quantity: Int,
        packing: Int,
        itemShelvingFk: Int,
        grouping: Int?

    ) {
         salix.itemShelvingUpdate(
              params = ItemShelvingSalix(visible = quantity, packing = packing, grouping = grouping),
              id = itemShelvingFk,
          ).enqueue(object : SalixCallback<Any>(context) {

            override fun onError(t: Throwable) {
                _responseMake.value = ResponseItemVO(
                    isError = true,
                    errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                )
            }

            override fun onSuccess(response: Response<Any>) {
                _responseMake.value =
                    ResponseItemVO(isError = false, response = response.message()!!)
            }

        })
    }

    fun shelvingPark(

        shelving: String,
        parking: String
    ) {
        silex.shelvingPark(shelving, parking)
            .enqueue(object : Callback<Any> {
                override fun onFailure(call: Call<Any>, t: Throwable) {
                    _response.value = ResponseItemVO(
                        isError = true,
                        errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                    )
                }

                override fun onResponse(call: Call<Any>, response: Response<Any>) {
                    if (!response.isSuccessful) {
                        _response.value = ResponseItemVO(
                            isError = true,
                            errorMessage = getMessageFromAllResponse(
                                nameofFunction(this),
                                response.message()
                            )
                        )
                    } else {
                        _response.value =
                            ResponseItemVO(isError = false, response = response.message())
                    }
                }
            })
    }

    fun shelvingChange(
        origen: String,
        destino: String
    ) {
        silex.shelvingChange(origen, destino)
            .enqueue(object : SilexCallback<Any>(context) {
                override fun onError(t: Throwable) {
                    _response.value = ResponseItemVO(
                        isError = true,
                        errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                    )
                }

                override fun onSuccess(response: Response<Any>) {
                    _response.value =
                        ResponseItemVO(isError = false, response = response.message()!!)
                }
            })
    }

    fun itemShelving_merge(
        vShelf: Int,
        vShelvingFk: String

    ) {
        salix.itemShelvingsUpdate(
            where = JsonObject().apply { addProperty("id", vShelf) },
            params = hashMapOf("shelvingFk" to vShelvingFk))
            .enqueue(object : SalixCallback<Any>(context) {
                override fun onError(t: Throwable) {
                    _response.value = ResponseItemVO(
                        isError = true,
                        errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                    )
                }

                override fun onSuccess(response: Response<Any>) {
                    _response.value =
                        ResponseItemVO(isError = false, response = response.message()!!)
                }
            })
    }

    fun itemShelving_deleteChecked(
        vShelvingFk: String

    ) {
        salix.itemShelvingsUpdate(
            where = JsonObject().apply { addProperty("shelvingFk", vShelvingFk) },
            params = hashMapOf("isChecked" to null))
            .enqueue(object : SilexCallback<Any>(context) {
                override fun onError(t: Throwable) {
                    _response.value = ResponseItemVO(
                        isError = true,
                        errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                    )
                }

                override fun onSuccess(response: Response<Any>) {
                    _response.value =
                        ResponseItemVO(isError = false, response = response.message()!!)
                }
            })
    }

    fun shelvinLog_add(
        code: String
    ) {
        silex.shelvingLog_add(code)
            .enqueue(object : SilexCallback<Any>(context) {
                override fun onError(t: Throwable) {
                    _responseLog.value = ResponseItemVO(
                        isError = true,
                        errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                    )
                }

                override fun onSuccess(response: Response<Any>) {
                    _responseLog.value =
                        ResponseItemVO(isError = false, response = response.message()!!)
                }

            })
    }

    fun travel_updatePacking(
        itemFk: Int,
        packingFk: Int
    ) {
        silex.travel_updatePacking(itemFk, packingFk)
            .enqueue(object : SilexCallback<Any>(context) {
                override fun onError(t: Throwable) {
                    _response.value = ResponseItemVO(
                        isError = true,
                        errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                    )
                }

                override fun onSuccess(response: Response<Any>) {
                    _response.value =
                        ResponseItemVO(isError = false, response = response.message()!!)
                }

            })
    }

    fun itemShelving_return(
        shelvingFk: String,

        ) {
        silex.itemShelving_return(shelvingFk)
            .enqueue(object : SilexCallback<ArrayList<Reubication>>(context) {
                override fun onError(t: Throwable) {
                    val listError: ArrayList<Reubication> = ArrayList()
                    listError.add(
                        Reubication(
                            0,
                            isError = true,
                            errorMessage = getMessageFromAllResponse(
                                nameofFunction(this),
                                t.message!!,

                                )
                        )
                    )
                    _reubicationList.value = ReubicationList(listError)
                }

                override fun onSuccess(response: Response<ArrayList<Reubication>>) {
                    if (response.body() == null) {
                        val listError: ArrayList<Reubication> = ArrayList()
                        listError.add(
                            Reubication(
                                0,
                                isError = true,
                                errorMessage = getMessageFromAllResponse(
                                    nameofFunction(this),
                                    response.message()
                                )
                            )
                        )
                        _reubicationList.value = ReubicationList(listError)
                    } else {

                        _reubicationList.value = response.body()?.let { ReubicationList(it) }

                    }
                }
            })
    }

    fun clearShelvingList(
        shelvingFk: String

    ) {

        salix.itemShelvingsUpdate(
            where = JsonObject().apply { addProperty("shelvingFk", shelvingFk) },
            hashMapOf("visible" to 0)
        )
            .enqueue(object : SalixCallback<Any>(context) {
                override fun onError(t: Throwable) {
                    _response.value = ResponseItemVO(
                        isError = true,
                        errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                    )
                }

                override fun onSuccess(response: Response<Any>) {
                    _response.value =
                        ResponseItemVO(isError = false, response = response.message())
                }
            })
    }

    fun shelvingChangeSalix(
        shelvingFkIn: String,
        shelvingFkOut:String

    ) {

        salix.itemShelvingsUpdate(
            where = JsonObject().apply { addProperty("shelvingFk", shelvingFkIn) },
            hashMapOf("shelvingFk" to shelvingFkOut)
        )
            .enqueue(object : SalixCallback<Any>(context) {
                override fun onError(t: Throwable) {
                    _response.value = ResponseItemVO(
                        isError = true,
                        errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                    )
                }

                override fun onSuccess(response: Response<Any>) {
                    _response.value =
                        ResponseItemVO(isError = false, response = response.message())
                }
            })
    }

    fun itemShelvingTransfer(
        itemFk: Int,
        shelvingFk: String

    ) {
        silex.itemShelvingTransfer(itemFk, shelvingFk)
            .enqueue(object : SilexCallback<Any>(context) {
                override fun onError(t: Throwable) {
                    _response.value = ResponseItemVO(
                        isError = true,
                        errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                    )
                }

                override fun onSuccess(response: Response<Any>) {
                    _response.value =
                        ResponseItemVO(isError = false, response = response.message()!!)
                }
            })
    }

    fun itemShelvingDelete(itemFk: Int) {
        salix.itemShelvingsDelete(itemFk)
            .enqueue(object : SalixCallback<Any>(context) {
                override fun onError(t: Throwable) {

                    _response.value = ResponseItemVO(
                        isError = true,
                        errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                    )
                }

                override fun onSuccess(response: Response<Any>) {
                    _response.value =
                        ResponseItemVO(isError = false, response = response.message())

                }
            })
    }

    fun itemShelving_selfConsumption(shelvingFk: String, itemFk: Int, quantity: Int) {
        silex.itemShelving_selfConsumption(shelvingFk, itemFk, quantity)
            .enqueue(object : SilexCallback<Any>(context) {
                override fun onError(t: Throwable) {

                    _response.value = ResponseItemVO(
                        isError = true,
                        errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                    )
                }

                override fun onSuccess(response: Response<Any>) {
                    _response.value =
                        ResponseItemVO(isError = false, response = response.message())

                }
            })
    }

    fun getIdFromCode(code: String) {
        salix.barcodes_toitem(code)
            .enqueue(object : SilexCallback<String?>(context) {
                override fun onError(t: Throwable) {
                    _responseCode.value = ResponseItemVO(
                        isError = true,
                        errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                    )
                }

                override fun onSuccess(response: Response<String?>) {


                    if (response.body() == null) {
                        _responseCode.value = ResponseItemVO(
                            isError = true,
                            errorMessage = context.getString(R.string.itemNotValid)
                        )
                    } else {
                        _responseCode.value =
                            ResponseItemVO(isError = false, response = response.body()!!.toString())
                    }
                }
            })
    }

}
