package com.secspace.sms.adapters

import android.text.TextUtils
import android.view.Menu
import com.google.gson.Gson
import com.secspace.log.Log
import com.secspace.sms.R
import com.secspace.sms.activities.SimpleActivity
import com.secspace.sms.dialogs.RenameConversationDialog
import com.secspace.sms.extensions.*
import com.secspace.sms.helpers.Config
import com.secspace.sms.helpers.refreshMessages
import com.secspace.sms.models.Conversation
import com.secspace.sms.models.Message
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.FeatureLockedDialog
import com.simplemobiletools.commons.extensions.addBlockedNumber
import com.simplemobiletools.commons.extensions.copyToClipboard
import com.simplemobiletools.commons.extensions.isOrWasThankYouInstalled
import com.simplemobiletools.commons.extensions.notificationManager
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.views.MyRecyclerView

class ConversationsAdapter(
    activity: SimpleActivity, recyclerView: MyRecyclerView, onRefresh: () -> Unit, itemClick: (Any) -> Unit
) : BaseConversationsAdapter(activity, recyclerView, onRefresh, itemClick) {
    override fun getActionMenuId() = R.menu.cab_conversations

    private val TAG = "ConversationsAdapter"
    override fun prepareActionMode(menu: Menu) {
        /* val selectedItems = getSelectedItems()
         val isSingleSelection = isOneItemSelected()
         val selectedConversation = selectedItems.firstOrNull() ?: return
         val isGroupConversation = selectedConversation.isGroupConversation
         val archiveAvailable = activity.config.isArchiveAvailable*/

        menu.apply {
            findItem(R.id.cab_block_number).title = /*activity.addLockedLabelIfNeeded(com.simplemobiletools.commons.R.string.block_number)*/ ""
            findItem(R.id.cab_block_number).isVisible = /*isNougatPlus()*/ false
            findItem(R.id.cab_add_number_to_contact).isVisible = /*isSingleSelection && !isGroupConversation*/ false
            findItem(R.id.cab_dial_number).isVisible =
                /*isSingleSelection && !isGroupConversation && !isShortCodeWithLetters(selectedConversation.phoneNumber)*/ false
            findItem(R.id.cab_copy_number).isVisible = /*isSingleSelection && !isGroupConversation*/ false
            findItem(R.id.cab_rename_conversation).isVisible = /*isSingleSelection && isGroupConversation*/ false
            findItem(R.id.cab_mark_as_read).isVisible = /*selectedItems.any { !it.read }*/ false
            findItem(R.id.cab_mark_as_unread).isVisible = /*selectedItems.any { it.read }*/ false
            findItem(R.id.cab_archive).isVisible = /*archiveAvailable*/ false
            checkPinBtnVisibility(this)
        }
    }

    override fun actionItemPressed(id: Int) {
        if (selectedKeys.isEmpty()) {
            return
        }

        when (id) {
            /*R.id.cab_add_number_to_contact -> addNumberToContact()
            R.id.cab_block_number -> tryBlocking()
            R.id.cab_dial_number -> dialNumber()
            R.id.cab_copy_number -> copyNumberToClipboard()
            R.id.cab_delete -> askConfirmDelete()
            R.id.cab_archive -> askConfirmArchive()
            R.id.cab_rename_conversation -> renameConversation(getSelectedItems().first())
            R.id.cab_mark_as_read -> markAsRead()
            R.id.cab_mark_as_unread -> markAsUnread()
            R.id.cab_select_all -> selectAll()*/
            R.id.cab_delete -> askConfirmDelete()
            R.id.cab_pin_conversation -> pinConversation(true)
            R.id.cab_unpin_conversation -> pinConversation(false)
        }
    }

    private fun tryBlocking() {
        if (activity.isOrWasThankYouInstalled()) {
            askConfirmBlock()
        } else {
            FeatureLockedDialog(activity) { }
        }
    }

    private fun askConfirmBlock() {
        val numbers = getSelectedItems().distinctBy { it.phoneNumber }.map { it.phoneNumber }
        val numbersString = TextUtils.join(", ", numbers)
        val question = String.format(resources.getString(com.simplemobiletools.commons.R.string.block_confirmation), numbersString)

        ConfirmationDialog(activity, question) {
            blockNumbers()
        }
    }

    private fun blockNumbers() {
        if (selectedKeys.isEmpty()) {
            return
        }

        val numbersToBlock = getSelectedItems()
        val newList = currentList.toMutableList().apply { removeAll(numbersToBlock) }

        ensureBackgroundThread {
            numbersToBlock.map { it.phoneNumber }.forEach { number ->
                activity.addBlockedNumber(number)
            }

            activity.runOnUiThread {
                submitList(newList)
                finishActMode()
            }
        }
    }

    private fun dialNumber() {
        val conversation = getSelectedItems().firstOrNull() ?: return
        activity.dialNumber(conversation.phoneNumber) {
            finishActMode()
        }
    }

    private fun copyNumberToClipboard() {
        val conversation = getSelectedItems().firstOrNull() ?: return
        activity.copyToClipboard(conversation.phoneNumber)
        finishActMode()
    }

    private fun askConfirmDelete() {
        val itemsCnt = selectedKeys.size
        val items = resources.getQuantityString(R.plurals.delete_conversations, itemsCnt, itemsCnt)

        val baseString = com.simplemobiletools.commons.R.string.deletion_confirmation
        val question = String.format(resources.getString(baseString), items)

        ConfirmationDialog(activity, question) {
            ensureBackgroundThread {
                Log.d(TAG, "ConversationsAdapter askConfirmDelete   selectedKeys = ${Gson().toJson(selectedKeys)} ")
                Log.d(TAG, "ConversationsAdapter askConfirmDelete   selectedKeys = ${Gson().toJson(currentList)} ")
                currentList.forEach {
                    if (selectedKeys.contains(it.hashCode())) {
                        Log.d(TAG, "ConversationsAdapter askConfirmDelete    selectedKeys = ${it.hashCode()}  threadId = ${it.threadId}")
                        //记录被删除的Conversation会话包含[零宽度字符]的ThreadId
                        val listMessageData = activity.getMessages(it.threadId, false)
                        Log.d(TAG, "ConversationsAdapter askConfirmDelete   threadId  = ${it.threadId}  listMessageData = ${Gson().toJson(listMessageData)} ")
                        if (listMessageData.isNotEmpty()) {
                            val listContains: List<Message> = listMessageData.filter { msg -> msg.body.contains("\u200B") }
                            var listMsgIdAll: String? = Config.newInstance(activity).listDeleteMsgIdAllData
                            Log.d(TAG, "ConversationsAdapter askConfirmDelete   获取被删除的会话集合  listMsgIdAll = ${listMsgIdAll}")
                            if(listMsgIdAll.isNullOrEmpty()){
                                Config.newInstance(activity).listDeleteMsgIdAllData = "${it.title},"
                            }else {
                                val listMsgIdAllResult: List<String> = listMsgIdAll.split(",")
                                if (listContains.isNotEmpty() && !listMsgIdAllResult.contains(it.title) && !it.title.contains("*")) {
                                    listMsgIdAll += "${it.title},"
                                    Config.newInstance(activity).listDeleteMsgIdAllData = listMsgIdAll
                                    Log.d(TAG, "ConversationsAdapter askConfirmDelete   获取被删除的会话集合  listMsgIdAll += ${listMsgIdAll}")
                                }
                            }
                        }
                    }
                }
                deleteConversations()
            }
        }
    }

    private fun askConfirmArchive() {
        val itemsCnt = selectedKeys.size
        val items = resources.getQuantityString(R.plurals.delete_conversations, itemsCnt, itemsCnt)

        val baseString = R.string.archive_confirmation
        val question = String.format(resources.getString(baseString), items)

        ConfirmationDialog(activity, question) {
            ensureBackgroundThread {
                archiveConversations()
            }
        }
    }

    private fun archiveConversations() {
        if (selectedKeys.isEmpty()) {
            return
        }

        val conversationsToRemove = currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
        conversationsToRemove.forEach {
            activity.updateConversationArchivedStatus(it.threadId, true)
            activity.notificationManager.cancel(it.threadId.hashCode())
        }

        val newList = try {
            currentList.toMutableList().apply { removeAll(conversationsToRemove) }
        } catch (ignored: Exception) {
            currentList.toMutableList()
        }

        activity.runOnUiThread {
            if (newList.none { selectedKeys.contains(it.hashCode()) }) {
                refreshMessages()
                finishActMode()
            } else {
                submitList(newList)
                if (newList.isEmpty()) {
                    refreshMessages()
                }
            }
        }
    }

    private fun deleteConversations() {
        if (selectedKeys.isEmpty()) {
            return
        }

        val conversationsToRemove = currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
        conversationsToRemove.forEach {
            activity.deleteConversation(it.threadId)
            activity.notificationManager.cancel(it.threadId.hashCode())
        }

        val newList = try {
            currentList.toMutableList().apply { removeAll(conversationsToRemove) }
        } catch (ignored: Exception) {
            currentList.toMutableList()
        }

        activity.runOnUiThread {
            if (newList.none { selectedKeys.contains(it.hashCode()) }) {
                refreshMessages()
                finishActMode()
            } else {
                submitList(newList)
                if (newList.isEmpty()) {
                    refreshMessages()
                }
            }
        }
    }

    private fun renameConversation(conversation: Conversation) {
        RenameConversationDialog(activity, conversation) {
            ensureBackgroundThread {
                val updatedConv = activity.renameConversation(conversation, newTitle = it)
                activity.runOnUiThread {
                    finishActMode()
                    currentList.toMutableList().apply {
                        set(indexOf(conversation), updatedConv)
                        updateConversations(this as ArrayList<Conversation>)
                    }
                }
            }
        }
    }

    private fun markAsRead() {
        if (selectedKeys.isEmpty()) {
            return
        }

        val conversationsMarkedAsRead = currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
        ensureBackgroundThread {
            conversationsMarkedAsRead.filter { conversation -> !conversation.read }.forEach {
                activity.markThreadMessagesRead(it.threadId)
            }

            refreshConversations()
        }
    }

    private fun markAsUnread() {
        if (selectedKeys.isEmpty()) {
            return
        }

        val conversationsMarkedAsUnread = currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
        ensureBackgroundThread {
            conversationsMarkedAsUnread.filter { conversation -> conversation.read }.forEach {
                activity.markThreadMessagesUnread(it.threadId)
            }

            refreshConversations()
        }
    }


    private fun pinConversation(pin: Boolean) {
        val conversations = getSelectedItems()
        if (conversations.isEmpty()) {
            return
        }

        if (pin) {
            activity.config.addPinnedConversations(conversations)
        } else {
            activity.config.removePinnedConversations(conversations)
        }

        getSelectedItemPositions().forEach {
            notifyItemChanged(it)
        }
        refreshConversations()
    }

    private fun checkPinBtnVisibility(menu: Menu) {
        val pinnedConversations = activity.config.pinnedConversations
        val selectedConversations = getSelectedItems()
        menu.findItem(R.id.cab_pin_conversation).isVisible = selectedConversations.any { !pinnedConversations.contains(it.threadId.toString()) }
        menu.findItem(R.id.cab_unpin_conversation).isVisible = selectedConversations.any { pinnedConversations.contains(it.threadId.toString()) }
    }

    private fun refreshConversations() {
        activity.runOnUiThread {
            refreshMessages()
            finishActMode()
        }
    }
}
