package es.verdnatura.dataStore

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.longPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import com.google.gson.Gson
import es.verdnatura.MobileApplication
import es.verdnatura.R
import es.verdnatura.domain.ConstAndValues
import es.verdnatura.domain.ConstAndValues.BASEURLSALIX
import es.verdnatura.domain.ConstAndValues.BASE_URL_SALIX
import es.verdnatura.domain.ConstAndValues.NUMBEROFWAGONS
import es.verdnatura.domain.ConstAndValues.PRINTERFK
import es.verdnatura.domain.ConstAndValues.PRINTERFKDEFAULT
import es.verdnatura.domain.ConstAndValues.PRINTERNAME
import es.verdnatura.domain.ConstAndValues.SECTORDESCRIP
import es.verdnatura.domain.ConstAndValues.SECTORFK
import es.verdnatura.domain.ConstAndValues.SECTORFKDEFAULT
import es.verdnatura.domain.ConstAndValues.TRAINNAME
import es.verdnatura.domain.ConstAndValues.WAREHOUSEFK
import es.verdnatura.domain.ConstAndValues.WAREHOUSEFKDEFAULT
import es.verdnatura.domain.ConstAndValues.WORKFORMSELECTED
import es.verdnatura.presentation.view.feature.login.model.OperatorSalix
import es.verdnatura.presentation.view.feature.login.model.WorkForms
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking
import org.json.JSONObject
import java.util.Calendar

val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
val Context.dataStoreWork: DataStore<Preferences> by preferencesDataStore(name = "workForm")

class DataStoreLocal(var mobileApplication: MobileApplication) {

    suspend fun saveDataOperator(operator: OperatorSalix) {

        editDataStoreKey(
            SECTORFK, if (operator.sector != null) {
                operator.sector.id
            } else {
                SECTORFKDEFAULT
            }
        )
        editDataStoreKey(
            WAREHOUSEFK, if (operator.sector != null) {
                operator.sector.warehouseFk
            } else {
                WAREHOUSEFKDEFAULT
            }
        )
        editDataStoreKey(
            SECTORDESCRIP, if (operator.sector != null) {
                operator.sector.description
            } else {
                mobileApplication.getString(R.string.Sinsector)
            }
        )

        editDataStoreKey(
            PRINTERFK, if (operator.printer != null) {
                operator.printer.id
            } else {
                PRINTERFKDEFAULT
            }
        )
        editDataStoreKey(
            PRINTERNAME, if (operator.printer != null) {
                operator.printer.name
            } else {
                mobileApplication.getString(R.string.printerWithout)
            }
        )

        editDataStoreKey(
            TRAINNAME, if (operator.train != null) {
                operator.train.name
            } else {
                ""
            }
        )
        editDataStoreKey(
            NUMBEROFWAGONS, operator.numberOfWagons
        )

    }

    inline fun <reified T> readDataStoreKey(key: String): T {

        return when (T::class) {
            Int::class ->
                runBlocking {
                    mobileApplication.dataStore.data
                        .map { preferences -> preferences[intPreferencesKey(key)] ?: -1 }
                        .first() as T
                }

            String::class -> runBlocking {
                mobileApplication.dataStore.data
                    .map { preferences ->
                        preferences[stringPreferencesKey(key)] ?: if (key == BASEURLSALIX) {
                            BASE_URL_SALIX
                        } else {
                            ""
                        }
                    }
                    .first() as T
            }

            Boolean::class -> runBlocking {
                mobileApplication.dataStore.data
                    .map { preferences -> preferences[booleanPreferencesKey(key)] ?: false }
                    .first() as T
            }

            Long::class -> runBlocking {
                mobileApplication.dataStore.data
                    .map { preferences -> preferences[longPreferencesKey(key)] ?: 0 }
                    .first() as T
            }

            else -> "ERROR" as T
        }

    }

    suspend fun editDataStoreKey(key: String, value: Any) {

        mobileApplication.dataStore.edit { preferences ->
            when (value) {
                is Int -> preferences[intPreferencesKey(key)] = value
                is String -> preferences[stringPreferencesKey(key)] = value
                is Boolean -> preferences[booleanPreferencesKey(key)] = value
                is Long -> preferences[longPreferencesKey(key)] = value
            }
        }

    }

    suspend fun deleteWorkForm(nameWorkForm: Preferences.Key<String>) {

        if (nameWorkForm.name == "all") {
            mobileApplication.dataStoreWork.edit {
                it.clear()
            }

        } else {
            mobileApplication.dataStoreWork.edit { preferences ->
                preferences.remove(nameWorkForm)
            }
            mobileApplication.dataStoreApp.editDataStoreKey(
                WORKFORMSELECTED, "Producción"
            )
            saveWorkForm(
                WorkForms(
                    "Producción",
                    "https://app.verdnatura.es",
                    "https://salix.verdnatura.es"
                )
            )
        }

    }

    suspend fun getWorkForm(): List<WorkForms> {
        var listForms: ArrayList<WorkForms> = ArrayList()
        val preferences = mobileApplication.dataStoreWork.data.first()

        preferences.asMap().forEach { entry ->
            val key = entry.key
            val value = entry.value

            var json2 = JSONObject(value.toString())

            listForms.add(
                WorkForms(
                    key.name,
                    json2.get("urlSilex").toString(),
                    json2.get("urlSalix").toString(),
                    json2.get("isShowDelete").toString().toBoolean(),
                    json2.get("created") as Long

                )
            )

        }

        if (listForms.isEmpty()) {
            createWorksDefault()
        }

        return listForms.sortedBy { it.created }
    }

    suspend fun createWorksDefault() {
        saveWorkForm(
            WorkForms(
                "Producción",
                "https://app.verdnatura.es",
                "https://salix.verdnatura.es"
            )
        )
        saveWorkForm(
            WorkForms(
                "Test",
                "https://test-app.verdnatura.es",
                urlSalix = "https://test-salix.verdnatura.es"
            )
        )
        var working_in_test = true
        if (working_in_test) {
            saveWorkForm(
                WorkForms(
                    "TestLocalhost",
                    "http://10.1.4.42:9000",
                    urlSalix = "https://test-salix.verdnatura.es"
                )
            )

            saveWorkForm(
                WorkForms(
                    "TestHome",
                    "http://192.168.1.132:9000",
                    urlSalix = "https://test-salix.verdnatura.es"
                )
            )
            saveWorkForm(
                WorkForms(
                    "TestLOCAL",
                    "http://10.1.4.42:9000",
                    urlSalix = "http://10.1.4.42:3000"
                )
            )
            saveWorkForm(
                WorkForms(
                    "TestLOCALHOME",
                    "http://192.168.1.132:9000",
                    urlSalix = "http://192.168.1.132:3000"
                )
            )
        } else {
            //deleteWorkForm("all")
        }
        saveWorkForm(
            WorkForms(
                "Añadir...",
                "",
                "",
                created = Calendar.getInstance().timeInMillis + Calendar.getInstance().timeInMillis

            )
        )

    }

    suspend fun saveWorkForm(workForm: WorkForms) {

        var gson = Gson()
        var json = gson.toJson(workForm)
        mobileApplication.dataStoreWork.edit { preferences ->
            preferences[stringPreferencesKey(workForm.name)] = json
        }

        runBlocking {
            mobileApplication.dataStoreApp.editDataStoreKey(
                ConstAndValues.BASEURL,
                workForm.urlSilex
            )
            mobileApplication.dataStoreApp.editDataStoreKey(
                BASEURLSALIX,
                workForm.urlSalix
            )
        }

    }
}