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

import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.map
import es.verdnatura.domain.SalixCallback
import es.verdnatura.domain.formatWithQuotes
import es.verdnatura.domain.userCases.GetItemFromBarcodeUseCase
import es.verdnatura.presentation.base.BaseViewModel
import es.verdnatura.presentation.common.Event
import es.verdnatura.presentation.common.ItemBarCodeSalix
import es.verdnatura.presentation.common.ItemDiscardSalixShortage
import es.verdnatura.presentation.view.feature.articulo.model.AddressLoses
import es.verdnatura.presentation.view.feature.articulo.model.AddressLosesList
import es.verdnatura.presentation.view.feature.articulo.model.ItemCardVO
import es.verdnatura.presentation.view.feature.articulo.model.ItemProposal
import es.verdnatura.presentation.view.feature.articulo.model.ItemProposalList
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody
import retrofit2.Response
import java.io.File

class ItemCardViewModel(var context: Context) : BaseViewModel(context) {

    private val getItemFromBarcodeUseCase = GetItemFromBarcodeUseCase(salix)

    private val _itemCard by lazy { MutableLiveData<ItemCardVO>() }
    val itemCard: LiveData<ItemCardVO>
        get() = _itemCard

    val loadResponseItemCard: LiveData<Event<ItemCardVO>> =
        _itemCard.map { Event(it) }

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

    private val _itemProposalList by lazy { MutableLiveData<ItemProposalList>() }
    val itemProposalList: LiveData<ItemProposalList>
        get() = _itemProposalList

    private val _addressLosesList by lazy { MutableLiveData<AddressLosesList>() }
    val addressLosesList: LiveData<AddressLosesList>
        get() = _addressLosesList

    val loadAddressLosesList: LiveData<Event<AddressLosesList>> =
        _addressLosesList.map { Event(it) }

    fun getItemCard(
        itemFk: Number,
        warehouseFk: Int,
    ) {
        salix.getCard(barcode = itemFk, warehouseFk = warehouseFk)
            .enqueue(object : SalixCallback<ItemCardVO>(context) {

                override fun onSuccess(response: Response<ItemCardVO>) {
                    _itemCard.value = response.body() ?: ItemCardVO()

                }

            })
    }

    fun itemGetSimilar(
        itemFk: Int,
        warehouseFk: Int,
        shipped: String,
        isShowedByType: Boolean,
        daysInforward: Int = 0,
    ) {
        salix.getItemSimilar(
            params = arrayListOf(
                itemFk,
                warehouseFk,
                shipped,
                isShowedByType,
                daysInforward
            ).formatWithQuotes()
        ).enqueue(object : SalixCallback<List<ItemProposal>>(context) {
            override fun onSuccess(response: Response<List<ItemProposal>>) {
                _itemProposalList.value = response.body()?.let {
                    ItemProposalList(it)
                }
            }
        })
    }

    fun setVisibleDiscard(
        itemFk: Int,
        warehouseFk: Int,
        quantity: Int,
        addressFk: Int?,

        ) {

        salix.setVisibleDiscard(
            ItemDiscardSalixShortage(itemFk, warehouseFk, quantity, addressFk)
        ).enqueue(object : SalixCallback<Any>(context) {

            override fun onSuccess(response: Response<Any>) {
                getItemCard(itemFk, warehouseFk)
                super.onSuccess(response)
            }
        })
    }

    fun updateGrouping(
        itemFk: Int, value: Int?, warehouseFk: Int

    ) {
        salix.updateGrouping(params = arrayListOf(warehouseFk, itemFk, value))
            .enqueue(object : SalixCallback<Any>(context) {
                override fun onSuccess(response: Response<Any>) {
                    getItemCard(itemFk, warehouseFk)
                    super.onSuccess(response)
                }

            })
    }

    fun updatePacking(
        itemFk: Int, value: Int, warehouseFk: Int

    ) {
        salix.updatePacking(params = arrayListOf(warehouseFk, itemFk, value))
            .enqueue(object : SalixCallback<Any>(context) {
                override fun onSuccess(response: Response<Any>) {
                    getItemCard(itemFk, warehouseFk)
                    super.onSuccess(response)
                }

            })
    }

    fun updateStems(
        itemFk: Int, value: Int?, warehouseFk: Int
    ) {
        salix.updateItem(itemFk, hashMapOf("stems" to value))
            .enqueue(object : SalixCallback<Any>(context) {

                override fun onSuccess(response: Response<Any>) {
                    getItemCard(itemFk, warehouseFk)
                    super.onSuccess(response)
                }
            })
    }

    fun updateReference(
        itemFk: Int, value: Int, warehouseFk: Int
    ) {
        salix.updateItem(itemFk, hashMapOf("comment" to value))
            .enqueue(object : SalixCallback<Any>(context) {

                override fun onSuccess(response: Response<Any>) {
                    getItemCard(itemFk, warehouseFk)
                    super.onSuccess(response)
                }
            })
    }

    fun getIdFromCodeSalix(code: String) {
        getItemFromBarcodeUseCase.execute(code)
            .enqueue(object : SalixCallback<Int?>(context) {

                override fun onSuccess(response: Response<Int?>) {
                    _responseCode.value = response.body()

                }
            })
    }

    fun barcodesEditSalix(itemFk: Int, barCodeValue: String, delete: Boolean, warehouseFk: Int) {

        if (delete) {
            salix.barcodesDelete(itemFk = itemFk, barcode = barCodeValue)
        } else {
            salix.barcodesEdit(
                ItemBarCodeSalix(itemFk, barCodeValue)
            )

        }.enqueue(object : SalixCallback<Any>(context) {

            override fun onSuccess(response: Response<Any>) {
                getItemCard(itemFk, warehouseFk)
            }
        })
    }

    fun uploadPhoto(
        urlImage: String,
        itemFK: Number,
        file: File = File(urlImage),
        fileRequestBody: RequestBody = RequestBody.create(MediaType.parse("image/jpeg"), file),
        filePart: MultipartBody.Part = MultipartBody.Part.createFormData(
            "file", file.name, fileRequestBody
        ),
    ) {
        salix.uploadImage("catalog", itemFK, filePart)
            .enqueue(object : SalixCallback<Any>(context) {
            })
    }

    fun getAddress() {
        salix.getAddress("""{"where":{"type": { "neq": "external"}}, "include": [ { "relation": "address", "scope": { "fields": { "nickname": true } } } ] }""")
            .enqueue(object : SalixCallback<List<AddressLoses>>(context) {
                override fun onSuccess(response: Response<List<AddressLoses>>) {
                    _addressLosesList.value = response.body()?.let { AddressLosesList(it) }
                }
            })
    }
}
