package com.nxp.vizncompanionapp.activities

import android.Manifest
import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.bluetooth.BluetoothDevice
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.location.LocationManager
import android.net.Uri
import android.os.Build
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.provider.Settings
import android.support.v4.app.ActivityCompat
import android.support.v7.widget.LinearLayoutManager
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Toast
import com.nxp.vizncompanionapp.R
import com.nxp.vizncompanionapp.adapters.BleListAdapter
import com.nxp.vizncompanionapp.utility.AppConstant
import com.nxp.vizncompanionapp.utility.DisplayNotifications
import com.nxp.vizncompanionapp.utility.PreferencesHelper
import com.nxp.vizncompanionapp.viewModel.BLEViewModel
import kotlinx.android.synthetic.main.activity_device_listing.*
import kotlinx.android.synthetic.main.content_ble_listing.*

class BleListingActivity : AppCompatActivity() {

    var prefeernce: PreferencesHelper? = null
    private var mDisplayNotifications: DisplayNotifications = DisplayNotifications()
    private val REQUEST_LOCATION = 1
    /**
     * Permissions needed for location service
     */
    private val PERMISSIONS_LOCATION = arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION)

    var adapter : BleListAdapter? = null
    private var mBLEViewModel: BLEViewModel? = null
    var isCreate: Boolean = false
    var isGoToSeetings : Boolean = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_ble_listing)
        setSupportActionBar(toolbar)
        supportActionBar?.setDisplayHomeAsUpEnabled(true)

        this.prefeernce = PreferencesHelper(this)

        adapter = BleListAdapter(this)
        rvBleList.adapter = adapter
        rvBleList.layoutManager = LinearLayoutManager(this)
        isCreate = true

        mBLEViewModel = ViewModelProviders.of(this).get(BLEViewModel::class.java)

        mBLEViewModel?.getAllBleDevices()?.observe(this, Observer { listScanResults ->
            // Update the cached copy of the words in the adapter.
            adapter?.setDevices(listScanResults)
        })

        onClickListener()
    }

    private fun onClickListener() {
        adapter?.setOnItemClickListener(object : BleListAdapter.MyClickListener{
            override fun onItemClick(position: Int, v: View, mDeviceList: List<BluetoothDevice>?) {
                goToWifiListingScreen(mDeviceList?.get(position))
                isCreate = true
            }

        })
    }

    fun goToWifiListingScreen(bluetoothDevice: BluetoothDevice?) {
        intent = Intent(this, WifiListingActivity::class.java)
        intent.putExtra("action", "ble_mode")
        intent.putExtra("device",bluetoothDevice)
        startActivity(intent)
        overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left)
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_ble_listing, menu)//Menu Resource, Menu
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            R.id.action_rescan -> {
                isCreate = true
                startScanProcess()
                true
            }
            android.R.id.home -> {
                onBackPressed()
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }

    override fun onStart() {
        super.onStart()
        startScanProcess()
    }

    fun startScanProcess() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mBLEViewModel?.initCallbackLollipop()
        } else {
            mBLEViewModel?.initScanCallbackSupport()
        }
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            if (prefeernce?.loadSavedStringPreferences(AppConstant.SHARED_KEY_NEVER_ASK_AGAIN_LOCATION_PERMISSION) == "") {
                setupLocationPermission()
            } else {
                mDisplayNotifications?.displayErrorDialog(this, getString(R.string.permissions_not_granted),getString(R.string.settings),getString(R.string.cancel))
            }
        } else {
            statusCheck()
        }
    }

    /**
     * Check the device version for permission
     */
    private fun setupLocationPermission() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // Location permissions have not been granted.
            requestLocationPermissions()
        } else {
            statusCheck()
        }
    }

    /**
     * Requests the Location permissions.
     * If the permission has been denied previously, a SnackBar will prompt the user to grant the
     * permission, otherwise it is requested directly.
     */
    fun requestLocationPermissions() {
        // BEGIN_INCLUDE(location_permission_request)
        ActivityCompat.requestPermissions(this, PERMISSIONS_LOCATION, REQUEST_LOCATION)
        // END_INCLUDE(location_permission_request)
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        if (requestCode == REQUEST_LOCATION) {
            // We have requested multiple permissions for location, so all of them need to be
            val hasSth = grantResults.isNotEmpty()
            if (hasSth) {
                // checked.
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    prefeernce?.savePreferences(AppConstant.SHARED_KEY_NEVER_ASK_AGAIN_LOCATION_PERMISSION,"")
                    statusCheck()
                } else if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
                    if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                                    Manifest.permission.ACCESS_FINE_LOCATION) || ActivityCompat.shouldShowRequestPermissionRationale(this,
                                    Manifest.permission.ACCESS_COARSE_LOCATION)) {
                        mDisplayNotifications?.displayErrorDialog(this,getString(R.string.permission_location_access),getString(R.string.ok),getString(R.string.cancel))
                    } else {
                        prefeernce?.savePreferences(AppConstant.SHARED_KEY_NEVER_ASK_AGAIN_LOCATION_PERMISSION,"check")
                        mDisplayNotifications?.displayErrorDialog(this,getString(R.string.permissions_not_granted),getString(R.string.settings),getString(R.string.cancel))
                    }
                }
            }
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        }
    }

    /**
     * Check the GPS status. Ask to turn on if brightness_level_off.
     */
    private fun statusCheck() {
        val manager = getSystemService(Context.LOCATION_SERVICE) as LocationManager

        if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            mDisplayNotifications?.displayErrorDialog(this,getString(R.string.permission_gps_access),getString(R.string.ok),getString(R.string.cancel))
        } else {
            if(isCreate) {
                if (!mBLEViewModel?.checkForBLE(this)!!) {
                    Toast.makeText(this, getString(R.string.bluetooth_not_support_msg), Toast.LENGTH_SHORT).show()
                } else {
                    mBLEViewModel?.checkBLEState(this)
                }
            } else {
                Log.e("TAG","null")
            }
        }
    }

    fun turnOnBLERequest(){
        mBLEViewModel?.turnOnBLE()
        mDisplayNotifications?.fetchData(this)
        Handler(Looper.getMainLooper()).postDelayed({
            mDisplayNotifications?.dismissDialog()
            mBLEViewModel?.scanBLEDevices(this)
        }, 1000)
    }

    fun turnOnGpsRequest(){
        startActivityForResult(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS), 111)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        when (requestCode) {
            111 -> isGPSEnabled()
            else -> super.onActivityResult(requestCode, resultCode, data)
        }
    }

    private fun isGPSEnabled() {
        isCreate = true
    }

    fun goToSettings() {
        isGoToSeetings = true
        val myAppSettings = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + this.packageName))
        myAppSettings.addCategory(Intent.CATEGORY_DEFAULT)
        myAppSettings.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        startActivity(myAppSettings)
    }

    override fun onBackPressed() {
        super.onBackPressed()
        mDisplayNotifications?.dismissDialog()
        mBLEViewModel?.scanLeDevice(false)
        finish()
        overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right)
    }

    override fun onDestroy() {
        super.onDestroy()
        mDisplayNotifications?.dismissDialog()
        mBLEViewModel?.scanLeDevice(false)
    }

    override fun onStop() {
        super.onStop()
        if(!isGoToSeetings) {
            isCreate = false
        } else {
            isGoToSeetings = false
        }
        mDisplayNotifications?.dismissDialog()
        mBLEViewModel?.scanLeDevice(false)
    }
}
