package es.verdnatura.presentation.base

import android.Manifest
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.LayoutRes
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.preference.PreferenceManager
import androidx.room.Room
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import es.verdnatura.MobileApplication
import es.verdnatura.R
import es.verdnatura.databinding.ToolbarFragmentBinding
import es.verdnatura.db.DeliveryDatabase
import es.verdnatura.domain.ConstAndValues.SECTORFKDEFAULT
import es.verdnatura.domain.ConstAndValues.WAREHOUSEFKDEFAULT
import es.verdnatura.presentation.view.feature.login.model.OperatorSalix
import es.verdnatura.presentation.view.feature.login.model.WorkForms
import es.verdnatura.presentation.view.feature.main.activity.MainActivity
import org.json.JSONObject
import org.koin.androidx.viewmodel.ext.android.viewModel
import timber.log.Timber
import java.util.*
import kotlin.collections.Map.*
import kotlin.reflect.KClass


abstract class BaseFragment<T : ViewDataBinding, V : BaseViewModel>(viewModelClass: KClass<V>) :
    Fragment() {
    protected lateinit var mobileApplication: MobileApplication
    protected val TAG = "VERDNATURA::"
    protected val PREFS_USER = "es.verdnatura.user.prefs"
    protected val PREFS_SERVER = "es.verdnatura.server.prefs"
    protected val USERFK = "userFk"
    protected val USER = "user"
    protected val PASSWORD = "password"
    protected val TOKEN = "token"
    protected val TTL = "ttl"
    protected val TOKENCREATED = "tokenCreated"
    protected val SECTORDESCRIP = "sectordescrip"
    protected val SECTORFK = "sectorFk"
    protected val NUMBEROFWAGONS = "operatorNumberOfWagons"
    protected val PRINTERNAME = "printername"
    protected val PRINTERFK = "printerFk"
    protected val WAREHOUSEFK = "warehouseFk"
    protected val REMEMBER = "recordar"
    protected val ANDROID_ID = "ANDROID_ID"
    protected val DEVICENAME = "devicename"
    protected val TRAINNAME = "trainName"
    protected val TRAINFK = "trainFk"
    protected val WORKFORMSELECTED = "workFormSelected"
    protected val SUPPLIERID = "SUPPLIERID"


    protected val ITEMPACKING = "itemPackingType"
    protected val ITEMPACKINGFK = "itemPackingTypeFk"

    //protected val VOZ = "voz"
    //nuevo campo número carros ajustes y campos para guardar el buyerid y buyernickname
    protected val BUYER = "buyernickname"
    protected val BUYERID = "buyerid"
    protected val WAGON = "wagon"
    protected val TAGSTYPE = "tagstype"
    protected val WAREHOUSEFK_DEFAULT = 60
    protected val DATENOVEHICLE = "DATENOVEHICLE"
    protected val DEPARTMENTMISTAKE = "DEPARTMENTMISTAKE"
    protected val DEPARTMENTMISTAKEID = "DEPARTMENTMISTAKEID"

    protected val viewModel: V by viewModel(viewModelClass)
    protected lateinit var binding: T

    // private var isOnReadyForSpeech = false
    protected lateinit var ma: MainActivity

    /*  private var textToSpeech: TextToSpeech? = null
      private var mAudioManager: AudioManager? = null
      protected var mSpeechRecognizer: SpeechRecognizer? = null
      private var mSpeechRecognizerIntent: Intent? = null*/

    /*  protected val NEW_COLLECTION = 0
      protected val LISTO = 1
      protected val CANCEL = 2
      protected val VOLVER = 3
      protected val REPITE = 4
      protected val OTRO = 5
      protected val FALTA = 6
      protected val ERROR = -1*/


    /*val allowedStrings =
        Arrays.asList(
            "cero", "uno", "dos", "tres", "cuatro", "cinco", "seis", "siete",
            "ocho", "nueve", "diez", "once", "doce", "trece", "catorce",
            "quince", "dieziseis", "diezisiete", "dieziocho", "diezinueve", "veinte",
            "treinta", "cuarenta", "cincuenta", "sesenta", "setenta", "ochenta", "noventa",
            "cien", "mil"
        )*/


    override fun onAttach(context: Context) {
        super.onAttach(context)

        if ((requireActivity().componentName).toString().contains("MainActivity")) {

            ma = activity as MainActivity
        }
        mobileApplication = requireActivity().application as MobileApplication
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? = inflater.inflate(getLayoutId(), container, false)

    /*sergio:deprecated. Se inicializa con onViewCreated
    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
         initDataBinding()
         getBundleArguments()
         observeViewModel()
         runSound()
        // requestRecordAudioPermission()
        requestRecordAudioPermissionNew()
         init()
    }*/

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initDataBinding()
        getBundleArguments()
        observeViewModel()
        //runSound()
        //requestRecordAudioPermission()
        //requestRecordAudioPermissionNew()

        //sergio: para llamadas con SIP
        //requestCallPhonePermissionNew()
        init()


    }


    @LayoutRes
    abstract fun getLayoutId(): Int
    open fun init() {}
    open fun observeViewModel() {}
    open fun getBundleArguments() {}
    open fun addBindingVariables() {}

    private fun initDataBinding() {
        binding = DataBindingUtil.bind<T>(requireView())!!
        binding.lifecycleOwner = viewLifecycleOwner
        binding.setVariable(BR.viewModel, this@BaseFragment.viewModel)
        lifecycle.addObserver(this@BaseFragment.viewModel)
        addBindingVariables()
    }

    fun textScanned_filterDouble(textScanned: String): String {

        if (textScanned.length > 13) {
            var size = textScanned.length
            if (textScanned.substring((size / 2), size) == textScanned.substring(0, size / 2)
            ) {
                return textScanned.substring(0, size / 2)

            }

        }
        return textScanned

    }

    fun getTooltip(image: Int): String {

        return when (image) {
            //itemCard
            R.drawable.ic_autorenew_black_24dp -> {
                getString(R.string.reloadItemData)
            }

            R.drawable.ic_history_black_24dp -> getString(R.string.showHistoricalItem)
            //presacador
            R.drawable.ic_local_parking_black_24dp -> getString(R.string.allowParking)
            //collection
            R.drawable.ic_print_black_24dp -> getString(R.string.printTicket)
            R.drawable.ic_playlist_add_black_24dp -> getString(R.string.addItem)
            R.drawable.ic_worker -> getString(R.string.showFacePicker)
            R.drawable.phone_call -> getString(R.string.callPicker)
            R.drawable.car -> getString(R.string.allowSelectVehicle)
            R.drawable.car_off -> getString(R.string.allowTakeoffVehicle)
            //REPETIDO:R.drawable.ic_history_black_24dp->"Realiza llamada al sacador"
            //sacador
            R.drawable.ic_add_black_24dp -> getString(R.string.newCollection)
            //REPETIDO: R.drawable.car->"Permite coger vehículo"
            //ubicador:
            //REPETIDO: R.drawable.ic_add_black_24dp->"Genera colección para sacar"
            //REPETIDO: ic_autorenew_black_24dp
            //historico articulo
            R.drawable.ic_transaction -> getString(R.string.showFilter)
            R.drawable.alpha_f_circle_outline -> getString(R.string.showFaults)
            R.drawable.alpha_b_circle_outline -> getString(R.string.showTrash)

            R.drawable.filter_outline -> getString(R.string.filterFlower)

            R.drawable.ic_mode_edit_black_24dp -> getString(R.string.allowChangeShelving)
            R.drawable.ic_delete_forever_black_24dp -> getString(R.string.deleteAllitems)
            R.drawable.ic_flash_auto_black_24dp -> getString(R.string.allowAutomaticAddItem)
            R.drawable.ic_logo_salix -> getString(R.string.accessSalix)
            R.drawable.ic_eye_ui -> getString(R.string.icViewCollection)
            R.drawable.ic_collection -> getString(R.string.icViewCollection)
            R.drawable.ic_ubicator_check -> getString(R.string.checkerUbication)
            R.drawable.ic_delivery_truck -> getString(R.string.loadRoute)
            R.drawable.ic_confirm -> getString(R.string.confirmDescription)

            R.drawable.camion -> getString(R.string.openLoadingConsignee)
            R.drawable.exit -> getString(R.string.exitScreen)
            R.drawable.ic_image_upload -> getString(R.string.messageUpload)

            R.drawable.expedition_find -> getString(R.string.showLogExpedition)
            R.drawable.ic_info_refresh -> getString(R.string.udpateRoutes)
            R.drawable.ic_info_delivery -> getString(R.string.info)
            R.drawable.ic_filter_inventory -> getString(R.string.filterNoReview)
            R.drawable.ic_remove_checks->getString(R.string.resetReviewItems)
            R.drawable.ic_eye_inventory -> getString(R.string.inventoryShowParking)
            R.drawable.ic_sort->getString(R.string.sortRouteSalix)
            R.drawable.ic_sign_ticket->getString(R.string.signed)
            R.drawable.ic_send-> getString(R.string.sendDriverRoute)
            R.drawable.ic_remove_checks-> getString(R.string.deleteChecked)
            else -> {
                ""
            }
        }

    }


    private fun requestCallPhonePermission() {
        val permissionLauncher = registerForActivityResult(
            ActivityResultContracts.RequestPermission()
        )
        { isGranted ->
            if (isGranted) {
                Timber.i("permisos ok")
            } else {
                Timber.i("Denegados permisos")
            }
        }

        permissionLauncher.launch(Manifest.permission.CALL_PHONE)
    }

    private fun requestRecordAudioPermissionNew() {

        val permissionLauncher = registerForActivityResult(
            ActivityResultContracts.RequestPermission()
        )
        { isGranted ->
            if (isGranted) {
                Timber.i("permisos ok")
            } else {
                Timber.i("Denegados permisos")
            }
        }

        permissionLauncher.launch(Manifest.permission.RECORD_AUDIO)
    }

    private fun requestCallPhonePermissionNew() {

        val permissionLauncher = registerForActivityResult(
            ActivityResultContracts.RequestPermission()
        )
        { isGranted ->
            if (isGranted) {
                Timber.i("permisos ok")
            } else {
                Timber.i("Denegados permisos")
            }
        }

        permissionLauncher.launch(Manifest.permission.CALL_PHONE)
    }

    fun hideBackButton(tool: ToolbarFragmentBinding) {
        tool.backButton.visibility = View.INVISIBLE
    }

    private fun getDefaults(key: String?, context: Context?): String? {
        val preferences = PreferenceManager.getDefaultSharedPreferences(context)
        return preferences.getString(key, null)
    }

    fun getDataInt(name: String): Int {
        val prefs: SharedPreferences = requireActivity().getSharedPreferences(PREFS_USER, 0)
        return when (name) {
            SECTORFK -> prefs.getInt(name, SECTORFKDEFAULT)
            WAREHOUSEFK -> prefs.getInt(name, WAREHOUSEFKDEFAULT)
            PRINTERFK -> prefs.getInt(name, 0)
            USERFK -> prefs.getInt(USERFK, 0)
            SUPPLIERID -> prefs.getInt(SUPPLIERID, 0)
            else -> {
                0
            }
        }

    }

    fun getData(name: String): String {
        val prefs: SharedPreferences = requireActivity().getSharedPreferences(PREFS_USER, 0)
        return when (name) {
            TOKEN -> prefs.getString(name, "").toString()
            ANDROID_ID -> prefs.getString(name, "0").toString()
            USERFK -> prefs.getString(USERFK, "").toString() //el id
            USER -> prefs.getString(USER, "").toString()
            PASSWORD -> prefs.getString(PASSWORD, "").toString()
            SECTORFK -> prefs.getInt(name, SECTORFKDEFAULT).toString()
            WAREHOUSEFK -> prefs.getInt(name, WAREHOUSEFKDEFAULT).toString()
            WAGON -> prefs.getInt(name, 2).toString()
            TAGSTYPE -> prefs.getString(name, getString(R.string.stickers)).toString()
            SECTORDESCRIP -> prefs.getString(name, getString(R.string.Sinsector)).toString()
            SECTORFK -> prefs.getInt(name, SECTORFKDEFAULT).toString()
            BUYER -> prefs.getString(name, "").toString()
            BUYERID -> prefs.getString(name, "").toString()
            DATENOVEHICLE -> prefs.getString(name, "0").toString()
            DEPARTMENTMISTAKE -> prefs.getString(name, "").toString()
            DEPARTMENTMISTAKEID -> prefs.getInt(name, 0).toString()
            PRINTERFK -> prefs.getInt(name, 0).toString()
            PRINTERNAME -> prefs.getString(name, getString(R.string.noprinter)).toString()
            NUMBEROFWAGONS -> prefs.getInt(name, 1).toString()
            TRAINFK -> prefs.getString(name, "").toString()
            TRAINNAME -> prefs.getString(name, "").toString()
            ITEMPACKING -> prefs.getString(name, "").toString()
            ITEMPACKINGFK -> prefs.getString(name, "").toString()
            WORKFORMSELECTED -> prefs.getString(name, "Producción").toString()
            "SUPPLIERNAME" -> prefs.getString(name, "").toString()
            "SUPPLIERID" -> prefs.getInt(name, 0).toString()
            "ENTRYTYPE" -> prefs.getString(name, "").toString()
            "ENTRYNUMBERIMAGES" -> prefs.getString(name, "0").toString()
            "ENTRYOBSERVATIONS" -> prefs.getString(name, "").toString()
            "SERIALNUMBER" -> prefs.getString(name, "").toString()

            "base_url" -> {
                val preferences = PreferenceManager.getDefaultSharedPreferences(context)
                preferences.getString(getString(R.string.baseurl), "").toString()
            }

            "base_urlSalix" -> {
                val preferences = PreferenceManager.getDefaultSharedPreferences(context)
                var serverSalix =
                    preferences.getString(getString(R.string.base_urlSalix), "").toString()
                if (serverSalix.isNullOrEmpty()) {
                    serverSalix = "https://salix.verdnatura.es"
                }
                return serverSalix
            }

            else -> {
                prefs.getString(name, "").toString()
            }
        }

    }

    fun removeSector() {
        val prefs: SharedPreferences = requireActivity().getSharedPreferences(PREFS_USER, 0)
        val editor = prefs.edit()
        editor.remove(SECTORFK).commit()
        editor.remove(SECTORDESCRIP).commit()
        editor.remove(WAREHOUSEFK).commit()

    }

    fun setDefaults(key: String?, value: String?, context: Context?) {

        val preferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
        val editor = preferences.edit()
        editor.putString(key, value)
        editor.commit()
    }

    fun removePrinter() {
        val prefs: SharedPreferences = requireActivity().getSharedPreferences(PREFS_USER, 0)
        val editor = prefs.edit()
        editor.remove(PRINTERFK).commit()
        editor.remove(PRINTERNAME).commit()

    }

    fun saveWorkForm(workForm: WorkForms) {
        var prefs: SharedPreferences = requireActivity().getSharedPreferences(PREFS_SERVER, 0)
        var editor = prefs.edit()
        var gson = Gson()
        var json = gson.toJson(workForm)
        editor.putString(workForm.name, json)
        editor.commit()

        saveData("base_url", workForm.urlSilex)
        saveData("base_urlSalix", workForm.urlSalix)
    }

    fun deleteWorkForm(nameWorkForm: String) {

        var prefs: SharedPreferences = requireActivity().getSharedPreferences(PREFS_SERVER, 0)
        var editor = prefs.edit()

        if (nameWorkForm == "all") {
            editor.clear().apply()
        } else {
            editor.remove(nameWorkForm).commit()
        }
    }


    fun getWorkForm(): List<WorkForms> {
        var listForms: ArrayList<WorkForms> = ArrayList()
        val prefs: SharedPreferences = requireActivity().getSharedPreferences(PREFS_SERVER, 0)
        val editor = prefs.edit()

        val keys: Map<String, *> = prefs.all
        for (Map in keys) {


            var json2 = JSONObject(Map.value.toString())

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


                )
            )

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

        return listForms.sortedBy { it.created }
    }

    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.51:9000",
                    urlSalix = "https://test-salix.verdnatura.es"
                )
            )
            saveWorkForm(
                WorkForms(
                    "TestLOCAL",
                    "http://10.1.4.42:9000",
                    urlSalix = "http://localhost:3000"
                )
            )
            saveWorkForm(
                WorkForms(
                    "TestLOCALHOME",
                    "http://192.168.1.51:9000",
                    urlSalix = "http://localhost:3000"
                )
            )
        } else {
            deleteWorkForm("all")
        }
        saveWorkForm(
            WorkForms(
                "Añadir...",
                "",
                "",
                created = Calendar.getInstance().timeInMillis + Calendar.getInstance().timeInMillis


            )
        )


    }

    fun saveData(name: String, value: Any) {

        val prefs: SharedPreferences = requireActivity().getSharedPreferences(PREFS_USER, 0)
        val editor = prefs.edit()

        when (name) {

            //ANDROID_ID -> editor.putString(name, value.toString())
            "base_url" -> {
                val preferences = PreferenceManager.getDefaultSharedPreferences(context)
                val editorPref = preferences.edit()
                editorPref.putString("base_url", value.toString())
                editorPref.commit()

            }

            "base_urlSalix" -> {
                val preferences = PreferenceManager.getDefaultSharedPreferences(context)
                val editorPref = preferences.edit()
                editorPref.putString("base_urlSalix", value.toString())
                editorPref.commit()
            }

            DEPARTMENTMISTAKEID -> {
                editor.putInt(name, value as Int)
            }

            "SUPPLIERID" -> {
                editor.putString(name, value.toString())
            }

            else -> {
                editor.putString(name, value.toString())
            }

        }
        editor.commit()


    }

    fun saveDataInt(name: String, value: Int) {

        val prefs: SharedPreferences = requireActivity().getSharedPreferences(PREFS_USER, 0)
        val editor = prefs.edit()

        when (name) {
            name -> editor.putInt(name, value)
            ANDROID_ID -> editor.putInt(name, value)
        }
        editor.apply()

    }

    fun saveDataOperator(operator: OperatorSalix) {
        if (operator.sector == null) {
            removeSector()
        } else {
            saveDataInt(SECTORFK, operator.sector.id)
            saveData(SECTORDESCRIP, operator.sector.description)
            saveDataInt(WAREHOUSEFK, operator.sector.warehouseFk)
        }
        if (operator.printer == null) {
            removePrinter()
        } else {
            saveDataInt(PRINTERFK, operator.printer.id)
            saveData(PRINTERNAME, operator.printer.name)
        }
        if (operator.train != null) {
            saveData(TRAINNAME, operator.train.name)
        }
        saveDataInt(NUMBEROFWAGONS, operator.numberOfWagons)

    }


    fun saveDataLong(name: String, value: Long) {

        val prefs: SharedPreferences = requireActivity().getSharedPreferences(PREFS_USER, 0)
        val editor = prefs.edit()

        when (name) {
            name -> editor.putLong(name, value)
        }
        editor.apply()

    }

    fun saveWorkingForms(list: ArrayList<String>) {
        val prefs: SharedPreferences = requireActivity().getSharedPreferences(PREFS_USER, 0)
        val editor = prefs.edit()
        editor.putString("workingForms", list.toString())
        editor.apply()
    }

    fun getWorkingForms(): Array<String> {
        val prefs: SharedPreferences = requireActivity().getSharedPreferences(PREFS_USER, 0)
        val jsonStr: String? = prefs.getString("workingForms", null)
        val gson = Gson()
        val lista: Array<String> = gson.fromJson(jsonStr, Array<String>::class.java)
        return lista
    }

    fun saveBuyer(buyernickname: String) {
        val prefs: SharedPreferences = requireActivity().getSharedPreferences(PREFS_USER, 0)
        val editor = prefs.edit()
        editor.putString(BUYER, buyernickname)
        editor.apply()
    }

    fun saveBuyerId(buyerid: String) {
        val prefs: SharedPreferences = requireActivity().getSharedPreferences(PREFS_USER, 0)
        val editor = prefs.edit()
        editor.putString(BUYERID, buyerid)
        editor.apply()
    }

    fun getIMEI(): String {
        val prefs: SharedPreferences = requireActivity().getSharedPreferences(PREFS_USER, 0)
        val imei = prefs.getString("IMEI", "0")
        return imei.toString()
    }


    fun getMessageFromJSON(json: String): String {
        val gson = Gson()
        var message = ""
        //  val mapType = object : TypeToken<Map<String, Any>>() {}.type

        var tutorialMap: Map<String, Any> =
            gson.fromJson(json, object : TypeToken<Map<String, Any>>() {}.type)
        tutorialMap.forEach {
            if (it.key.equals("Message")) {
                message = it.value.toString()
            }
        }
        return message
    }

    fun getListFromJSON(json: String): List<String> {
        val gson = Gson()
        var list = mutableListOf<String>()

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

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

            list.add(it.key + ":" + it.value)

        }
        return list
    }

}

fun database(myContext: Context): DeliveryDatabase {

    val db = Room.databaseBuilder(
        myContext,
        DeliveryDatabase::class.java, "expediciones.db"
    ).build()
    return db
}


