package it.danieleverducci.openweddingapp.ui

import android.Manifest
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.google.zxing.integration.android.IntentIntegrator
import it.danieleverducci.openweddingapp.R
import com.google.android.material.snackbar.Snackbar
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.util.Log
import android.view.View
import android.widget.EditText
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import it.danieleverducci.openweddingapp.DeRApplication
import it.danieleverducci.openweddingapp.MainActivity
import it.danieleverducci.openweddingapp.entities.Token
import it.danieleverducci.openweddingapp.networking.TokenNet
import it.danieleverducci.openweddingapp.utils.WifiUtils
import org.json.JSONException


class LoginActivity : AppCompatActivity() {
    companion object {
        const val MY_PERMISSIONS_REQUEST = 34987
        const val TAG = "LoginActivity"
        const val CODE_PARAM_IN_URI = "qr"  // i.e. https://mysite.com/?qr=1234
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)

        if ((application as DeRApplication).token != null) {
            // User already logged in
            val i = Intent(this, MainActivity::class.java)
            startActivity(i)
            finish()
        } else if (intent.data != null) {
            // Non-logged user started the application from a link
            loginWithMagicLink(intent.data)

        }
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)

        // Non-logged user brings on top the already-running application from a link
        loginWithMagicLink(intent?.data)
    }

    private fun loginWithMagicLink(uri: Uri?) {
        if (uri == null) {
            Log.e(TAG,"Intent with no URI received!")
            return
        }

        val code = uri.getQueryParameter(CODE_PARAM_IN_URI)
        if (code != null)
            checkUserCredentials(code)
        else
            setContentView(R.layout.activity_login)
    }

    public fun onManualLoginButtonClicked(v: View) {
        val codeField = findViewById<EditText>(R.id.login_code)
        val code = codeField.text.toString()
        checkUserCredentials(code)
    }

    public fun onLoginButtonClicked(v: View) {
        // Request camera permission
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.CAMERA)
            != PackageManager.PERMISSION_GRANTED) {
            // Request permission
            ActivityCompat.requestPermissions(this,
                arrayOf(Manifest.permission.CAMERA),
                MY_PERMISSIONS_REQUEST)
        } else {
            // Permission has already been granted: Start qrcode scanner
            IntentIntegrator(this).initiateScan()
        }

    }

    private fun checkUserCredentials(code: String) {
        findViewById<View>(R.id.loading_screen).visibility = View.VISIBLE
        try {
            val tokenNet = TokenNet(this)
            tokenNet.postItem(
                object: TokenNet.OnTokenPostCompletedListener {
                    override fun OnTokenPostCompleted(item: Token?, error: TokenNet.Error?) {
                        findViewById<View>(R.id.loading_screen).visibility = View.GONE
                        if (error == null && item?.token != null) {
                            // Save user
                            (application as DeRApplication).token = item
                            // Start main activity
                            val i = Intent(applicationContext, MainActivity::class.java)
                            startActivity(i)
                            finish()
                        } else {
                            if (error == TokenNet.Error.USER_NOT_FOUND) {
                                Snackbar.make(findViewById(R.id.activity_login_root), R.string.login_net_notfound_error, Snackbar.LENGTH_LONG).show()
                            } else {
                                // No connection?

                                Snackbar.make(findViewById(R.id.activity_login_root), R.string.login_net_generic_error, Snackbar.LENGTH_LONG).show()
                                // Try to connect to wedding network
                                val app = (application as DeRApplication)
                                if (!app.askedConnectingToWeddingWifi) {
                                    WifiUtils.askToAddWeddingNetworks(this@LoginActivity, app.remoteSettings.wifiNetworks)
                                    app.askedConnectingToWeddingWifi = true
                                }
                            }
                        }
                    }
                },
                code
            )
        } catch (e: JSONException) {
            Log.d(TAG, "Unable to parse json from server: ${e.toString()}")
            Snackbar.make(findViewById(R.id.activity_login_root), R.string.login_server_error, Snackbar.LENGTH_LONG).show()
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        // QR Code scanned
        val result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data)
        if (result != null) {
            if (result.contents != null) {
                Log.d(TAG, "Qrcode is " + resultCode);
                try {
                    // Obtain code from URL (http://some/url?qr=125863)
                    val url = result.contents
                    val uri = Uri.parse(url)
                    val code = uri.getQueryParameter("qr")
                        ?: throw IllegalArgumentException("No code found")
                    checkUserCredentials(code);
                } catch (e: java.lang.IllegalArgumentException) {
                    Snackbar.make(findViewById(R.id.activity_login_root), R.string.login_qr_unrecognized_error, Snackbar.LENGTH_LONG).show()
                }
            }
        } else {
            super.onActivityResult(requestCode, resultCode, data)
        }
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
        when (requestCode) {
            MY_PERMISSIONS_REQUEST -> {
                // If request is cancelled, the result arrays are empty.
                if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                    // permission was granted
                    IntentIntegrator(this).initiateScan()
                }
                return
            }
        }
    }



}