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

import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.google.gson.reflect.TypeToken
import es.verdnatura.domain.GetLoginUserCase
import es.verdnatura.domain.NodeJsService
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.Printers
import es.verdnatura.presentation.view.feature.ajustes.model.SectorItemVO
import es.verdnatura.presentation.view.feature.ajustes.model.WorkerPrintersList
import es.verdnatura.presentation.view.feature.login.model.LoginDevice
import es.verdnatura.presentation.view.feature.login.model.LoginSalixVO
import es.verdnatura.presentation.view.feature.login.model.versionApp
import es.verdnatura.presentation.view.feature.login.model.workerId
import es.verdnatura.presentation.view.feature.paletizador.model.itemsExpeditionDynamics
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class LoginViewModel(context: Context) : BaseViewModel() {

    private val getLoginUserCase: GetLoginUserCase = GetLoginUserCase(context)

    private val _loginsalixitem by lazy { MutableLiveData<LoginSalixVO>() }
    val loginsalixitem: LiveData<LoginSalixVO>
        get() = _loginsalixitem


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

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

    private val _versionappitem by lazy { MutableLiveData<versionApp>() }
    val versionappitem: LiveData<versionApp>
        get() = _versionappitem

    private val _logindevice by lazy { MutableLiveData<LoginDevice>() }
    val logindevice: LiveData<LoginDevice>
        get() = _logindevice

    private val _workerId by lazy { MutableLiveData<workerId>() }
    val workerId: LiveData<workerId>
        get() = _workerId

    private val _nodejs by lazy { MutableLiveData<NodeJsService.SmartTagNode>() }
    val nodejs: LiveData<NodeJsService.SmartTagNode>
        get() = _nodejs


    private val _workergetSector by lazy { MutableLiveData<SectorItemVO>() }
    val workergetSector: LiveData<SectorItemVO>
        get() = _workergetSector

    private val _workergetPrinter by lazy { MutableLiveData<Printers>() }
    val workergetPrinter: LiveData<Printers>
        get() = _workergetPrinter

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


    private val _workerPrintList by lazy { MutableLiveData<WorkerPrintersList>() }

    val loadWorkerPrintList = Transformations.map(_workerPrintList) { Event(it) }

    fun loginSalix(user: String, password: String) {
        getLoginUserCase.salixLogin(user, password).enqueue(object : Callback<LoginSalixVO> {
            override fun onResponse(call: Call<LoginSalixVO>, response: Response<LoginSalixVO>) {

                val loginSalixVO: LoginSalixVO?
                if (response.body() != null) {

                    loginSalixVO = response.body()?.token?.let {
                        LoginSalixVO(
                            user,
                            password,
                            it,
                            isError = false,
                            errorMessage = ""
                        )
                    }
                } else {

                    loginSalixVO = LoginSalixVO(
                        user,
                        password,
                        isError = true,
                        errorMessage = getMessageFromAllResponse(
                            nameofFunction(this), response.message()
                        )
                    )


                }

                _loginsalixitem.value = loginSalixVO
            }

            override fun onFailure(call: Call<LoginSalixVO>, t: Throwable) {
                val loginSalixVO =
                    LoginSalixVO(
                        user,
                        password,
                        "",
                        isError = true,
                        errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                    )
                _loginsalixitem.value = loginSalixVO
            }
        })
    }

    fun device_checkLogin(user: String, password: String, android_id: String) {

        getLoginUserCase.device_checkLogin(user, password, android_id)
            .enqueue(object : Callback<LoginDevice> {
                override fun onResponse(call: Call<LoginDevice>, response: Response<LoginDevice>) {

                    val loginDevice: LoginDevice?


                    if (!response.isSuccessful) {
                        loginDevice = LoginDevice(
                            isError = true,
                            errorMessage = getMessageFromAllResponse(
                                nameofFunction(this),
                                response.message()
                            )
                        )


                    } else {
                        if (response.body() != null) {

                            loginDevice = response.body()?.let {

                                LoginDevice(
                                    it.vMessage, it.vIsAuthorized,
                                    isError = false,
                                    errorMessage = ""
                                )

                            }

                        } else {
                            loginDevice = LoginDevice(
                                isError = true,
                                errorMessage = getMessageFromAllResponse(
                                    nameofFunction(this),
                                    response.message()
                                )
                            )
                        }
                    }
                    _logindevice.value = loginDevice
                }

                override fun onFailure(call: Call<LoginDevice>, t: Throwable) {

                    val loginDevice =
                        LoginDevice(
                            "",
                            "",
                            isError = true,
                            errorMessage = getMessageFromAllResponse(
                                nameofFunction(this),
                                t.message!!
                            )
                        )
                    _logindevice.value = loginDevice
                }
            })
    }


    fun worker_getId(user: String, password: String) {
        getLoginUserCase.worker_getId(user, password)
            .enqueue(object : Callback<String> {
                override fun onResponse(call: Call<String>, response: Response<String>) {

                    val workerId: workerId?


                    if (response.body() != null) {

                        workerId = workerId(
                            response.body().toString(),
                            isError = false,
                            errorMessage = ""
                        )

                    } else {
                        workerId = workerId(
                            isError = true,
                            errorMessage = getMessageFromAllResponse(
                                nameofFunction(this),
                                response.message()
                            )
                        )
                    }

                    _workerId.value = workerId
                }

                override fun onFailure(call: Call<String>, t: Throwable) {
                    val workerId =
                        workerId(
                            isError = true,
                            errorMessage = getMessageFromAllResponse(
                                nameofFunction(this),
                                t.message!!
                            )
                        )
                    _workerId.value = workerId
                }

            })
    }


    fun deviceLog_add(
        user: String, password: String, app: String, versionApp: String, android_id: String
    ) {
        getLoginUserCase.deviceLog_add(user, password, app, versionApp, android_id)
            .enqueue(object : Callback<Void> {
                override fun onResponse(call: Call<Void>, response: Response<Void>) {

                    if (!response.isSuccessful) {

                        messageError(nameofFunction(this), response.message())

                    }
                }

                override fun onFailure(call: Call<Void>, t: Throwable) {

                    messageError(nameofFunction(this), t.message!!)
                }

            })
    }

    fun messageError(callFunction: String, message: String) {
        _devicelogresponse.value = ResponseItemVO(
            isError = true,
            errorMessage = getMessageFromAllResponse(callFunction, message)
        )

    }

    fun checkVersion(user: String, password: String, nameApp: String) {
        getLoginUserCase.checkVersion(user, password, nameApp)
            .enqueue(object : Callback<versionApp> {
                override fun onResponse(call: Call<versionApp>, response: Response<versionApp>) {

                    //var versionApp: versionApp?

                    if (response.body() != null) {

                        _versionappitem.value = response.body()?.let {

                            versionApp(
                                it.appname,
                                it.version,
                                it.IsVersionCritical,
                                it.url,
                                isError = false,
                                errorMessage = ""
                            )

                        }

                    } else {
                        _versionappitem.value = versionApp(
                            user,
                            password,
                            isError = true,
                            errorMessage = getMessageFromAllResponse(
                                nameofFunction(this),
                                response.message()
                            )
                        )
                    }

                    // _versionappitem.value = versionApp

                }

                override fun onFailure(call: Call<versionApp>, t: Throwable) {
                    _versionappitem.value =
                        versionApp(
                            nameApp,
                            "",
                            isError = true,
                            errorMessage = getMessageFromAllResponse(
                                nameofFunction(this),
                                t.message!!
                            )
                        )
                    //_versionappitem.value = versionApp
                }
            })
    }

    /* fun nodeJsTest(smarttag: String, wagon: String, shelving: String)
     {
         getLoginUserCase.nodeJsTest(smarttag, wagon, shelving)
             .enqueue(object : Callback<NodeJsService.SmartTagNode>
             {
                 override fun onResponse(
                     call: Call<NodeJsService.SmartTagNode>,
                     response: Response<NodeJsService.SmartTagNode>
                                        )
                 {


                     val workerId: NodeJsService.SmartTagNode?

                     *//*   if (response.isSuccessful()){
                           //Log.i("VERDNATURA::","OK")
                       }

                       if (!response.errorBody().toString().isEmpty()){

                       }*//*

                    if (response.body() != null)
                    {

                        workerId = NodeJsService.SmartTagNode(
                            response.body().toString(),
                            isError = false,
                            errorMessage = ""
                                                             )

                    } else
                    {
                        workerId = NodeJsService.SmartTagNode(
                            isError = true,
                            errorMessage = "Error al llamar al servicio Node."
                                                             )
                    }

                    _nodejs.value = workerId
                }

                override fun onFailure(call: Call<NodeJsService.SmartTagNode>, t: Throwable)
                {
                    val workerId =
                        NodeJsService.SmartTagNode(isError = true, errorMessage = t.message!!)

                      //Log.i("VERDNATURA::","el error nodejs es "+t.message+"--"+t.cause.toString()+"--"+t.stackTrace.toString())

                    _nodejs.value = workerId
                }

            })
    }*/

    fun getListFromJSON(json: JsonObject): MutableList<itemsExpeditionDynamics> {
        val gson = Gson()
        var list = mutableListOf<itemsExpeditionDynamics>()

        //  val mapType = object : TypeToken<Map<String, Any>>() {}.type

        var expeditionState: Map<String, Any> =
            gson.fromJson(json, object : TypeToken<Map<String, Any>>() {}.type)
        expeditionState.forEach {

            list.add(itemsExpeditionDynamics(key = it.key, value = it.value.toString()))

        }
        return list
    }

    fun worker_getSector(user: String, password: String) {

        getLoginUserCase.worker_getSector(user, password).enqueue(object : Callback<SectorItemVO> {
            override fun onFailure(call: Call<SectorItemVO>, t: Throwable) {

                _workergetSector.value = SectorItemVO(
                    0,
                    "",
                    0,
                    isError = true,
                    errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                )
            }

            override fun onResponse(
                call: Call<SectorItemVO>,
                response: Response<SectorItemVO>
            ) {

                if (!response.isSuccessful) {
                    _workergetSector.value = SectorItemVO(
                        0, "", 0,
                        isError = true,
                        errorMessage = getMessageFromAllResponse(
                            nameofFunction(this),
                            response.message()
                        )
                    )
                } else {

                    _workergetSector.value = response.body()?.let {
                        SectorItemVO(
                            it.id,
                            it.description,
                            it.warehouseFk,
                            isError = false
                        )
                    }


                }

            }

        })
    }

    fun operator_getNumberOfWagons(user: String, password: String) {

        getLoginUserCase.operator_getNumberOfWagons(user, password)
            .enqueue(object : Callback<Int?> {
                override fun onFailure(call: Call<Int?>, t: Throwable) {

                    _operatorGetNumberOfWagons.value = ResponseItemNumber(
                        null,
                        isError = true,
                        errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                    )
                }

                override fun onResponse(
                    call: Call<Int?>,
                    response: Response<Int?>
                ) {

                    if (!response.isSuccessful) {
                        _operatorGetNumberOfWagons.value = ResponseItemNumber(
                            null, true,
                            errorMessage = getMessageFromAllResponse(
                                nameofFunction(this),
                                response.message()
                            )
                        )
                    } else {

                        if (response.body() != null)
                            _operatorGetNumberOfWagons.value =
                                ResponseItemNumber(response.body(), isError = false)


                    }

                }

            })
    }

    fun operator_add(user: String, password: String) {

        getLoginUserCase.operator_add(user, password).enqueue(object : Callback<Any> {
            override fun onFailure(call: Call<Any>, t: Throwable) {
                _operatorAdd.value = ResponseItemVO(
                    isError = true,
                    errorMessage = getMessageFromAllResponse(nameofFunction(this), t.message!!)
                )
            }

            override fun onResponse(
                call: Call<Any>,
                response: Response<Any>
            ) {

                if (!response.isSuccessful) {
                    _operatorAdd.value = ResponseItemVO(
                        "", true,
                        errorMessage = getMessageFromAllResponse(
                            nameofFunction(this),
                            response.message()
                        )
                    )


                } else {

                    _operatorAdd.value = ResponseItemVO("", false)
                }

            }

        })
    }

    fun worker_getPrinter(user: String, password: String) {

        getLoginUserCase.worker_getPrinter(user, password)
            .enqueue(object : Callback<List<Printers>> {
                override fun onFailure(call: Call<List<Printers>>, t: Throwable) {
                    val listError: ArrayList<Printers> = ArrayList()
                    listError.add(
                        Printers(
                            isError = true,
                            errorMessage = getMessageFromAllResponse(
                                nameofFunction(this),
                                t.message!!
                            )
                        )
                    )
                    _workerPrintList.value = WorkerPrintersList(listError)

                }

                override fun onResponse(
                    call: Call<List<Printers>>,
                    response: Response<List<Printers>>
                ) {
                    if (response.body() != null) {
                        _workerPrintList.value = response.body()?.let {
                            WorkerPrintersList(it)
                        }

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

                    }


                }

            })
    }
}
