package com.miya.fastcashier.ui

import android.Manifest
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.blankj.utilcode.util.ToastUtils
import com.miya.fastcashier.databinding.ActivityLoginBinding
import com.miya.fastcashier.service.AccountService
import com.miya.fastcashier.utils.clickWithTrigger
import com.miya.fastcashier.utils.manage.LocalKeyDataMKManageKit
import com.miya.fastcashier.viewmodel.LoginViewModel
import com.permissionx.guolindev.PermissionX
import com.permissionx.guolindev.callback.RequestCallback


class LoginActivity : AppCompatActivity() {

    private lateinit var loginViewModel: LoginViewModel
    private lateinit var binding: ActivityLoginBinding

    companion object {
        fun start(context: Context, flags: Int) {
            val intent = Intent(context, LoginActivity::class.java)
            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or flags
            context.startActivity(intent)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityLoginBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val username = binding.username
        val password = binding.password
        val loading = binding.loading
        val login = binding.login
        val tvErrInfo = binding.tvErrInfo

        loginViewModel = ViewModelProvider(this)
            .get(LoginViewModel::class.java)

        loginViewModel.loginLiveData.observe(this) { result ->

            loading.visibility = View.GONE

            result.getOrElse {
                tvErrInfo.text = it.message
                tvErrInfo.visibility = View.VISIBLE
                return@observe
            }

            result.getOrNull().also {
                it?.let { it1 ->

                    val userName = username.text.toString()
                    val passWord = password.text.toString()

                    LocalKeyDataMKManageKit.putLoginIngfo(userName, passWord)
                    AccountService.init(it1, userName)
                    //根据本地存储时间，MMKV初始化合理的结算时间
                    LocalKeyDataMKManageKit.handleCompliantBalanceDate()

                    MainActivity.start(this@LoginActivity)
                    finish()
                }
            }
        }

        loginViewModel.loginFormState.observe(this@LoginActivity, Observer {
            val loginState = it ?: return@Observer

            login.isEnabled = loginState.isDataValid

            if (loginState.usernameError != null) {
                username.error = getString(loginState.usernameError)
            }
            if (loginState.passwordError != null && !TextUtils.isEmpty(password.text)) {
                password.error = getString(loginState.passwordError)
            }
        })

        username.apply {
            afterTextChanged {
                loginViewModel.loginDataChanged(
                    username.text.toString(),
                    password.text.toString()
                )
            }
            setOnEditorActionListener { _, actionId, _ ->
                when (actionId) {
                    EditorInfo.IME_ACTION_NEXT -> {
                        password.requestFocus()
                        password.text?.let { password.setSelection(it.length) };
                    }
                }
                false
            }
        }

        password.apply {
            afterTextChanged {
                loginViewModel.loginDataChanged(
                    username.text.toString(),
                    password.text.toString()
                )
            }

            setOnEditorActionListener { _, actionId, _ ->
                when (actionId) {
                    EditorInfo.IME_ACTION_DONE -> {
                        loading.visibility = View.VISIBLE;
                        loginViewModel.login(
                            username.text.toString(),
                            password.text.toString()
                        )
                    }
                }
                false
            }

            binding.login.clickWithTrigger {
                checkPermissions()
            }
        }

        LocalKeyDataMKManageKit.getLoginUserName()?.let {
            username.setText(it)
        }
        LocalKeyDataMKManageKit.getLoginUserPassword()?.let {
            password.setText(it)
        }

        if (!TextUtils.isEmpty(username.text) && !TextUtils.isEmpty(password.text)) {
            loading.visibility = View.VISIBLE;
            loginViewModel.login(
                username.text.toString(),
                password.text.toString()
            )
        }

    }

    private fun checkPermissions() {
        PermissionX.init(this)
            .permissions(
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE
            )
            .request(RequestCallback { allGranted: Boolean, grantedList: List<String?>?, deniedList: List<String?>? ->
                if (allGranted) {
                    binding.loading.visibility = View.VISIBLE
                    loginViewModel.login(
                        binding.username.text.toString(),
                        binding.password.text.toString()
                    )
                } else {
                    ToastUtils.showShort("请检查权限后重试")
                }
            })
    }

    /**
     * Extension function to simplify setting an afterTextChanged action to EditText components.
     */
    private fun EditText.afterTextChanged(afterTextChanged: (String) -> Unit) {
        this.addTextChangedListener(object : TextWatcher {
            override fun afterTextChanged(editable: Editable?) {
                afterTextChanged.invoke(editable.toString())
            }

            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}

            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
        })
    }
}


