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

import android.annotation.SuppressLint
import android.content.Intent
import android.net.Uri
import android.provider.Settings
import android.view.View.GONE
import android.view.View.VISIBLE
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
import es.verdnatura.MobileApplication
import es.verdnatura.R
import es.verdnatura.databinding.FragmentLoginBinding
import es.verdnatura.domain.ConstAndValues.ANDROID_ID
import es.verdnatura.domain.ConstAndValues.BASEURLSALIX
import es.verdnatura.domain.ConstAndValues.PASSWORD
import es.verdnatura.domain.ConstAndValues.REMEMBER
import es.verdnatura.domain.ConstAndValues.RENEWINTERVAL
import es.verdnatura.domain.ConstAndValues.RENEWPERIOD
import es.verdnatura.domain.ConstAndValues.TOKEN
import es.verdnatura.domain.ConstAndValues.TOKENCREATED
import es.verdnatura.domain.ConstAndValues.TTL
import es.verdnatura.domain.ConstAndValues.USER
import es.verdnatura.domain.ConstAndValues.WORKFORMSELECTED
import es.verdnatura.domain.notNull
import es.verdnatura.domain.toast
import es.verdnatura.presentation.base.BaseFragment
import es.verdnatura.presentation.common.OnTrashItemRowClickListener
import es.verdnatura.presentation.common.OnWorkFormsItemRowClickListener
import es.verdnatura.presentation.view.component.CustomDialog
import es.verdnatura.presentation.view.component.CustomDialogInput
import es.verdnatura.presentation.view.component.CustomDialogInputThreeValues
import es.verdnatura.presentation.view.component.CustomDialogList
import es.verdnatura.presentation.view.feature.login.adapter.WorkFormAdapter
import es.verdnatura.presentation.view.feature.login.model.WorkForms
import es.verdnatura.presentation.view.feature.login.model.WorkerData
import es.verdnatura.presentation.view.feature.main.activity.MainActivity
import kotlinx.coroutines.runBlocking
import java.util.Date
import kotlin.system.exitProcess

class LoginFragment(private var imageUri: Uri?) :
    BaseFragment<FragmentLoginBinding, LoginViewModel>(LoginViewModel::class) {

    private lateinit var customDialogInput: CustomDialogInput
    private lateinit var customDialog: CustomDialog
    private lateinit var customNewForm: CustomDialogInputThreeValues
    private var workFormAdapter: WorkFormAdapter? = null
    private lateinit var customDialogList: CustomDialogList
    private lateinit var listForms: List<WorkForms>

    companion object {
        fun newInstance(imageUri: Uri?) = LoginFragment(imageUri)
    }

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

    override fun init() {

        customDialogList = CustomDialogList(requireContext())
        customDialog = CustomDialog(requireContext())
        customDialogInput = CustomDialogInput(requireContext())
        //createFolderSerial()
        setSwitch()
        saveIdentifiers()
        checkUser()
        binding.buttonLogin.setOnClickListener {
            viewModel.loginSalix(
                user = binding.edittextUsername.text.toString(),
                password = binding.edittextPassword.text.toString()

            )

        }
        if (mobileApplication.dataStoreApp.readDataStoreKey<String>(TOKEN)
                .isNotBlank() && binding.switchRemember.isChecked
        ) {
            handleUserCall()

        }

        binding.textviewRememberPassword.setOnClickListener {
            binding.edittextUsername.setText("")
            binding.edittextPassword.setText("")
            binding.switchRemember.isChecked = false
            runBlocking { mobileApplication.dataStoreApp.editDataStoreKey(REMEMBER, false) }
        }

        val myWorkFormSlected =
            mobileApplication.dataStoreApp.readDataStoreKey(WORKFORMSELECTED) as String

        if (myWorkFormSlected.isBlank()) {
            runBlocking {
                mobileApplication.dataStoreApp.editDataStoreKey(
                    WORKFORMSELECTED, "Producción"
                )
                mobileApplication.dataStoreApp.saveWorkForm(
                    WorkForms(
                        "Producción", "https://salix.verdnatura.es"
                    )
                )
            }
        }
        binding.edittextServer.setText(
            mobileApplication.dataStoreApp.readDataStoreKey(WORKFORMSELECTED) as String
        )

        if (binding.edittextServer.text.toString() == "TestLOCAL") {
            binding.edittextUsername.setText(getString(R.string.userDev))
            binding.edittextPassword.setText(getString(R.string.passDev))
        }
        //deleteWorkForm("all")
        listForms = runBlocking { mobileApplication.dataStoreApp.getWorkForm() }
        binding.edittextServer.keyListener = null
        binding.textviewWelcome.setOnLongClickListener {
            binding.textinputlayoutServer.visibility = VISIBLE
            true
        }
        binding.edittextServer.setOnLongClickListener {
            showWorkingForms()
            true
        }
        binding.edittextUsername.requestFocus()

    }

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

        )
    }

    private fun setSwitch() {
        binding.switchRemember.setOnCheckedChangeListener { _, isChecked ->
            runBlocking {
                mobileApplication.dataStoreApp.editDataStoreKey(
                    REMEMBER, isChecked
                )
            }

        }
    }

    /*    private fun getDevicePDA(): Int? {
            return try {
                Settings.Global.getString(
                    mobileApplication.contentResolver, Settings.Global.DEVICE_NAME
                ).toInt()
            } catch (ex: Exception) {
                null
            }

        }*/

    /*    private fun createFolderSerial() {

            val directory = File(
                requireContext().getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "/dataSerial"
            )

            if (!directory.exists()) {
                directory.mkdirs()
            }
            try {
                val filename = "serial.txt"
                val file = File(directory, filename)
                mobileApplication.serialNumber = file.readText()
            } catch (ex: Exception) {
                d("VERDNATURA:", getString(R.string.errorFile))
            }

        }*/

    private fun setAdapter(listWorkForms: List<WorkForms>) {

        workFormAdapter = WorkFormAdapter(listWorkForms, object : OnWorkFormsItemRowClickListener {

            override fun onWorkFormsItemRowClickListener(item: WorkForms) {

                when (item.name) {
                    getString(R.string.addWorkForm) -> {
                        showNewForm()
                    }

                    else -> {
                        binding.edittextServer.setText(item.name)
                        runBlocking {
                            mobileApplication.dataStoreApp.editDataStoreKey(
                                BASEURLSALIX, item.urlSalix
                            )
                        }

                        runBlocking {
                            mobileApplication.dataStoreApp.editDataStoreKey(
                                WORKFORMSELECTED, item.name
                            )
                        }
                        customDialogList.dismiss()
                        exitProcess(1)

                    }
                }

            }
        }, object : OnTrashItemRowClickListener {
            override fun onTrashItemRowClickListener(item: WorkForms) {

                customDialog.setTitle(getString(R.string.deleteWorkForm))
                    .setDescription(getString(R.string.deleteWorkFormConfirmation))
                    .setOkButton(getString(R.string.cancel)) {
                        customDialog.dismiss()
                    }.setOkButton(getString(R.string.ok)) {

                        val workFormNameKey = stringPreferencesKey(item.name)

                        runBlocking {
                            mobileApplication.dataStoreApp.deleteWorkForm(
                                workFormNameKey
                            )
                        }
                        workFormAdapter!!.notifyItemRemoved(listWorkForms.indexOf(item))
                        customDialog.dismiss()
                        customDialogList.dismiss()
                        exitProcess(1)

                    }.show()

            }
        })


        customDialogList.getRecyclerView().adapter = workFormAdapter
        customDialogList.getRecyclerView().layoutManager =
            LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)


        customDialogList.setTitle(getString(R.string.selectWorkingForm)).hideDescription()
            .hideDialog().setOkButton(getString(R.string.cancel)) {
                customDialogList.dismiss()
            }.show()

    }

    @SuppressLint("HardwareIds")
    private fun saveIdentifiers() {

        val androidId: String =
            Settings.Secure.getString(requireActivity().contentResolver, Settings.Secure.ANDROID_ID)
        mobileApplication.androidId = androidId

        runBlocking {
            mobileApplication.dataStoreApp.editDataStoreKey(ANDROID_ID, androidId)
        }

    }

    private fun showWorkingForms() {

        val listForms = runBlocking { mobileApplication.dataStoreApp.getWorkForm() }
        setAdapter(listForms)
    }

    private fun showNewForm() {
        customNewForm =
            CustomDialogInputThreeValues(requireContext()).setTitle(getString(R.string.workFormAdd))
                .setDescription(getString(R.string.workFormDescrip))
        customNewForm.setInputTextVisibility(GONE)
        customNewForm.setInfoTex(
            getString(R.string.name),
            getString(R.string.silexServer),
            getString(R.string.salixServer)
        )
        customNewForm.setFocusText()
        customNewForm.setOkButton(getString(R.string.save)) {
            runBlocking {
                mobileApplication.dataStoreApp.saveWorkForm(
                    WorkForms(
                        customNewForm.getValue(), customNewForm.getValueThree(), true
                    )
                )
            }

            binding.edittextServer.setText(customNewForm.getValue())
            runBlocking {
                mobileApplication.dataStoreApp.editDataStoreKey(
                    WORKFORMSELECTED, customNewForm.getValue()
                )
            }
            customNewForm.dismiss()
            customDialogList.dismiss()
            exitProcess(1)

        }.setKoButton(getString(R.string.cancel)) {
            customNewForm.dismiss()
        }

        customNewForm.show()

    }

    private fun checkUser() {

        if (mobileApplication.dataStoreApp.readDataStoreKey<Boolean>(REMEMBER)) {

            binding.edittextUsername.setText(
                mobileApplication.dataStoreApp.readDataStoreKey<String>(
                    USER
                )
            )
            binding.edittextPassword.setText(
                mobileApplication.dataStoreApp.readDataStoreKey<String>(
                    PASSWORD
                )
            )
            if (mobileApplication.dataStoreApp.readDataStoreKey<String>(TOKEN) != "") {
                binding.switchRemember.isChecked = true
            }
        }

    }

    private fun reviewVersion(it: WorkerData) {
        if (it.version == getInfoVersionNameApp()) {
            goToMain()
        } else {
            if (binding.edittextServer.text.toString() == "Producción") {
                mobileApplication.clearApplicationData()
            }
            customDialog.setTitle(getString(R.string.Actualizar))
                .setDescription(getString(R.string.updatemng)).setOkButton(
                    getString(
                        R.string.Actualizar
                    )
                ) {
                    try {
                        val openURL = Intent(Intent.ACTION_VIEW)
                        openURL.data = Uri.parse(it.url)
                        startActivity(openURL)
                    } catch (ex: Exception) {
                        getString(R.string.problemUpdate).toast(requireActivity())
                    }

                }
            if (it.isVersionCritical) {
                customDialog.setDescription(getString(R.string.updatecritical))
            } else {
                customDialog.setKoButton(getString(R.string.cancel)) {
                    customDialog.dismiss()
                    goToMain()
                }
            }
            customDialog.show()

        }
    }

    override fun observeViewModel() {
        with(viewModel) {

            handleUserResponse.observe(viewLifecycleOwner) {
                runBlocking {
                    mobileApplication.dataStoreApp.saveWorkerData(
                        it
                    )
                }
                reviewVersion(it)
            }

            versionAppItem.observe(viewLifecycleOwner) {

                if (it.version == getInfoVersionNameApp()) {
                    goToMain()
                } else {
                    if (binding.edittextServer.text.toString() == "Producción") {
                        mobileApplication.clearApplicationData()
                    }
                    customDialog.setTitle(getString(R.string.Actualizar))
                        .setDescription(getString(R.string.updatemng)).setOkButton(
                            getString(
                                R.string.Actualizar
                            )
                        ) {
                            try {
                                val openURL = Intent(Intent.ACTION_VIEW)
                                openURL.data = Uri.parse(it.url)
                                startActivity(openURL)
                            } catch (ex: Exception) {
                                getString(R.string.problemUpdate).toast(requireActivity())
                            }

                        }
                    if (it.isVersionCritical) {
                        customDialog.setDescription(getString(R.string.updatecritical))
                    } else {
                        customDialog.setKoButton(getString(R.string.cancel)) {
                            customDialog.dismiss()
                            goToMain()
                        }
                    }
                    customDialog.show()

                }

            }
            serialNumber.observe(viewLifecycleOwner) {
                mobileApplication.serialNumber = it
                viewModel.getCurrentUserData(
                    getString(R.string.logAppName),
                    getInfoVersionNameApp(),
                    mobileApplication.dataStoreApp.readDataStoreKey(ANDROID_ID),
                    it
                )
            }
            logindevice.observe(viewLifecycleOwner) {

                if (it.vIsAuthorized == "0") {

                    customDialog.setTitle(getString(R.string.error)).setDescription(it.vMessage!!)
                        .setOkButton(getString(R.string.close)) {
                            customDialog.dismiss()
                        }.show()

                } else {

                    runBlocking {
                        if (binding.switchRemember.isChecked) {
                            mobileApplication.dataStoreApp.editDataStoreKey(REMEMBER, true)
                        } else {
                            mobileApplication.dataStoreApp.editDataStoreKey(REMEMBER, false)
                        }
                    }
                    if (it.vIsAuthorized == "1") {

                        if (it.vMessage.isNullOrEmpty()) {
                            getVersion()
                        } else {
                            customDialog.setTitle(getString(R.string.info))
                                .setDescription(it.vMessage)
                                .setOkButton(getString(R.string.close)) {
                                    customDialog.dismiss()
                                    getVersion()
                                }.show()
                        }

                    }

                }

            }

            workerOperator.observe(viewLifecycleOwner) {
                runBlocking {
                    mobileApplication.dataStoreApp.saveDataOperator(
                        it
                    )

                }
            }


            loginSalixItem.observe(viewLifecycleOwner) {

                if (it.isError) {
                    saveTokenPref("", 0)
                    if (it.errorMessage.contains("REQUIRES_2FA")) {
                        showInputCode()
                    } else {
                        customDialog.setTitle(getString(R.string.error))

                            .setDescription(
                                when {
                                    it.errorMessage.contains("Unauthorized") -> getString(R.string.messageUserError)
                                    it.errorMessage.contains("Unable to resolve") -> getString(R.string.messageInternetError)
                                    else -> it.errorMessage
                                }
                            ).setOkButton(
                                getString(R.string.accept)
                            ) {
                                customDialog.dismiss()

                            }.show()
                    }
                } else {
                    saveTokenPref(it.token, it.ttl)
                    app.userName = binding.edittextUsername.text.toString()
                    app.userPassword = binding.edittextPassword.text.toString()

                    viewModel.getAccessTokenConfigs()
                }
            }
            loadAccessConfigSalixList.observe(viewLifecycleOwner) { event ->

                event.getContentIfNotHandled().notNull {

                    if (it.list.isNotEmpty()) {

                        runBlocking {
                            mobileApplication.dataStoreApp.editDataStoreKey(
                                RENEWPERIOD, it.list[0].renewPeriod
                            )
                            mobileApplication.dataStoreApp.editDataStoreKey(
                                RENEWINTERVAL, it.list[0].renewInterval
                            )
                        }

                        //Tarea 6868
                        handleUserCall()

                    }
                }

            }

        }
        super.observeViewModel()
    }

    private fun showInputCode() {
        customDialogInput.setTitle(getString(R.string.messageTwoFactorTitle))

            .setDescription(
                getString(R.string.messageTwoFactor)
            ).setOkButton(
                getString(R.string.validate)
            ) {
                customDialogInput.dismiss()
                viewModel.validateAuth(
                    user = binding.edittextUsername.text.toString(),
                    password = binding.edittextPassword.text.toString(),
                    code = customDialogInput.getValue()
                )

            }.show()
    }

    private fun setupFirebase(userName: String) {
        Firebase.crashlytics.setUserId(userName)
    }

    /*    private fun getInfoVersionNameApp(): String {
            val manager: PackageManager = requireContext().packageManager
            val info: PackageInfo = manager.getPackageInfo(requireContext().packageName, 0)
            mobileApplication.versionName = info.versionName
            return info.versionName
        }*/

    private fun saveTokenPref(token: String, ttl: Long) {

        runBlocking {
            mobileApplication.dataStoreApp.editDataStoreKey(TOKEN, token)
            mobileApplication.dataStoreApp.editDataStoreKey(TTL, ttl)
            mobileApplication.dataStoreApp.editDataStoreKey(TOKENCREATED, Date().time)
        }

    }

    private fun goToMain() {
        setupFirebase((requireActivity().application as MobileApplication).userName.toString())
        val intent = Intent(activity, MainActivity::class.java)
        intent.data = imageUri
        startActivity(intent)
        requireActivity().finish()
    }

    private fun getVersion() {
        viewModel.checkVersion(
            nameApp = getString(R.string.nameApp)

        )

    }
}
