package com.test.questionnairesdk.library

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity.RESULT_OK
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.media.projection.MediaProjectionManager
import android.net.http.SslError
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.webkit.*
import androidx.core.content.ContextCompat
import androidx.fragment.app.DialogFragment
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.fasterxml.jackson.databind.ObjectMapper
import com.hbisoft.hbrecorder.HBRecorder
import com.hbisoft.hbrecorder.HBRecorderListener
import com.test.questionnairesdk.R
import kotlinx.android.synthetic.main.fragment_questionnaire_webview.*

class QuestionnaireWebviewFragment : DialogFragment(), HBRecorderListener {

    var webkitPermissionRequest: PermissionRequest? = null

    val REQUEST_CODE_PERMISSION = 1001
    var webviewAndroidPermissionMap = HashMap<String, String>()
    lateinit var hbRecorder: HBRecorder
    val SCREEN_RECORD_REQUEST_CODE = 10000

    private val messageReceiver = object : BroadcastReceiver() {

        override fun onReceive(context: Context, intent: Intent) {
            // Get extra data included in the Intent
            val message = intent.getStringExtra("record") ?: null
            message?.let {
                if (it == "STOPPED") {
                    hbRecorder.stopScreenRecording()
                }
            }
        }
    }

    fun hideProgressBar() {
//        user_detail_container.visibility = View.VISIBLE
        questionnaire_home_webview.visibility = View.VISIBLE
        progress_layout.visibility = View.GONE
    }

    fun showProgressBar() {
//        user_detail_container.visibility = View.GONE
        questionnaire_home_webview.visibility = View.GONE
        progress_layout.visibility = View.VISIBLE
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setStyle(STYLE_NO_FRAME, R.style.AppTheme)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        super.onCreateView(inflater, container, savedInstanceState)
        var view = inflater.inflate(R.layout.fragment_questionnaire_webview, container, false)

        return view
    }

    fun startRecordingScreen() {
        val mediaProjectionManager =
            activity?.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as? MediaProjectionManager
        val permissionIntent = mediaProjectionManager?.createScreenCaptureIntent()
        startActivityForResult(permissionIntent, SCREEN_RECORD_REQUEST_CODE)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == SCREEN_RECORD_REQUEST_CODE) {
            if (resultCode == RESULT_OK) { //Start screen recording
                hbRecorder.startScreenRecording(data, resultCode, activity)
            }
        }
    }

    override fun onStart() {
        super.onStart()
        q_start_recording.setOnClickListener {
            startRecordingScreen()
            val intent = Intent(activity, HUD::class.java)
            ContextCompat.startForegroundService(activity!!, intent)
        }

        q_stop_recording.setOnClickListener {
            hbRecorder.stopScreenRecording()
        }


        hbRecorder = HBRecorder(activity, this)
        hbRecorder.isAudioEnabled(false)

        activity?.let {
            LocalBroadcastManager.getInstance(it).registerReceiver(messageReceiver,
                object : IntentFilter("fashtag-screen-record-stopped") {

                })
        }
        questionnaire_home_webview.loadUrl("${RetrofitNetworking.ASKRIBE_CONSUMER_BASE_URL}/mobile-consumer")
    }

    private fun askForWebkitPermission(webviewAndroidPermissionMap: Map<String, String>) {
        activity?.let {
            val grantedPermissions = webviewAndroidPermissionMap?.entries.filter { entry ->
                ContextCompat.checkSelfPermission(
                    it,
                    entry.value
                ) == PackageManager.PERMISSION_GRANTED
            }?.map {
                it.key
            }.toTypedArray()
            val nonGrantedPermissions = webviewAndroidPermissionMap?.entries.filter { entry ->
                ContextCompat.checkSelfPermission(
                    it,
                    entry.value
                ) != PackageManager.PERMISSION_GRANTED
            }?.map {
                it.value
            }.toTypedArray()
            if (grantedPermissions.isNotEmpty()) {
                webkitPermissionRequest?.grant(grantedPermissions)
            }
            if (nonGrantedPermissions.isNotEmpty()) {
                requestPermissions(nonGrantedPermissions, REQUEST_CODE_PERMISSION)
            }
//            if (ContextCompat.checkSelfPermission(it, androidPermission) == PackageManager.PERMISSION_GRANTED) {
//                webkitPermissionRequest?.grant(webkitPermissions)
//            } else {
//                requestPermissions(androidPermissions, REQUEST_CODE_PERMISSION)
//            }
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
//        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        val webViewPermissions = webviewAndroidPermissionMap.entries.filter {
            permissions.contains(it.value)
        }.map {
            it.key
        }
        webkitPermissionRequest?.grant(webViewPermissions.toTypedArray())
    }

    @SuppressLint("SetJavaScriptEnabled")
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        questionnaire_home_webview?.settings?.apply {
            setAppCacheEnabled(true)
            javaScriptEnabled = true
            domStorageEnabled = true
            setAppCacheEnabled(true)
            loadsImagesAutomatically = true
            mixedContentMode = WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE
        }
        questionnaire_home_webview.webViewClient = object : WebViewClient() {
            override fun onReceivedSslError(
                view: WebView?,
                handler: SslErrorHandler?,
                error: SslError?
            ) {
//                super.onReceivedSslError(view, handler, error)
                handler?.proceed()
            }
        }
        questionnaire_home_webview.webChromeClient = object : WebChromeClient() {
            override fun onPermissionRequest(request: PermissionRequest?) {
//                super.onPermissionRequest(request)
                webkitPermissionRequest = request
                val webviewPermissionRequests = request?.resources?.filter {
                    it == PermissionRequest.RESOURCE_AUDIO_CAPTURE || it == PermissionRequest.RESOURCE_VIDEO_CAPTURE
                }?.toTypedArray() ?: arrayOf()
                val androidPermissionRequests = webviewPermissionRequests.map {
                    if (it == PermissionRequest.RESOURCE_AUDIO_CAPTURE) {
                        Manifest.permission.RECORD_AUDIO
                    } else {
                        Manifest.permission.CAMERA
                    }
                }.toTypedArray()
                webviewAndroidPermissionMap = hashMapOf()
                webviewPermissionRequests.forEachIndexed { index, value ->
                    webviewAndroidPermissionMap[value] = androidPermissionRequests[index]
                }
                askForWebkitPermission(webviewAndroidPermissionMap)
            }
        }
        questionnaire_home_webview.addJavascriptInterface(JavaScriptInterface(), "NativeBridge")
    }

    inner class JavaScriptInterface {

        @JavascriptInterface
        fun getReqObjForFirstQuestion(callback: String) {
            activity?.runOnUiThread {
                questionnaire_home_webview.evaluateJavascript(
                    "window.$callback(${ObjectMapper().writeValueAsString(
                        AskribeSDK.requestObject
                            ?: ""
                    )
                    })", null
                )
            }
        }

        @JavascriptInterface
        fun startRecording(callback: String) {
//            activity?.runOnUiThread {
//                startRecordingScreen()
//                val intent = Intent(activity, HUD::class.java)
//                ContextCompat.startForegroundService(activity!!, intent)
//            }
        }

        @JavascriptInterface
        fun questionnaireConsumerFinished() {
            activity?.runOnUiThread {
               AskribeSDK.onExitCallback?.invoke()
            }
        }


    }

    override fun HBRecorderOnError(errorCode: Int, reason: String?) {
        Log.e("HB", reason)
    }

    override fun HBRecorderOnStart() {
    }

    fun fileUploaded(fileUrl: String) {
        activity?.runOnUiThread {
            questionnaire_home_webview.evaluateJavascript(
                "window.screenRecordingFinished('${fileUrl}')",
                null
            )
        }
    }

    override fun HBRecorderOnComplete() {
        Log.e("HB", "stopped")
        uploadFile(hbRecorder.filePath)
    }


    @SuppressLint("CheckResult")
    fun uploadFile(fileName: String) {
//        utilityDataManager.uploadAudioFile("questionnaire-media", createMultipartBody(fileName))
//            .subscribeOn(Schedulers.io())
//            .observeOn(AndroidSchedulers.mainThread())
//            .map(ValidateHttpStatusCode<FileUploadResponse, FileUploadResponse>())
//            .subscribe({ fileUploadResponse ->
//                fileUploaded(fileUploadResponse?.url ?: "data")
//                Log.e("uploaded", fileUploadResponse?.url ?: "data")
//            }, {
//                APIErrorManager.handleError(it)
//            })
    }

}
