package com.secspace.sms.activities

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.role.RoleManager
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.ShortcutManager
import android.graphics.Color
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Telephony
import android.text.TextUtils
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.app.NotificationCompat
import androidx.lifecycle.lifecycleScope
import com.secspace.sms.R
import com.secspace.sms.adapters.ConversationsAdapter
import com.secspace.sms.adapters.SearchResultsAdapter
import com.secspace.sms.databinding.ActivityMainBinding
import com.secspace.sms.extensions.*
import com.secspace.sms.helpers.RecentsHelper
import com.secspace.sms.helpers.SEARCHED_MESSAGE_ID
import com.secspace.sms.helpers.THREAD_ID
import com.secspace.sms.helpers.THREAD_TITLE
import com.secspace.sms.models.*
import com.secspace.sms.util.PhoneUtils
import com.simplemobiletools.commons.dialogs.PermissionRequiredDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.util.GsonUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode


class MainActivity : SimpleActivity() {
    private val TAG = "MainActivity"
    private val MAKE_DEFAULT_APP_REQUEST = 1

    private var storedTextColor = 0
    private var storedFontSize = 0
    private var lastSearchedText = ""
    private var bus: EventBus? = null
    private var wasProtectionHandled = false

    private val binding by viewBinding(ActivityMainBinding::inflate)

    @SuppressLint("InlinedApi")
    override fun onCreate(savedInstanceState: Bundle?) {
        isMaterialActivity = true
        super.onCreate(savedInstanceState)
        setContentView(binding.root)
        setupOptionsMenu()
        refreshMenuItems()

        updateMaterialActivityViews(
            mainCoordinatorLayout = binding.mainCoordinator,
            nestedView = binding.conversationsList,
            useTransparentNavigation = true,
            useTopSearchMenu = true
        )

        if (savedInstanceState == null) {
            checkAndDeleteOldRecycleBinMessages()
            handleAppPasswordProtection {
                wasProtectionHandled = it
                if (it) {
                    clearAllMessagesIfNeeded {
                        loadMessages()
                    }
                } else {
                    finish()
                }
            }
        }

        if (checkAppSideloading()) {
            return
        }

//        testSendNotify()
//        setBadgeNum(99)
//        setBadgeCount(this@MainActivity,66)
    }


    //测试通知
    private fun testSendNotify() {
        val builder: NotificationCompat.Builder
        //8.0
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder = NotificationCompat.Builder(this, getChannelId())

            builder.setSmallIcon(com.secspace.sms.R.mipmap.ic_launcher)
                .setDefaults(Notification.DEFAULT_ALL)
                .setTicker("title")
                .setAutoCancel(true)
                .setContentTitle("contentTitle")
                .setContentText("contentText")
                .setNumber(99)
            notificationManager.notify(123, builder.build())
        }


    }

    /**
     * https://blog.51cto.com/u_16213326/11294652
     */
    private fun setBadgeCount(context: Context, count: Int) {
        val intent = Intent("android.intent.action.BADGE_COUNT_UPDATE")
        intent.putExtra("badge_count", count)
        intent.putExtra("badge_count_package_name", context.packageName)
        intent.putExtra("badge_count_class_name", getLauncherClassName(context))
        context.sendBroadcast(intent)
    }

    private fun getLauncherClassName(context: Context): String? {
        val pm = context.packageManager
        val intent = Intent(Intent.ACTION_MAIN)
        intent.addCategory(Intent.CATEGORY_LAUNCHER)
        val resolveInfos = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
        for (resolveInfo in resolveInfos) {
            val pkgName = resolveInfo.activityInfo.applicationInfo.packageName
            if (pkgName.equals(context.packageName, ignoreCase = true)) {
                return resolveInfo.activityInfo.name
            }
        }
        return null
    }

    //https://developer.honor.com/cn/forum/topicdetail/topicid-3540765949296640
    private fun setBadgeNum(num: Int) {
        try {
            val bunlde = Bundle()
            bunlde.putString("package", "com.test.badge") // com.test.badge is your package name
            bunlde.putString("class", "com.test. badge.MainActivity") // com.test. badge.MainActivity is your apk main activity
            bunlde.putInt("badgenumber", num)
            this.contentResolver.call(Uri.parse("content://com.hihonor.android.launcher.settings/badge/"), "change_badge", null, bunlde)
        } catch (e: java.lang.Exception) {
//            mIsSupportedBade = false
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    fun getChannelId(): String {
        val channelId = "1"
        val channelName = "sms"

        val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT)
        channel.enableLights(true) //显示桌面红点
        channel.lightColor = Color.RED
        channel.setShowBadge(true)
        notificationManager.createNotificationChannel(channel)
        return channel.id
    }

    @RequiresApi(Build.VERSION_CODES.N_MR1)
    fun getShortcutCount(context: Context): Int {
        val shortcutManager: ShortcutManager = context.getSystemService(ShortcutManager::class.java)
        val shortcutInfoList = shortcutManager.dynamicShortcuts
        return shortcutInfoList.size
    }

    override fun onResume() {
        super.onResume()
        initMessenger()

        updateMenuColors()
        refreshMenuItems()

        getOrCreateConversationsAdapter().apply {
            if (storedTextColor != getProperTextColor()) {
                updateTextColor(getProperTextColor())
            }

            if (storedFontSize != config.fontSize) {
                updateFontSize()
            }

            updateDrafts()
        }

        updateTextColors(binding.mainCoordinator)
        binding.searchHolder.setBackgroundColor(getProperBackgroundColor())

        val properPrimaryColor = getProperPrimaryColor()
        binding.noConversationsPlaceholder2.setTextColor(properPrimaryColor)
        binding.noConversationsPlaceholder2.underlineText()
        binding.conversationsFastscroller.updateColors(properPrimaryColor)
        binding.conversationsProgressBar.setIndicatorColor(properPrimaryColor)
        binding.conversationsProgressBar.trackColor = properPrimaryColor.adjustAlpha(LOWER_ALPHA)
//        checkShortcut()
        (binding.conversationsFab.layoutParams as? CoordinatorLayout.LayoutParams)?.bottomMargin =
            navigationBarHeight + resources.getDimension(com.simplemobiletools.commons.R.dimen.activity_margin).toInt()
    }

    override fun onPause() {
        super.onPause()
        storeStateVariables()
    }

    override fun onDestroy() {
        super.onDestroy()
        bus?.unregister(this)
    }

    override fun onBackPressed() {
        if (binding.mainMenu.isSearchOpen) {
            binding.mainMenu.closeSearch()
        } else {
            super.onBackPressed()
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putBoolean(WAS_PROTECTION_HANDLED, wasProtectionHandled)
    }

    @RequiresApi(Build.VERSION_CODES.Q)
    override fun onRestoreInstanceState(savedInstanceState: Bundle) {
        super.onRestoreInstanceState(savedInstanceState)
        wasProtectionHandled = savedInstanceState.getBoolean(WAS_PROTECTION_HANDLED, false)

        if (!wasProtectionHandled) {
            handleAppPasswordProtection {
                wasProtectionHandled = it
                if (it) {
                    loadMessages()
                } else {
                    finish()
                }
            }
        } else {
            loadMessages()
        }
    }

    private fun setupOptionsMenu() {
        binding.mainMenu.getToolbar().inflateMenu(R.menu.menu_main)
        binding.mainMenu.toggleHideOnScroll(true)
        binding.mainMenu.setupMenu()

        binding.mainMenu.onSearchClosedListener = {
            fadeOutSearch()
        }

        binding.mainMenu.onSearchTextChangedListener = { text ->
            if (text.isNotEmpty()) {
                if (binding.searchHolder.alpha < 1f) {
                    binding.searchHolder.fadeIn()
                }
            } else {
                fadeOutSearch()
            }
            searchTextChanged(text)
        }

        /* binding.mainMenu.getToolbar().setOnMenuItemClickListener { menuItem ->
             when (menuItem.itemId) {
                 R.id.more_apps_from_us -> launchMoreAppsFromUsIntent()
                 R.id.show_recycle_bin -> launchRecycleBin()
                 R.id.show_archived -> launchArchivedConversations()
                 R.id.settings -> launchSettings()
                 R.id.about -> launchAbout()
                 else -> return@setOnMenuItemClickListener false
             }
             return@setOnMenuItemClickListener true
         }*/
    }

    private fun refreshMenuItems() {
        binding.mainMenu.getToolbar().menu.apply {
            findItem(R.id.more_apps_from_us).isVisible = /*!resources.getBoolean(com.simplemobiletools.commons.R.bool.hide_google_relations)*/false
            findItem(R.id.show_recycle_bin).isVisible = /*config.useRecycleBin*/ false
            findItem(R.id.show_archived).isVisible = /*config.isArchiveAvailable*/ false
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
        super.onActivityResult(requestCode, resultCode, resultData)
        if (requestCode == MAKE_DEFAULT_APP_REQUEST) {
            if (resultCode == Activity.RESULT_OK) {
                askPermissions()
            } else {
                finish()
            }
        }
    }

    private fun storeStateVariables() {
        storedTextColor = getProperTextColor()
        storedFontSize = config.fontSize
    }

    private fun updateMenuColors() {
        updateStatusbarColor(getProperBackgroundColor())
        binding.mainMenu.updateColors()
    }

    @RequiresApi(Build.VERSION_CODES.Q)
    private fun loadMessages() {
        if (isQPlus()) {
            val roleManager = getSystemService(RoleManager::class.java)
            if (roleManager!!.isRoleAvailable(RoleManager.ROLE_SMS)) {
                if (roleManager.isRoleHeld(RoleManager.ROLE_SMS)) {
                    askPermissions()
                } else {
                    val intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_SMS)
                    startActivityForResult(intent, MAKE_DEFAULT_APP_REQUEST)
                }
            } else {
                toast(com.simplemobiletools.commons.R.string.unknown_error_occurred)
                finish()
            }
        } else {
            if (Telephony.Sms.getDefaultSmsPackage(this) == packageName) {
                askPermissions()
            } else {
                val intent = Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT)
                intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, packageName)
                startActivityForResult(intent, MAKE_DEFAULT_APP_REQUEST)
            }
        }
    }

    // while SEND_SMS and READ_SMS permissions are mandatory, READ_CONTACTS is optional. If we don't have it, we just won't be able to show the contact name in some cases
    private fun askPermissions() {
        handlePermission(PERMISSION_READ_SMS) {
            if (it) {
                handlePermission(PERMISSION_SEND_SMS) {
                    if (it) {
                        handlePermission(PERMISSION_READ_CONTACTS) {
                            handleNotificationPermission { granted ->
                                if (!granted) {
                                    PermissionRequiredDialog(
                                        activity = this,
                                        textId = com.simplemobiletools.commons.R.string.allow_notifications_incoming_messages,
                                        positiveActionCallback = { openNotificationSettings() })
                                }
                            }

//                            initMessenger()
                            bus = EventBus.getDefault()
                            try {
                                bus!!.register(this)
                            } catch (ignored: Exception) {
                            }
                        }
                    } else {
                        finish()
                    }
                }
            } else {
                finish()
            }
        }
    }

    private fun initMessenger() {
        storeStateVariables()
        getCachedConversations()

        binding.noConversationsPlaceholder2.setOnClickListener {
            launchNewConversation()
        }

        binding.conversationsFab.setOnClickListener {
            launchNewConversation()
        }
    }

    private fun getCachedConversations() {
        lifecycleScope.launch(Dispatchers.IO) {
            val conversations = try {
                conversationsDB.getNonArchived().toMutableList() as ArrayList<Conversation>
            } catch (e: Exception) {
                ArrayList()
            }

            val archived = try {
                conversationsDB.getAllArchived()
            } catch (e: Exception) {
                listOf()
            }

            updateUnreadCountBadge(conversations)
//            runOnUiThread {
//                setupConversations(conversations, cached = true)
            getNewConversations((conversations + archived).toMutableList() as ArrayList<Conversation>)
//            }
            conversations.forEach {
                clearExpiredScheduledMessages(it.threadId)
            }
        }
    }

    private fun getNewConversations(cachedConversations: ArrayList<Conversation>) {
        val privateCursor = getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true)

        val privateContacts = MyContactsContentProvider.getSimpleContacts(this@MainActivity, privateCursor)
//            Log.e(TAG, " getNewConversations  privateContacts:${GsonUtil.parseListToJson(privateContacts)}")
        //获取系统SMS DB短信列表
        val conversations: java.util.ArrayList<Conversation> = getConversations(privateContacts = privateContacts)
//            Log.e(TAG, " getNewConversations  获取系统SMS DB短信列表(脏数据) conversations:${GsonUtil.parseListToJson(conversations)}")

        //通过DB数据与cache对比threadID
        conversations.forEach { clonedConversation ->
            val threadIds = cachedConversations.map { it.threadId }
            if (!threadIds.contains(clonedConversation.threadId)) {
                conversationsDB.insertOrUpdate(clonedConversation)
                cachedConversations.add(clonedConversation)
            }
        }

        cachedConversations.forEach { cachedConversation ->
            val threadId = cachedConversation.threadId

            val isTemporaryThread = cachedConversation.isScheduled
            val isConversationDeleted = !conversations.map { it.threadId }.contains(threadId)
            if (isConversationDeleted && !isTemporaryThread) {
                conversationsDB.deleteThreadId(threadId)
            }

            val newConversation: Conversation? = conversations.find { it.phoneNumber == cachedConversation.phoneNumber }
            if (isTemporaryThread && newConversation != null) {
                // delete the original temporary thread and move any scheduled messages to the new thread
                conversationsDB.deleteThreadId(threadId)
                messagesDB.getScheduledThreadMessages(threadId)
                    .forEach { message ->
                        messagesDB.insertOrUpdate(message.copy(threadId = newConversation.threadId))
                    }
                insertOrUpdateConversation(newConversation, cachedConversation)
            }
        }

        cachedConversations.forEach { cachedConv ->
            val conv = conversations.find {
                it.threadId == cachedConv.threadId && !Conversation.areContentsTheSame(cachedConv, it)
            }
//                Log.e(TAG, " getNewConversations 对比后的结果(新数据)222 find conv:${GsonUtil.parseBeanToJson(conv)}")
            if (conv != null && conv.isSFNumber) {
//                    Log.e(TAG, " conversations find it conv:${GsonUtil.parseBeanToJson(conv)}")
                val lastModified = maxOf(cachedConv.date, conv.date)
                val conversation = conv.copy(date = lastModified)
//                    Log.e(
//                        TAG,
//                        " getNewConversations 对比后的结果(新数据) isSFNumber=${conv.isSFNumber} find conversation:${GsonUtil.parseBeanToJson(conversation)}"
//                    )
                insertOrUpdateConversation(conversation)
            }
        }
        val allConversations = conversationsDB.getNonArchived() as ArrayList<Conversation>
//            Log.e(TAG, "----MainActivity----handleMessage allConversations:${GsonUtil.parseListToJson(allConversations)}")
//            runOnUiThread {
        setupConversations(allConversations)
//            }

//            Log.e(TAG, "----MainActivity----handleMessage appRunCount:${config.appRunCount}")
        if (config.appRunCount == 1) {
            conversations.map { it.threadId }.forEach { threadId ->
                val messages = getMessages(threadId, getImageResolutions = false, includeScheduledMessages = false)
                messages.chunked(30).forEach { currentMessages: List<Message> ->
                    messagesDB.insertMessages(*currentMessages.toTypedArray())
                }
            }
        }
    }

    private fun getOrCreateConversationsAdapter(): ConversationsAdapter {
        var currAdapter = binding.conversationsList.adapter
        if (currAdapter == null) {
            hideKeyboard()
            currAdapter = ConversationsAdapter(
                activity = this,
                recyclerView = binding.conversationsList,
                onRefresh = { notifyDatasetChanged() },
                itemClick = { handleConversationClick(it) }
            )

            binding.conversationsList.adapter = currAdapter
            if (areSystemAnimationsEnabled) {
                binding.conversationsList.scheduleLayoutAnimation()
            }
        }
        return currAdapter as ConversationsAdapter
    }

    /**
     * 1.获取最新短信 与通话记录中对比数据进行掩码操作
     * 2.更新列表最新一条的数据
     */
    private fun setFirstConversationAndUpdateData(sortedConversations: ArrayList<Conversation>) {
        val hasPerMissionResult = this@MainActivity.hasPermission(PERMISSION_READ_CALL_LOG)
        if (hasPerMissionResult) {
            val firstConversation = sortedConversations.first()//获取第一条未掩码会话
            Log.d(TAG, " MainActivity firstConversation()  获取第一条会话  =: ${GsonUtil.parseBeanToJson(firstConversation)}")

            val phoneNumber = firstConversation.title.replace(" ", "")
            //只针对手机号
            if (phoneNumber.length != 11 ) return
            if (!firstConversation.isSFNumber) {
                Log.d(TAG, "----MainActivity----获取第一条会话手机号 phoneNumber:$phoneNumber")
                RecentsHelper(context = this@MainActivity).getRecentCalls(false, Int.MAX_VALUE) { recents: List<RecentCall> ->
                    val listCallRecent: List<RecentCall> = recents.distinctBy { it.phoneNumber }
//                    Log.d(TAG, "----MainActivity----最近通话记录列表 :${GsonUtil.parseListToJson(listCallRecent)}")
                    val findResult: RecentCall? = listCallRecent.firstOrNull  { it.phoneNumber.replace(" ","") == phoneNumber && it.isShunFeng }
                    Log.d(TAG, "----MainActivity----是否从通话记录中查找到电话号Result:${findResult != null}")
                    //从最近通话记录中找到了号码 进行掩码操作
                    if (findResult != null) {
                        PhoneUtils.phoneNumberFormat(phoneNumber) { itNumber ->
                            firstConversation.phoneNumber = itNumber
                            firstConversation.isSFNumber = true
                            Log.d(
                                TAG,
                                "----MainActivity----手机号掩码操作 itNumber:${itNumber}  phoneNumber:${firstConversation.phoneNumber}  threadId:${firstConversation.threadId}  "
                            )
                        }
                    }
                }
            }
            //根据最新的短信threadId 获取所有短信列表 取最新一条记录
            val messages: java.util.ArrayList<Message> = getMessages(firstConversation.threadId, true)
            Log.e(TAG, " MainActivity getMessages()  执行查询会话 messages 数据库  =:${GsonUtil.parseListToJson(messages)}  ")
            val lastMsg = messages.last()
            firstConversation.snippet = lastMsg.body
            firstConversation.date = lastMsg.date
            conversationsDB.insertOrUpdate(firstConversation)
        }
    }

    private fun setupConversations(conversations: ArrayList<Conversation>, cached: Boolean = false) {
        if (conversations.size == 0) return

        val sortedConversations = conversations.sortedWith(
            compareByDescending<Conversation> { config.pinnedConversations.contains(it.threadId.toString()) }
                .thenByDescending { it.date }
        ).toMutableList() as ArrayList<Conversation>

        setFirstConversationAndUpdateData(sortedConversations)

        lifecycleScope.launch(Dispatchers.Main) {
//            delay(1_000)
            Log.d(TAG, " MainActivity setupConversations()  修改后显示短信列表数据  =: ${GsonUtil.parseListToJson(sortedConversations)}")
//        runOnUiThread {
            if (cached && config.appRunCount == 1) {
                // there are no cached conversations on the first run so we show the loading placeholder and progress until we are done loading from telephony
                showOrHideProgress(conversations.isEmpty())
            } else {
                showOrHideProgress(false)
                showOrHidePlaceholder(conversations.isEmpty())
            }

            try {
                getOrCreateConversationsAdapter().apply {
                    updateConversations(sortedConversations) {
                        if (!cached) {
                            showOrHidePlaceholder(currentList.isEmpty())
                        }
                    }
                }
            } catch (ignored: Exception) {
            }
        }
    }

    private fun showOrHideProgress(show: Boolean) {
        if (show) {
            binding.conversationsProgressBar.show()
            binding.noConversationsPlaceholder.beVisible()
            binding.noConversationsPlaceholder.text = getString(R.string.loading_messages)
        } else {
            binding.conversationsProgressBar.hide()
            binding.noConversationsPlaceholder.beGone()
        }
    }

    private fun showOrHidePlaceholder(show: Boolean) {
        binding.conversationsFastscroller.beGoneIf(show)
        binding.noConversationsPlaceholder.beVisibleIf(show)
        binding.noConversationsPlaceholder.text = getString(R.string.no_conversations_found)
        binding.noConversationsPlaceholder2.beVisibleIf(show)
    }

    private fun fadeOutSearch() {
        binding.searchHolder.animate().alpha(0f).setDuration(SHORT_ANIMATION_DURATION).withEndAction {
            binding.searchHolder.beGone()
            searchTextChanged("", true)
        }.start()
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun notifyDatasetChanged() {
        getOrCreateConversationsAdapter().notifyDataSetChanged()
    }

    private fun handleConversationClick(any: Any) {
        Intent(this, ThreadActivity::class.java).apply {
            val conversation = any as Conversation
            putExtra(THREAD_ID, conversation.threadId)
            putExtra(THREAD_TITLE, conversation.phoneNumber)
            putExtra(WAS_PROTECTION_HANDLED, wasProtectionHandled)
            startActivity(this)
        }
    }

    private fun launchNewConversation() {
        hideKeyboard()
        Intent(this, NewConversationActivity::class.java).apply {
            startActivity(this)
        }
    }

    /*@SuppressLint("NewApi")
    private fun checkShortcut() {
        val appIconColor = config.appIconColor
        if (isNougatMR1Plus() && config.lastHandledShortcutColor != appIconColor) {
            val newConversation = getCreateNewContactShortcut(appIconColor)

            val manager = getSystemService(ShortcutManager::class.java)
            try {
                manager.dynamicShortcuts = listOf(newConversation)
                config.lastHandledShortcutColor = appIconColor
            } catch (ignored: Exception) {
            }
        }
    }*/

    /* @SuppressLint("NewApi")
     private fun getCreateNewContactShortcut(appIconColor: Int): ShortcutInfo {
         val newEvent = getString(R.string.new_conversation)
         val drawable = resources.getDrawable(com.simplemobiletools.commons.R.drawable.shortcut_plus)
         (drawable as LayerDrawable).findDrawableByLayerId(com.simplemobiletools.commons.R.id.shortcut_plus_background).applyColorFilter(appIconColor)
         val bmp = drawable.convertToBitmap()

         val intent = Intent(this, NewConversationActivity::class.java)
         intent.action = Intent.ACTION_VIEW
         return ShortcutInfo.Builder(this, "new_conversation")
             .setShortLabel(newEvent)
             .setLongLabel(newEvent)
             .setIcon(Icon.createWithBitmap(bmp))
             .setIntent(intent)
             .build()
     }*/

    private fun searchTextChanged(text: String, forceUpdate: Boolean = false) {
        if (!binding.mainMenu.isSearchOpen && !forceUpdate) {
            return
        }

        lastSearchedText = text
        binding.searchPlaceholder2.beGoneIf(text.length >= 2)
        if (text.length >= 2) {
            ensureBackgroundThread {
                val searchQuery = "%$text%"
                val messages = messagesDB.getMessagesWithText(searchQuery)
                val conversations = conversationsDB.getConversationsWithText(searchQuery)
                if (text == lastSearchedText) {
                    showSearchResults(messages, conversations, text)
                }
            }
        } else {
            binding.searchPlaceholder.beVisible()
            binding.searchResultsList.beGone()
        }
    }

    private fun showSearchResults(messages: List<Message>, conversations: List<Conversation>, searchedText: String) {
        val searchResults = ArrayList<SearchResult>()
        conversations.forEach { conversation ->
            val date = conversation.date.formatDateOrTime(this, true, true)
            val searchResult = SearchResult(-1, conversation.title, conversation.phoneNumber, date, conversation.threadId, conversation.photoUri)
            searchResults.add(searchResult)
        }

        messages.sortedByDescending { it.id }.forEach { message ->
            var recipient = message.senderName
            if (recipient.isEmpty() && message.participants.isNotEmpty()) {
                val participantNames = message.participants.map { it.name }
                recipient = TextUtils.join(", ", participantNames)
            }

            val date = message.date.formatDateOrTime(this, true, true)
            val searchResult = SearchResult(message.id, recipient, message.body, date, message.threadId, message.senderPhotoUri)
            searchResults.add(searchResult)
        }

        runOnUiThread {
            binding.searchResultsList.beVisibleIf(searchResults.isNotEmpty())
            binding.searchPlaceholder.beVisibleIf(searchResults.isEmpty())

            val currAdapter = binding.searchResultsList.adapter
            if (currAdapter == null) {
                SearchResultsAdapter(this, searchResults, binding.searchResultsList, searchedText) {
                    hideKeyboard()
                    Intent(this, ThreadActivity::class.java).apply {
                        putExtra(THREAD_ID, (it as SearchResult).threadId)
                        putExtra(THREAD_TITLE, it.title)
                        putExtra(SEARCHED_MESSAGE_ID, it.messageId)
                        startActivity(this)
                    }
                }.apply {
                    binding.searchResultsList.adapter = this
                }
            } else {
                (currAdapter as SearchResultsAdapter).updateItems(searchResults, searchedText)
            }
        }
    }

    private fun launchRecycleBin() {
        hideKeyboard()
        startActivity(Intent(applicationContext, RecycleBinConversationsActivity::class.java))
    }

    private fun launchArchivedConversations() {
        hideKeyboard()
        startActivity(Intent(applicationContext, ArchivedConversationsActivity::class.java))
    }

    private fun launchSettings() {
        hideKeyboard()
        startActivity(Intent(applicationContext, SettingsActivity::class.java))
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun refreshMessages(event: Events.RefreshMessages) {
        Log.e(TAG, "----MainActivity----refreshMessages EventBus")
        initMessenger()
    }

}
