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

import android.app.AlertDialog
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import es.verdnatura.R
import es.verdnatura.databinding.FragmentAjustesBinding
import es.verdnatura.domain.ConstAndValues.ANDROID_ID
import es.verdnatura.domain.ConstAndValues.HOLDPOSITION
import es.verdnatura.domain.ConstAndValues.ITEMPACKING
import es.verdnatura.domain.ConstAndValues.MENUBYDEFAULTSELECTED
import es.verdnatura.domain.ConstAndValues.NUMBEROFWAGONS
import es.verdnatura.domain.ConstAndValues.PRINTERFK
import es.verdnatura.domain.ConstAndValues.PRINTERNAME
import es.verdnatura.domain.ConstAndValues.SECTORDESCRIP
import es.verdnatura.domain.ConstAndValues.SECTORFK
import es.verdnatura.domain.ConstAndValues.TRAINFK
import es.verdnatura.domain.ConstAndValues.TRAINNAME
import es.verdnatura.domain.ConstAndValues.WAREHOUSEFK
import es.verdnatura.domain.notNull
import es.verdnatura.presentation.base.BaseFragment
import es.verdnatura.presentation.common.OnAjustesItemClickListener
import es.verdnatura.presentation.common.OnOptionsSelectedListener
import es.verdnatura.presentation.common.ToolBarAdapterTooltip
import es.verdnatura.presentation.view.component.CustomDialog
import es.verdnatura.presentation.view.feature.ajustes.adapter.SettingsAdapter
import es.verdnatura.presentation.view.feature.ajustes.model.AjustesItemVO
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.Train
import es.verdnatura.presentation.view.feature.articulo.model.ItemPackingType
import es.verdnatura.presentation.view.feature.login.fragment.LoginViewModel
import es.verdnatura.presentation.view.feature.pasillero.fragment.PasilleroViewModel
import es.verdnatura.presentation.view.feature.pasillero.model.CodeWorkerAction
import es.verdnatura.presentation.view.feature.pasillero.model.PasillerosItemVO
import kotlinx.coroutines.runBlocking

class AjustesFragment :
    BaseFragment<FragmentAjustesBinding, AjustesViewModel>(AjustesViewModel::class) {

    private lateinit var customDialog: CustomDialog
    private var sectorListVO: List<SectorItemVO> = listOf()
    private var printersList: MutableList<Printers> = mutableListOf()
    private var trainsList: List<Train> = listOf()
    private var settingsAdapter: SettingsAdapter? = null
    private var itemPackingList: List<ItemPackingType> = listOf()
    private var messagePrinter: String? = null
    private lateinit var loginViewModel: LoginViewModel
    private lateinit var pasilleroViewModel: PasilleroViewModel

    companion object {
        fun newInstance() = AjustesFragment()
    }

    override fun getLayoutId(): Int = R.layout.fragment_ajustes

    override fun onCreate(savedInstanceState: Bundle?) {
        customDialog = CustomDialog(requireContext())
        super.onCreate(savedInstanceState)

    }

    override fun init() {

        binding.mainToolbar.toolbarTitle.text = getString(R.string.settings)
        hideBackButton(binding.mainToolbar)
        getUserData()
        binding.userText.text = mobileApplication.userName
        binding.itemVersion.text = requireActivity().packageManager.getPackageInfo(
            requireActivity().packageName, 0
        ).versionName!!
        binding.androididText.text =
            mobileApplication.dataStoreApp.readDataStoreKey<String>(ANDROID_ID)
        binding.serialNumber.text = mobileApplication.serialNumber
        pasilleroViewModel = PasilleroViewModel(mobileApplication)
        setToolBar()
        super.init()
    }

    private fun setToolBar() {

        val listIcons: ArrayList<ImageView> = ArrayList()
        val iconInfo = ImageView(context)
        iconInfo.setImageResource(R.drawable.ic_info_delivery)

        listIcons.add(iconInfo)
        binding.mainToolbar.toolbarIcons.adapter =
            ToolBarAdapterTooltip(listIcons, object : OnOptionsSelectedListener {
                override fun onOptionsItemSelected(item: Drawable) {

                    customDialog.setTitle(getString(R.string.info))
                        .setDescription(
                            getString(R.string.version) + ":\t" +
                                    requireActivity().packageManager.getPackageInfo(
                                        requireActivity().packageName, 0
                                    ).versionName!! + "(${getVersionCode()})" + "\n" +
                                    getString(R.string.user) + ":\t" +
                                    mobileApplication.userName + "\n" +
                                    getString(R.string.androidid) + ":\t" +
                                    mobileApplication.dataStoreApp.readDataStoreKey<String>(
                                        ANDROID_ID
                                    ) + "\n" +
                                    if (!mobileApplication.serialNumber.isNullOrBlank()) {
                                        getString(R.string.serialNumber) + "\t" +
                                                mobileApplication.serialNumber
                                    } else ""

                        )
                        .setOkButton(getString(R.string.Close)) {
                            customDialog.dismiss()
                        }.show()

                }
            })
        binding.mainToolbar.toolbarIcons.layoutManager =
            LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
    }

    private fun getVersionCode(): Long {
        val context = requireContext()
        val packageManager: PackageManager = context.packageManager
        val packageInfo: PackageInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            packageManager.getPackageInfo(
                context.packageName,
                PackageManager.PackageInfoFlags.of(0)
            )
        } else {
            @Suppress("DEPRECATION")
            packageManager.getPackageInfo(context.packageName, 0)
        }

        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            packageInfo.longVersionCode
        } else {
            @Suppress("DEPRECATION")
            packageInfo.versionCode.toLong()
        }
    }

    override fun observeViewModel() {
        with(viewModel) {

            settingsAdapter = SettingsAdapter(settingsItem, object : OnAjustesItemClickListener {
                override fun onAjustesItemClickListener(item: AjustesItemVO) {
                    when (item.title) {
                        getString(R.string.sector) -> viewModel.getSectorsSalix()
                        getString(R.string.closeSession) -> ma.onMyBackPressed()
                        getString(R.string.printerLabel) -> {
                            messagePrinter = getString(R.string.SelectPrinter)
                            viewModel.printerGet(
                                mobileApplication.dataStoreApp.readDataStoreKey(
                                    SECTORFK
                                )
                            )
                        }

                        getString(R.string.vehicleControl) -> ma.onPasillerosItemClickListener(
                            PasillerosItemVO(
                                title = R.string.titleUserControlVehicle
                            ), mobileApplication.userId.toString()
                        )

                        getString(R.string.menuByDefault) -> showMenuByDefault()
                        getString(R.string.settingsTitleItemPacking) -> if (item.action) viewModel.getItemPackingTypeSalix()
                        getString(R.string.settingsTitleTrain) -> if (item.action) viewModel.trainGet()
                        getString(R.string.runActivityStop) -> pasilleroViewModel.workerActivityAdd(
                            CodeWorkerAction.STOP
                        )

                        else -> {}
                    }

                }
            })


            loadActionUpdate.observe(viewLifecycleOwner) { event ->
                event.getContentIfNotHandled().notNull {
                    messagePrinter =
                        getString(R.string.SelectPrinter) + "\n" + getString(R.string.printerRemoved)
                    viewModel.printerGet(mobileApplication.dataStoreApp.readDataStoreKey(SECTORFK))
                }
            }

            binding.setttingsItems.adapter = settingsAdapter
            binding.setttingsItems.layoutManager =
                LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)

            loadSectorList.observe(viewLifecycleOwner) { event ->
                event.getContentIfNotHandled().notNull { it ->

                    if (it.list.isNotEmpty()) {
                        val listSectores: ArrayList<String> = ArrayList()
                        it.list.forEach {
                            listSectores.add(it.description)
                        }
                        // modificar
                        listSectores.sort()
                        val array = arrayOfNulls<String>(listSectores.size)
                        sectorListVO = it.list
                        showDialogForAll(
                            listSectores.toArray(array), getString(R.string.selectSector)
                        )

                    } else {
                        customDialog.setTitle(getString(R.string.sectors))
                            .setDescription(getString(R.string.Noexistessectores))
                            .setOkButton(getString(R.string.Close)) {
                                customDialog.dismiss()
                            }.show()
                    }

                }
            }
            loadItemPackingList.observe(viewLifecycleOwner) { event ->
                event.getContentIfNotHandled().notNull { it ->

                    if (it.list.isNotEmpty()) {
                        val listItemsPacking: ArrayList<String> = ArrayList()
                        it.list.forEach {
                            listItemsPacking.add(it.description)
                        }
                        val array = arrayOfNulls<String>(listItemsPacking.size)
                        itemPackingList = it.list
                        showDialogForAll(
                            listItemsPacking.toArray(array),
                            getString(R.string.settingsTitleItemPacking)
                        )

                    } else {
                        customDialog.setTitle(getString(R.string.settingsTitleItemPacking))
                            .setDescription(getString(R.string.NoItemPackingType))
                            .setOkButton(getString(R.string.Close)) {
                                customDialog.dismiss()
                            }.show()
                    }

                }
            }
            loadPrintersList.observe(viewLifecycleOwner) { event ->
                event.getContentIfNotHandled().notNull { it ->

                    if (it.list.isNotEmpty()) {
                        val listPrinters: ArrayList<String> = ArrayList()
                        it.list.forEach {
                            listPrinters.add(it.name)
                        }
                        val array = arrayOfNulls<String>(listPrinters.size)
                        printersList = it.list
                        showDialogForAll(listPrinters.toArray(array), messagePrinter ?: "")

                    } else {
                        viewModel.settingsItem[2].selected = getString(R.string.noprinter)
                        settingsAdapter!!.notifyItemChanged(2)
                        customDialog.setTitle(getString(R.string.printers))
                            .setDescription(getString(R.string.Noprinters))
                            .setOkButton(getString(R.string.Close)) {
                                customDialog.dismiss()
                                handleUserCall()
                            }.show()
                    }

                }
            }
            loadTrainList.observe(viewLifecycleOwner) { event ->
                event.getContentIfNotHandled().notNull { it ->

                    if (it.list.isNotEmpty()) {
                        val listTrain: ArrayList<String> = ArrayList()
                        it.list.forEach {
                            listTrain.add(it.name)
                        }
                        val array = arrayOfNulls<String>(listTrain.size)
                        trainsList = it.list
                        showDialogForAll(
                            listTrain.toArray(array), getString(R.string.selectTrain)
                        )

                    }

                }
            }
        }
        super.observeViewModel()
    }

    private fun getUserData() {

        loginViewModel = LoginViewModel(requireActivity().applicationContext)
        /*  try {
              loginViewModel.operatorGetData(mobileApplication.userId!!)
          } catch (_: Exception) {
              ma.messageWithSound(
                  message = getString(R.string.errorGetData), isError = true, isPlayed = true
              )
          }
          loginViewModel.workerOperator.observe(this@AjustesFragment) { iti ->
              runBlocking { mobileApplication.dataStoreApp.saveDataOperator(iti) }
          }*/
        handleUserCall()
        loginViewModel.handleUserResponse.observe(this@AjustesFragment) { iti ->
            runBlocking { mobileApplication.dataStoreApp.saveWorkerData(iti) }
        }
        setSettings()
    }

    private fun handleUserCall() {
        val jsonData = mutableMapOf<String, Any>(
            "androidId" to mobileApplication.androidId,
            "nameApp" to getString(R.string.nameApp),
            "versionApp" to getInfoVersionNameApp()
        )
        loginViewModel.handleUser(if (getDevicePDA() != null) {
            jsonData.apply {
                this["deviceId"] = getDevicePDA().toString()  // Añadir nuevo campo
            }
        } else {
            jsonData
        }

        )
    }

    private fun showMenuByDefault() {

        pasilleroViewModel.inititializeDefaultDataInit()
        val arrayList: ArrayList<String> = arrayListOf()

        pasilleroViewModel.pasillerositem.forEach {
            arrayList.add(getString(it.title!!))
        }
        arrayList.add(getString(R.string.all))
        arrayList.sorted()
        showDialogForAll((arrayList).toTypedArray(), getString(R.string.menuByDefault))
    }

    private fun setSettings() {

        runBlocking {

            viewModel.inititializeDefaultAjusts(
                mobileApplication.dataStoreApp.readDataStoreKey(SECTORDESCRIP),
                mobileApplication.dataStoreApp.readDataStoreKey(SECTORFK),
                (mobileApplication.dataStoreApp.readDataStoreKey(NUMBEROFWAGONS) as Int).toString(),
                mobileApplication.dataStoreApp.readDataStoreKey(PRINTERFK),
                mobileApplication.dataStoreApp.readDataStoreKey(PRINTERNAME),
                mobileApplication.dataStoreApp.readDataStoreKey<String>(TRAINNAME),
                mobileApplication.dataStoreApp.readDataStoreKey<String>(ITEMPACKING),
                menuDefault = mobileApplication.dataStoreApp.readDataStoreKey(
                    MENUBYDEFAULTSELECTED
                ),
                holdPosition = mobileApplication.dataStoreApp.readDataStoreKey<Boolean>(HOLDPOSITION),

                )
        }
        binding.splashProgress.visibility = View.GONE
    }

    private fun showDialogForAll(array: Array<String>, title: String) {
        val builder = AlertDialog.Builder(this.context)
        builder.setTitle(title)

        val adapter = object :
            ArrayAdapter<String>(requireContext(), android.R.layout.simple_list_item_1, array) {
            override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
                val view = super.getView(position, convertView, parent)
                val textView = view.findViewById<TextView>(android.R.id.text1)

                val positionPrinterEmergency =
                    printersList.indexOfFirst { printer -> printer.sector?.backupPrinterFk == printer.id }

                if (position == positionPrinterEmergency) {
                    textView.setTextColor(Color.RED)
                } else {
                    textView.setTextColor(Color.BLACK)
                }


                return view
            }
        }


        builder.setAdapter(adapter) { _, which ->
            val selected = array[which]
            when (title) {
                getString(R.string.settingsTitleItemPacking) -> {
                    itemPackingList.forEach {
                        if (it.description == selected) {

                            runBlocking {
                                mobileApplication.dataStoreApp.editDataStoreKey(
                                    ITEMPACKING, it.description
                                )
                            }
                            viewModel.settingsItem[4].selected = it.description
                            viewModel.operatorUpdate(
                                workerId = mobileApplication.userId!!,
                                hashMapOf("itemPackingTypeFk" to it.description)
                            )
                            settingsAdapter!!.notifyItemChanged(4)

                            return@forEach
                        }
                    }
                }

                getString(R.string.selectSector) -> {
                    sectorListVO.forEach {
                        if (it.description == selected) {

                            runBlocking {
                                mobileApplication.dataStoreApp.editDataStoreKey(
                                    PRINTERNAME, getString(R.string.noprinter)
                                )
                                mobileApplication.dataStoreApp.editDataStoreKey(PRINTERFK, -1)

                                mobileApplication.dataStoreApp.editDataStoreKey(
                                    SECTORDESCRIP, it.description
                                )
                                mobileApplication.dataStoreApp.editDataStoreKey(
                                    SECTORFK, it.id
                                )
                                it.warehouseFk?.let { it1 ->
                                    mobileApplication.dataStoreApp.editDataStoreKey(
                                        WAREHOUSEFK, it1
                                    )
                                }
                            }

                            viewModel.settingsItem[0].sectorFk = it.id
                            viewModel.settingsItem[0].selected = it.description
                            viewModel.workerUpdateOperatorSalix(
                                "sector", mobileApplication.userId!!, it.id, null
                            )

                            settingsAdapter!!.notifyItemChanged(0)

                            return@forEach
                        }
                    }
                }

                getString(R.string.selectTrain) -> {
                    trainsList.forEach {
                        if (it.name == selected) {

                            runBlocking {
                                mobileApplication.dataStoreApp.editDataStoreKey(TRAINNAME, it.name)
                                mobileApplication.dataStoreApp.editDataStoreKey(TRAINFK, it.id)
                            }

                            viewModel.settingsItem[3].selected = it.name
                            viewModel.operatorUpdate(
                                workerId = mobileApplication.userId!!,
                                hashMapOf("trainFk" to it.id.toString())
                            )
                            settingsAdapter!!.notifyItemChanged(3)

                            return@forEach
                        }
                    }
                }

                getString(R.string.menuByDefault) -> {
                    array.forEach {
                        if (it == selected) {
                            runBlocking {
                                mobileApplication.dataStoreApp.editDataStoreKey(
                                    MENUBYDEFAULTSELECTED, if (it != getString(R.string.all)) {
                                        it
                                    } else {
                                        ""
                                    }
                                )
                            }
                            viewModel.settingsItem[6].selected = it
                            settingsAdapter!!.notifyItemChanged(6)

                            return@forEach

                        }
                    }
                }

                else -> {
                    val printer = printersList.find { it.name == selected }
                    if (printer != null) {
                        if (printer.sector?.backupPrinterFk == printer.id) {
                            showWarningPrinter(printer.name, printer.id)
                        } else {
                            savePrinter(printer.name, printer.id)
                        }
                    }
                    printersList.clear()
                }
            }

        }
        val dialog = builder.create()
        dialog.show()
    }

    private fun savePrinter(name: String, id: Int) {
        runBlocking {
            mobileApplication.dataStoreApp.editDataStoreKey(
                PRINTERNAME, name
            )
            mobileApplication.dataStoreApp.editDataStoreKey(
                PRINTERFK, id
            )
        }

        viewModel.settingsItem[2].selected = name
        viewModel.workerUpdateOperatorSalix(
            entity = "printer",
            workerFk = mobileApplication.userId!!,
            sectorFk = mobileApplication.dataStoreApp.readDataStoreKey(
                SECTORFK
            ),
            labelerFk = id
        )
        settingsAdapter!!.notifyItemChanged(2)
        handleUserCall()

    }

    private fun showWarningPrinter(name: String, id: Int) {
        val customWarningPrinter = CustomDialog(requireContext())

        customWarningPrinter.setTitle(getString(R.string.confirm)).setDescription(
            getString(R.string.selectPrinterEmergency)
        )

            .setOkButton(getString(R.string.yes)) {
                customWarningPrinter.dismiss()
                savePrinter(name, id)

            }.setKoButton(getString(R.string.no)) {
                customWarningPrinter.dismiss()

            }.show()

    }
}