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.fastcashier.lib_common.function.account.AccountService
import com.fastcashier.lib_common.util.clickWithTrigger
import com.miya.fastcashier.databinding.ActivityLoginBinding
import com.miya.fastcashier.util.CenterToasty
import com.miya.fastcashier.util.manage.ChannelManageKit
import com.miya.fastcashier.util.manage.LocalKeyDataMKManageKit
import com.miya.fastcashier.viewmodel.LoginViewModel
import com.permissionx.guolindev.PermissionX


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)

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

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

            binding.vLoading.visibility = View.GONE

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

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

                    val userName = binding.etUsername.text.toString()
                    val passWord = binding.etPassword.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

            binding.btnLogin.isEnabled = loginState.isDataValid

            if (loginState.usernameError != null) {
                binding.etUsername.error = getString(loginState.usernameError)
            }
            if (loginState.passwordError != null && !TextUtils.isEmpty(binding.etPassword.text)) {
                binding.etPassword.error = getString(loginState.passwordError)
            }
        })

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

        binding.etPassword.apply {
            afterTextChanged {
                loginViewModel.loginDataChanged(
                    binding.etUsername.text.toString(),
                    binding.etPassword.text.toString()
                )
            }

            setOnEditorActionListener { _, actionId, _ ->
                when (actionId) {
                    EditorInfo.IME_ACTION_DONE -> {
                        if (!TextUtils.isEmpty(binding.etUsername.text.toString())) {
                            checkPermissions()
                        }
                    }
                }
                false
            }

            binding.btnLogin.clickWithTrigger {
                checkPermissions()
            }
        }

        LocalKeyDataMKManageKit.getLoginUserName()?.let {
            binding.etUsername.setText(it)
        }
        LocalKeyDataMKManageKit.getLoginUserPassword()?.let {
            binding.etPassword.setText(it)
        }

        if (!TextUtils.isEmpty(binding.etUsername.text) && !TextUtils.isEmpty(binding.etPassword.text)) {
            checkPermissions()
        }
    }

    private fun checkPermissions() {
        PermissionX.init(this)
            .permissions(
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE
            )
            .request { allGranted: Boolean, grantedList: List<String?>?, deniedList: List<String?>? ->
                if (allGranted) {
                    login()
                } else {
                    ToastUtils.showShort("请检查权限后重试")
                }
            }
    }

    private fun login() {
        binding.vLoading.visibility = View.VISIBLE
        val userName = binding.etUsername.text.toString()
        loginViewModel.login(
            userName,
            binding.etPassword.text.toString()
        )

        //暂不加账号过滤
//        if (ChannelManageKit.containsAccount(this, userName)) {
//            loginViewModel.login(
//                userName,
//                binding.etPassword.text.toString()
//            )
//        } else {
//            binding.vLoading.visibility = View.GONE
//            CenterToasty.error(this, "账号有误，请检查后重试").show()
//        }
    }

    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) {}
        })
    }
}


