/*
 * Copyright (c) 2010-2020 Belledonne Communications SARL.
 *
 * This file is part of linphone-android
 * (see https://www.linphone.org).
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.linphone.activities.main.dialer.fragments

import android.app.Dialog
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.json.JSONObject
import org.linphone.BuildConfig
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R
import org.linphone.activities.main.MainActivity
import org.linphone.activities.main.dialer.viewmodels.DialerViewModel
import org.linphone.activities.main.fragments.SecureFragment
import org.linphone.activities.main.viewmodels.DialogViewModel
import org.linphone.activities.main.viewmodels.SharedMainViewModel
import org.linphone.activities.navigateToConfigFileViewer
import org.linphone.activities.navigateToContacts
import org.linphone.core.tools.Log
import org.linphone.databinding.DialerFragmentBinding
import org.linphone.rest.AsyncHttpResponse
import org.linphone.rest.RestApis
import org.linphone.utils.*

class DialerFragment : SecureFragment<DialerFragmentBinding>(),
    AsyncHttpResponse.AsyncHttpResponseListener,
    View.OnClickListener {
    private lateinit var viewModel: DialerViewModel
    private lateinit var sharedViewModel: SharedMainViewModel
    var record_status: String = "1"
    lateinit var sessionManager: SessionManager
    private var uploadLogsInitiatedByUs = false
    override fun getLayoutId(): Int = R.layout.dialer_fragment

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding.lifecycleOwner = this
        sessionManager = SessionManager(activity)

        viewModel = ViewModelProvider(this).get(DialerViewModel::class.java)
        binding.viewModel = viewModel

        binding.accountsCallIv.setOnClickListener(this)
        binding.callIv.setOnClickListener(this)
        binding.voiceMailIv.setOnClickListener(this)
        binding.recordIv.setOnClickListener(this)
        binding.unRecordIv.setOnClickListener(this)

        sharedViewModel = requireActivity().run {
            ViewModelProvider(this).get(SharedMainViewModel::class.java)
        }

        binding.setNewContactClickListener {
            navigateToContacts(viewModel.enteredUri.value)
        }
        getCallerIdRejectionsApicall(
            RestApis.get_voip_params,
            AppStrings.CallRecording.callrecording_disabled
        )

        // record calling
        /* binding.recordIv?.setOnClickListener {
             android.util.Log.e("tag", "recordIv: " )
             record_status = AppStrings.Constants.off
             binding.unRecordIv?.setVisibility(View.VISIBLE)
             binding.recordIv!!.setVisibility(View.GONE)
             getCallerIdRejectionsApicall(RestApis.set_voip_params, record_status)
         }*/

        binding.setTransferCallClickListener {
            viewModel.transferCall()
            // Transfer has been consumed
            sharedViewModel.pendingCallTransfer = false
            viewModel.transferVisibility.value = false
        }

        if (arguments?.containsKey("Transfer") == true) {
            sharedViewModel.pendingCallTransfer = arguments?.getBoolean("Transfer") ?: false
            Log.i("[Dialer] Is pending call transfer: ${sharedViewModel.pendingCallTransfer}")
        }

        if (arguments?.containsKey("URI") == true) {
            val address = arguments?.getString("URI") ?: ""
            Log.i("[Dialer] Found URI to call: $address")
            val skipAutoCall = arguments?.getBoolean("SkipAutoCallStart") ?: false

            if (corePreferences.callRightAway && !skipAutoCall) {
                Log.i("[Dialer] Call right away setting is enabled, start the call to $address")
                viewModel.directCall(address)
            } else {
                sharedViewModel.dialerUri = address
            }
        }
        arguments?.clear()

        viewModel.enteredUri.observe(viewLifecycleOwner, {
            if (it == corePreferences.debugPopupCode) {
                displayDebugPopup()
                viewModel.enteredUri.value = ""
            }
        })

        viewModel.uploadFinishedEvent.observe(viewLifecycleOwner, {
            it.consume { url ->
                // To prevent being trigger when using the Send Logs button in About page
                if (uploadLogsInitiatedByUs) {
                    val clipboard =
                        requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
                    val clip = ClipData.newPlainText("Logs url", url)
                    clipboard.setPrimaryClip(clip)

                    val activity = requireActivity() as MainActivity
                    activity.showSnackBar(R.string.logs_url_copied_to_clipboard)

                    AppUtils.shareUploadedLogsUrl(activity, url)
                }
            }
        })

        viewModel.updateAvailableEvent.observe(viewLifecycleOwner, {
            it.consume { url ->
                // displayNewVersionAvailableDialog(url)
            }
        })

        Log.i("[Dialer] Pending call transfer mode = ${sharedViewModel.pendingCallTransfer}")
        viewModel.transferVisibility.value = sharedViewModel.pendingCallTransfer

        checkForUpdate()
    }

    private fun getCallerIdRejectionsApicall(action: String?, record_status: String) {
        Log.e("TAG", "getCallerIdRejectionsApicall: ")
        Log.e("TAG", "getCallerIdRejectionsApicall: " + record_status)
        Log.e("TAG", "getCallerIdRejectionsApicall: " + action)

        if (AppMethods.isConnectingToInternet(activity)) {
            val response = AsyncHttpResponse(this, false)
            var jo: JSONObject? = null
            try {
                jo = JSONObject()
                jo.put(AppStrings.InputParams.action, action)
                jo.put(
                    AppStrings.InputParams.login,
                    sessionManager.getStoreData(AppStrings.Session.login)
                )
                jo.put(
                    AppStrings.InputParams.password,
                    sessionManager.getStoreData(AppStrings.Session.password)
                )
                val job = JSONObject()
                job.put(AppStrings.CallRecording.callrecording_disabled, record_status)
                jo.put(AppStrings.InputParams.params, job)
                // android.util.Log.e(DialerFragment.TAG, "getPbxSettingApi: params : $jo")
            } catch (e: Exception) {
                e.printStackTrace()
            }
            response.postJsonAsyncHttp(RestApis.url, action, jo)
        } else {
            AppMethods.alertForNoInternet(activity)
        }
    }

    override fun onPause() {
        sharedViewModel.dialerUri = viewModel.enteredUri.value ?: ""
        super.onPause()
    }

    override fun onResume() {
        super.onResume()
/*

        if (resources.getBoolean(R.bool.isTablet)) {
            coreContext.core.nativePreviewWindowId = binding.videoPreviewWindow
        }
*/

        viewModel.updateShowVideoPreview()
        viewModel.autoInitiateVideoCalls.value =
            coreContext.core.videoActivationPolicy.automaticallyInitiate
        uploadLogsInitiatedByUs = false

        viewModel.enteredUri.value = sharedViewModel.dialerUri
    }

    private fun displayDebugPopup() {
        val alertDialog = MaterialAlertDialogBuilder(requireContext())
        alertDialog.setTitle(getString(R.string.debug_popup_title))

        val items = if (corePreferences.debugLogs) {
            resources.getStringArray(R.array.popup_send_log)
        } else {
            resources.getStringArray(R.array.popup_enable_log)
        }

        alertDialog.setItems(items) { _, which ->
            when (items[which]) {
                getString(R.string.debug_popup_disable_logs) -> {
                    corePreferences.debugLogs = false
                }
                getString(R.string.debug_popup_enable_logs) -> {
                    corePreferences.debugLogs = true
                }
                getString(R.string.debug_popup_send_logs) -> {
                    uploadLogsInitiatedByUs = true
                    viewModel.uploadLogs()
                }
                getString(R.string.debug_popup_show_config_file) -> {
                    navigateToConfigFileViewer()
                }
            }
        }

        alertDialog.show()
    }

    private fun checkForUpdate() {
        val url: String? = corePreferences.checkIfUpdateAvailableUrl
        if (url != null && url.isNotEmpty()) {
            val lastTimestamp: Int = corePreferences.lastUpdateAvailableCheckTimestamp
            val currentTimeStamp = System.currentTimeMillis().toInt()
            val interval: Int = corePreferences.checkUpdateAvailableInterval
            if (lastTimestamp == 0 || currentTimeStamp - lastTimestamp >= interval) {
                val currentVersion = BuildConfig.VERSION_NAME
                Log.i("[Dialer] Checking for update using url [$url] and current version [$currentVersion]")
                coreContext.core.checkForUpdate(currentVersion)
                corePreferences.lastUpdateAvailableCheckTimestamp = currentTimeStamp
            }
        }
    }

    private fun displayNewVersionAvailableDialog(url: String) {
        val viewModel = DialogViewModel(getString(R.string.dialog_update_available))
        val dialog: Dialog = DialogUtils.getDialog(requireContext(), viewModel)

        viewModel.showCancelButton {
            dialog.dismiss()
        }

        viewModel.showOkButton({
            val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
            startActivity(browserIntent)
            dialog.dismiss()
        }, getString(R.string.dialog_ok))

        dialog.show()
    }

    override fun onAsyncHttpResponseGet(response: String, URL: String) {
        // TODO("Not yet implemente
        //  d")
        android.util.Log.e("TAG", "onAsyncHttpResponseGet: response is  : " + response)
        recordingResponse(response, URL)

        /*if (URL.equals(RestApis.action_update)) {


            android.util.Log.e("TAG", "onAsyncHttpResponseGet: response loc is : "+ response);
            uodateLocationResponse(response);
        }else{
            recordingResponse(response, URL);
        }*/
        Log.e("TAG", "onAsyncHttpResponseGet: " + response)
    }

    fun recordingResponse(response: String, url: String) {
        android.util.Log.e("TAG", "recordingResponse: $response")
        try {
            val jo = JSONObject(response)
            val Status = jo.optString(AppStrings.OutputParams.Status)
            val Message = jo.optString(AppStrings.OutputParams.Message)
            if (Status == AppStrings.OutputParams.Success) {
                if (url == RestApis.get_voip_params) {
                    val params = jo.getJSONObject(AppStrings.OutputParams.params)
                    record_status =
                        params.optString(AppStrings.CallRecording.callrecording_disabled)
                    if (record_status == AppStrings.Constants.on) {
                        binding.recordIv.visibility = View.VISIBLE
                        binding.unRecordIv.visibility = View.GONE
                    } else if (record_status == AppStrings.Constants.off) {
                        binding.recordIv.visibility = View.GONE
                        binding.unRecordIv.visibility = View.VISIBLE
                    }
                } else if (url == RestApis.set_voip_params) {
                    AppMethods.showToast(activity, Message)
                    AppMethods.hideSoftKeyboard(activity)
                    //                    getActivity().finish();
                }
            } else {
//                AppMethods.alertWithOk(this, Message);
                AppMethods.showToast(activity, Message)
            }
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
    }

    override fun onClick(v: View?) {
        when (v?.id) {
            R.id.voice_mail_iv -> {
//                LinphoneManager.getInstance().newOutgoingCall(AppStrings.Constants.voice_mail_number,"Voicemail "+AppStrings.Constants.voice_mail_number);
                /*   LinphoneManager.getInstance()
                    .newOutgoingCall(AppStrings.Constants.voice_mail_number, "Voicemail ")*/
            }
            R.id.accounts_call_iv -> {
                /*  android.util.Log.e(DialerFragment.TAG, "accounts_call_iv  ")
                  LinphoneManager.getInstance().newOutgoingCall(
                      AppStrings.Constants.accounts_number,
                      "Accounts " + AppStrings.Constants.accounts_number
                  )*/
            }
            R.id.call_iv -> {
                /*  android.util.Log.e(
                      DialerFragment.TAG,
                      "onClick:call_iv  " + mAddress.getText().toString()
                  )
                  mCall.performClick()*/
            }
            R.id.un_record_iv -> {
                binding.recordIv?.visibility = View.VISIBLE
                binding.unRecordIv?.visibility = View.GONE
                record_status = AppStrings.Constants.on
                getCallerIdRejectionsApicall(RestApis.set_voip_params, record_status)
            }
            R.id.record_iv -> {
                record_status = AppStrings.Constants.off
                binding.unRecordIv?.visibility = View.VISIBLE
                binding.recordIv?.visibility = View.GONE
                getCallerIdRejectionsApicall(RestApis.set_voip_params, record_status)
            }
        }
    }
}
