package es.verdnatura.presentation.view.feature.ajustes.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.MobileApplication
import es.verdnatura.R
import es.verdnatura.domain.SalixCallback
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.ResponseItemNumber
import es.verdnatura.presentation.common.ResponseItemVO
import es.verdnatura.presentation.view.feature.ajustes.model.AjustesItemVO
import es.verdnatura.presentation.view.feature.ajustes.model.Printers
import es.verdnatura.presentation.view.feature.ajustes.model.PrintersList
import es.verdnatura.presentation.view.feature.ajustes.model.SectorItemVO
import es.verdnatura.presentation.view.feature.ajustes.model.SectorListVO
import es.verdnatura.presentation.view.feature.ajustes.model.Train
import es.verdnatura.presentation.view.feature.ajustes.model.TrainList
import es.verdnatura.presentation.view.feature.articulo.model.ItemPackingType
import es.verdnatura.presentation.view.feature.articulo.model.ItemPackingTypeList
import es.verdnatura.presentation.view.feature.login.model.Operator
import retrofit2.Response

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

    private val _ajustesitem by lazy { ArrayList<AjustesItemVO>() }
    val ajustesitem: List<AjustesItemVO>
        get() = _ajustesitem

    private val _sectorList by lazy { MutableLiveData<SectorListVO>() }
    val sectorList: LiveData<SectorListVO>
        get() = _sectorList

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

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

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

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

    private val _printerList by lazy { MutableLiveData<PrintersList>() }
    val printerList: LiveData<PrintersList>
        get() = _printerList

    private val _operatorGetNumberOfWagons by lazy { MutableLiveData<ResponseItemNumber>() }
    val operatorGetNumberOfWagons: LiveData<ResponseItemNumber>
        get() = _operatorGetNumberOfWagons

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


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

    private val _itemspackinglist by lazy { MutableLiveData<ItemPackingTypeList>() }
    val itemspackinglist: LiveData<ItemPackingTypeList>
        get() = _itemspackinglist

    private val _trainList by lazy { MutableLiveData<TrainList>() }
    val trainList: LiveData<TrainList>
        get() = _trainList

    val loadSectorList = Transformations.map(_sectorList) { Event(it) }
    val loadPrintersList = Transformations.map(_printerList) { Event(it) }
    val loadItemPackingList = Transformations.map(_itemspackinglist) { Event(it) }
    val loadTrainList = Transformations.map(_trainList) { Event(it) }
    val loadUpdatePacking = Transformations.map(_actionUpdatePackingTicket) { Event(it) }

    fun inititializeDefaultAjusts(
        sectorDescrip: String,
        sectorFk: Int,
        warehouseFk: Int,
        carroDescrip: String,
        printerFk: Int,
        printerSelected: String,
        train: String?,
        itemPackingType: String?,
        actionIsAllowed: Boolean
    ) {
        _ajustesitem.clear()
        _ajustesitem.add(
            AjustesItemVO(
                0,
                context.getString(R.string.sector),
                sectorDescrip,
                sectorFk,
                warehouseFk,
                0,
                printerSelected,
                true
            )
        )


        _ajustesitem.add(
            AjustesItemVO(
                1,
                context.getString(R.string.wagoons),
                carroDescrip,
                0,
                0,
                0, context.getString(R.string.printerWithout),
                false
            )
        )
        _ajustesitem.add(
            AjustesItemVO(
                2,
                context.getString(R.string.printerLabel),
                printerSelected,
                0,
                0,
                printerFk,
                printerSelected,
                true
            )
        )
        _ajustesitem.add(
            AjustesItemVO(
                6,
                context.getString(R.string.settingsTitleTrain),
                train,
                0,
                0,
                0,
                action = actionIsAllowed
            )
        )
        _ajustesitem.add(
            AjustesItemVO(
                7,
                context.getString(R.string.settingsTitleItemPacking),
                itemPackingType,
                0,
                0,
                0,
                action = actionIsAllowed
            )
        )

        _ajustesitem.add(
            AjustesItemVO(
                4,
                context.getString(R.string.vehicleControl),
                "",
                0,
                0,
                0, context.getString(R.string.printerWithout),
                true
            )
        )
        _ajustesitem.add(
            AjustesItemVO(
                5,
                context.getString(R.string.closeSession),
                "",
                0,
                0,
                0, context.getString(R.string.printerWithout),
                true
            )
        )

    }

    fun getItemPackingTypeSalix() {
        salix.get_ItemPackingType().enqueue(object :
            SalixCallback<List<ItemPackingType>>(context) {
            override fun onError(t: Throwable) {

                val listError: ArrayList<ItemPackingType> = ArrayList()
                listError.add(
                    ItemPackingType(
                        isError = true,
                        errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                    )
                )
                _itemspackinglist.value = ItemPackingTypeList(listError)
            }

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

                if (response.body() != null) {
                    _itemspackinglist.value = response.body()?.let { ItemPackingTypeList(it) }

                } else {
                    val listError: ArrayList<ItemPackingType> = ArrayList()
                    listError.add(
                        ItemPackingType(
                            isError = true,
                            errorMessage = getMessageFromAllResponse(
                                nameofFunction(this),
                                response.message()
                            )
                        )
                    )
                    _itemspackinglist.value = ItemPackingTypeList(listError)
                }
            }

        })
    }

    fun getSectorsSalix() {
        salix.getSectorsSalix().enqueue(object : SalixCallback<List<SectorItemVO>>(context) {
            override fun onError(t: Throwable) {

                val listError: ArrayList<SectorItemVO> = ArrayList()
                listError.add(SectorItemVO(0, "", 0, true, t.message!!))
                _sectorList.value = SectorListVO(listError)
            }

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

                if (response.body() != null) {
                    _sectorList.value = response.body()?.let { SectorListVO(it) }
                } else {
                    val listError: ArrayList<SectorItemVO> = ArrayList()
                    listError.add(
                        SectorItemVO(
                            0, "", 0, true,
                            getMessageFromAllResponse(nameofFunction(this), response.message())
                        )
                    )
                    _sectorList.value = SectorListVO(listError)
                }
            }

        })
    }

    fun printer_get() {
        //Tarea 6276
        //salix.getprinters().enqueue(object : SalixCallback<List<Printers>>(context) {
        silex.printer_get().enqueue(object : SalixCallback<List<Printers>>(context) {
            override fun onSuccess(response: Response<List<Printers>>) {
                if (response.body() != null) {
                    _printerList.value = response.body()?.let { PrintersList(it) }
                } else {
                    val listError: ArrayList<Printers> = ArrayList()
                    listError.add(
                        Printers(
                            0, "", true,
                            getMessageFromAllResponse(nameofFunction(this), response.message())
                        )
                    )
                    _printerList.value = PrintersList(listError)
                }
            }

            override fun onError(t: Throwable) {
                val listError: ArrayList<Printers> = ArrayList()
                listError.add(Printers(0, "", true, t.message!!))
                _printerList.value = PrintersList(listError)

            }

        })
    }

    fun train_get() {
        salix.getTrain().enqueue(object : SalixCallback<List<Train>>(context) {
            override fun onSuccess(response: Response<List<Train>>) {
                _trainList.value = response.body()?.let { TrainList(it) }
            }

            override fun onError(t: Throwable) {
                val listError: ArrayList<Train> = ArrayList()
                listError.add(Train(0, "", true, t.message!!))
                _trainList.value = TrainList(listError)
            }

        })
    }

    fun operator_updateItemPackingType(itemPackingTypeFk: String) {

        silex.operator_updateItemPackingType(itemPackingTypeFk)
            .enqueue(object : SalixCallback<Unit>(context) {
                override fun onError(t: Throwable) {

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

                override fun onSuccess(response: Response<Unit>) {

                    _actionUpdatePacking.value = ResponseItemVO(
                        response = response.message(),
                        isError = false,
                        errorMessage = ""

                    )

                }

            })
    }

    fun worker_isF11Allowed() {
        salix.worker_isF11Allowed("""{"where":{"id":${(context as MobileApplication).userId}},"fields":{"isF11Allowed":true}}""")
            .enqueue(object : SalixCallback<JsonObject>(context) {
                override fun onSuccess(response: Response<JsonObject>) {
                    _workerAllowedResponse.value = ResponseItemVO(
                        response = response.body()!!.entrySet().first().value.toString(),
                        isError = false,
                    )
                }

            })
    }

    fun worker_updateOperatorSalix(entity: String, workerFk: Int, sectorFk: Int?, labelerFk: Int?) {
        salix.update_operator(id = workerFk, Operator(sectorFk, labelerFk))
            .enqueue(object : SalixCallback<Unit>(context) {
                override fun onError(t: Throwable) {
                    _actionUpdate.value = ResponseItemVO(
                        isError = true,
                        errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                    )
                    throw t
                }

                override fun onSuccess(response: Response<Unit>) {
                    if (entity == "sector") {
                        _actionUpdate.value = ResponseItemVO(
                            response = response.message(),
                            isError = false,
                            errorMessage = ""

                        )
                    }

                    super.onSuccess(response)
                }

            })
    }

    fun operatorUpdateTrain(workerId: Int, trainFk: Int) {

        salix.update_operator(id = workerId, params = hashMapOf("trainFk" to trainFk))
            .enqueue(object : SalixCallback<Unit>(context) {
                override fun onSuccess(response: Response<Unit>) {
                    super.onSuccess(response)
                }

                override fun onError(t: Throwable) {
                    throw t
                }

            })
    }
}

