package es.verdnatura.presentation.view.feature.delivery.viewmodels

import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import es.verdnatura.domain.SalixCallback
import es.verdnatura.domain.formatWithQuotes
import es.verdnatura.presentation.base.BaseViewModel
import es.verdnatura.presentation.common.Event
import es.verdnatura.presentation.common.ResponseItemVO
import es.verdnatura.presentation.view.feature.delivery.model.ClientTicketList
import es.verdnatura.presentation.view.feature.delivery.model.ClientTicketSalix
import es.verdnatura.presentation.view.feature.delivery.model.DeliveryInfo
import es.verdnatura.presentation.view.feature.delivery.model.ExpeditionInfoList
import es.verdnatura.presentation.view.feature.delivery.model.ExpeditionInfoLoadUnload
import es.verdnatura.presentation.view.feature.delivery.model.ExpeditionInfoLog
import es.verdnatura.presentation.view.feature.delivery.model.ExpeditionInfoSummary
import es.verdnatura.presentation.view.feature.delivery.model.ExpeditionList
import es.verdnatura.presentation.view.feature.delivery.model.ExpeditionSummaryList
import es.verdnatura.presentation.view.feature.delivery.model.FreeLanceDeliveryInfoList
import es.verdnatura.presentation.view.feature.delivery.model.RouteDelivery
import es.verdnatura.presentation.view.feature.delivery.model.RouteDeliveryList
import es.verdnatura.presentation.view.feature.delivery.model.RouteInfo
import es.verdnatura.presentation.view.feature.delivery.model.RouteList
import es.verdnatura.presentation.view.feature.delivery.model.Ticket
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody
import org.json.JSONArray
import org.json.JSONObject
import retrofit2.Call
import retrofit2.Response
import java.io.File

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

    private val _expeditionInfoList by lazy { MutableLiveData<ExpeditionInfoList>() }
    val expeditionInfoList: LiveData<ExpeditionInfoList> = _expeditionInfoList

    private val _expeditionInfoLoadUnloadList by lazy { MutableLiveData<ExpeditionList>() }
    val expeditionInfoLoadUnloadList: LiveData<ExpeditionList> = _expeditionInfoLoadUnloadList

    private val _expeditionInfoSummary by lazy { MutableLiveData<ExpeditionSummaryList>() }
    val expeditionInfoSummary: LiveData<ExpeditionSummaryList> = _expeditionInfoSummary

    private val _routeList by lazy { MutableLiveData<RouteList>() }
    val routeList: LiveData<RouteList> = _routeList

    private val _clientTicketList by lazy { MutableLiveData<ClientTicketList>() }
    val clientTicketList: LiveData<ClientTicketList> = _clientTicketList

    private val _routeInfoList by lazy { MutableLiveData<RouteDeliveryList>() }
    val routeInfoList: LiveData<RouteDeliveryList> = _routeInfoList

    private val _freelanceInfoList by lazy { MutableLiveData<FreeLanceDeliveryInfoList>() }
    val freelanceInfoList: LiveData<FreeLanceDeliveryInfoList> = _freelanceInfoList

    private val _companyInfoList by lazy { MutableLiveData<FreeLanceDeliveryInfoList>() }
    val companyInfoList: LiveData<FreeLanceDeliveryInfoList> = _companyInfoList

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

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

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

    private val _responseSign by lazy { MutableLiveData<ResponseItemVO>() }
    val responseSign: LiveData<ResponseItemVO> = _responseSign

    private val _expeditionList by lazy { MutableLiveData<ExpeditionList>() }
    val expeditionList: LiveData<ExpeditionList> = _expeditionList

    val loadRouteList = Transformations.map(_routeList) { Event(it) }

    private val _responseLoadList by lazy { MutableLiveData<ResponseItemVO>() }
    val responseLoadList: LiveData<ResponseItemVO> = _responseLoadList

    private val _responseStateList by lazy { MutableLiveData<ResponseItemVO>() }
    val responseStateList: LiveData<ResponseItemVO> = _responseStateList

    fun companyGetFiscaldata(
        userId: Int
    ) {
        salix.companyGetFiscaldata(arrayListOf(userId))
            .enqueue(object : SalixCallback<List<DeliveryInfo>>(context) {
                override fun onSuccess(response: Response<List<DeliveryInfo>>) {
                    _companyInfoList.value = response.body()?.let { FreeLanceDeliveryInfoList(it) }
                }

            })
    }

    fun expeditionGetLog(
        expedition: Int
    ) {
        salix.getExpeditionStates(
            """{"where": {"expeditionFk": $expedition},"include": [{"relation": "expeditionStateType","scope": {"fields": ["id","description"]}}],"fields": {"id": true,"created": true,"typeFk": true}}"""
        ).enqueue(object : SalixCallback<List<ExpeditionInfoLog>>(context) {
            override fun onSuccess(response: Response<List<ExpeditionInfoLog>>) {
                _expeditionInfoList.value = response.body()?.let { ExpeditionInfoList(it) }
            }

        })
    }

    fun getExpeditionFromRoute(
        route: Int
    ) {
        salix.expeditionGetFromRoute(arrayListOf(route))
            .enqueue(object : SalixCallback<List<ExpeditionInfoLoadUnload>>(context) {
                override fun onSuccess(response: Response<List<ExpeditionInfoLoadUnload>>) {
                    _expeditionInfoLoadUnloadList.value =
                        response.body()?.let { ExpeditionList(it) }
                }

                override fun onError(t: Throwable) {
                    _responseLoadList.value = ResponseItemVO("", true, t.message.toString(), 0)

                }
            })
    }

    fun get_routesFromExpedition(
        expedition: Int
    ) {
        salix.getRoutesFromExpedition(
            filter = """{
             "where": {
                "id": $expedition
                },
            "fields": [
            "id",
            "ticketFk"
            ],
            "include": [
            {
                "relation": "ticket",
                "scope": {
                "include": {
                "relation": "route",
                "scope": {
                "fields": [
                "id",
                "created",
                "agencyModeFk",
                "routeFk"
                ],
                "include": {
                "relation": "agencyMode",
                "scope": {
                "include": {
                "relation": "agency",
                "scope": {
                "fields": [
                "name"
                ]
            }
            },
                "fields": [
                "id",
                "agencyFk"
                ]
            }
            }
            }
            },
                "fields": [
                "id",
                "nickname",
                "routeFk"
                ]
            }
            }
            ]
        }""".trim()
        )
            // silex.get_routesFromExpedition(expedition)
            .enqueue(object : SalixCallback<List<RouteDelivery>>(context) {
                override fun onSuccess(response: Response<List<RouteDelivery>>) {
                    if (response.body() != null) {
                        _routeInfoList.value = response.body()?.let { RouteDeliveryList(it) }

                    }
                }

                override fun onError(t: Throwable) {
                    _routeInfoList.value = RouteDeliveryList()
                    super.onError(t)
                }
            })

    }

    fun expeditionStateAddSalix(expeditions: Any) {

        salix.addExpeditionState(expeditions).enqueue(object : SalixCallback<Unit>(context) {
            override fun onSuccess(response: Response<Unit>) {
                _responseStateAdd.value = ResponseItemVO("", false, "", 0)
            }

            override fun onError(t: Throwable) {
                super.onError(t)
                _responseStateAdd.value = ResponseItemVO()
            }

            override fun onFailure(call: Call<Unit>, t: Throwable) {
                _responseStateAdd.value = ResponseItemVO("", true, t.message.toString(), 0)

            }
        })
    }

    fun getInfoFreelance(
        userId: Int
    ) {
        salix.freelanceGetInfo(arrayListOf(userId))
            .enqueue(object : SalixCallback<List<DeliveryInfo>>(context) {
                override fun onSuccess(response: Response<List<DeliveryInfo>>) {

                    _freelanceInfoList.value =
                        response.body()?.let { FreeLanceDeliveryInfoList(it) }

                }

            })
    }

    fun routeGetExpeditionSummary(
        route: Int
    ) {
        //Tarea 6275
        salix.routeGetExpeditionSummary(route)
            .enqueue(object : SalixCallback<List<ExpeditionInfoSummary>>(context) {

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

                    if (response.body() != null) {
                        _expeditionInfoSummary.value =
                            response.body()?.let { ExpeditionSummaryList(it) }
                    } else {
                        _expeditionInfoSummary.value = ExpeditionSummaryList()
                    }
                }

                override fun onError(t: Throwable) {
                    _expeditionInfoSummary.value = ExpeditionSummaryList()
                    super.onError(t)

                }
            })
    }

    fun getRoutes(
    ) {

        salix.getRoutes().enqueue(object : SalixCallback<MutableList<RouteInfo>>(context) {

            override fun onSuccess(response: Response<MutableList<RouteInfo>>) {
                _routeList.value = response.body()?.let { RouteList(it) }
            }

            override fun onError(t: Throwable) {
                //_routeList.value = RouteList()
                _responseLoadList.value = ResponseItemVO("", true, t.message.toString(), 0)
                //super.onError(t)

            }

            override fun onFailure(call: Call<MutableList<RouteInfo>>, t: Throwable) {
                _responseLoadList.value = ResponseItemVO("", true, t.message.toString(), 0)
            }
        })
    }

    fun getTickets(
        routeId: Long
    ) {
        salix.getTickets("""{"id":$routeId,"order":["priority","id"],"limit":1}""")
            .enqueue(object : SalixCallback<MutableList<ClientTicketSalix>>(context) {
                override fun onSuccess(response: Response<MutableList<ClientTicketSalix>>) {
                    _clientTicketList.value = response.body()?.let { ClientTicketList(it) }
                }

                override fun onError(t: Throwable) {
                   _responseLoadList.value = ResponseItemVO("", true, t.message.toString(), 0)

                }
            })
    }

    fun driverRouteEmail(
        routeId: Long, email: String
    ) {
        salix.driverRouteEmail(id = routeId, hashMapOf("recipient" to email))
            .enqueue(object : SalixCallback<Any>(context) {})
    }

    fun routeUpdate(
        route: RouteInfo
    ) {
        salix.routeUpdate(route.id, route).enqueue(object : SalixCallback<Any>(context) {

            override fun onSuccess(response: Response<Any>) {
                _responseUpdateRoute.value = ResponseItemVO()
                super.onSuccess(response)

            }

            override fun onError(t: Throwable) {
                _responseUpdateRoute.value = ResponseItemVO()
                super.onError(t)

            }
        })
    }

    fun addNotes(
        listTickets: MutableList<Ticket>, note: String

    ) {
        salix.addNote(
            arrayListOf(listTickets[0].Id, note).formatWithQuotes()
        ).enqueue(object : SalixCallback<Any>(context) {})
    }

    fun imageUpload(
        warehouseId: Number,
        companyId: Number,
        dmsTypeId: Number,
        reference: String,
        description: String,
        hasFile: Boolean,
        file: MultipartBody.Part
    ) {
        salix.imageUpload(warehouseId, companyId, dmsTypeId, reference, description, hasFile, file)
            .enqueue(object : SalixCallback<Any>(context) {})
    }

    fun saveSign(filePath: String, mapQuery: Map<String?, String?>) {
        val filePart = MultipartBody.Part.createFormData(
            "file", File(filePath).name, RequestBody.create(
                MediaType.parse("image/png"), File(filePath)
            )
        )
        salix.saveSign(filePart, mapQuery).enqueue(object : SalixCallback<Any>(context) {

            override fun onSuccess(response: Response<Any>) {
                _responseSign.value = ResponseItemVO(filePath, false, "", 0)

            }

            //Otro fallo
            override fun onError(t: Throwable) {
                _responseSign.value = ResponseItemVO(
                    "", true, "Tickets:" + File(filePath).name + "→" + t.message.toString(), 0
                )
                //   super.onError(t)
            }

            //Fallo de red
            override fun onFailure(call: Call<Any>, t: Throwable) {
                _responseSign.value = ResponseItemVO("NetWork Error", true, t.message.toString(), 0)
            }

        })
    }
}

fun createJSONObject(listTickets: MutableList<Ticket>, note: String): String {
    // Supongamos que tienes la lista de tickets y el valor como los siguientes:
    // val listTickets: List<String> = listOf("4255452", "5454515")
    // Crear el objeto JSON
    val jsonObject = JSONObject()
    val jsonArrayTickets = JSONArray(listTickets)
    jsonObject.put("tickets", jsonArrayTickets)
    jsonObject.put("note", note)

    // Convertir el objeto JSON a un String
    return jsonObject.toString()
}



