package com.secspace.sms.receivers

import android.content.Context
import android.net.Uri
import com.bumptech.glide.Glide
import com.google.gson.Gson
import com.klinker.android.send_message.MmsReceivedReceiver
import com.secspace.log.Log
import com.secspace.sms.R
import com.secspace.sms.extensions.*
import com.secspace.sms.helpers.Config
import com.secspace.sms.helpers.RecentsHelper
import com.secspace.sms.helpers.refreshMessages
import com.secspace.sms.models.Message
import com.secspace.sms.models.RecentCall
import com.secspace.sms.popup.MyPushWindow
import com.secspace.sms.util.AES
import com.secspace.sms.util.PhoneFromUtil
import com.secspace.sms.util.PhoneUtils
import com.secspace.sms.util.SmsCountUtil
import com.simplemobiletools.commons.extensions.hasPermission
import com.simplemobiletools.commons.extensions.isNumberBlocked
import com.simplemobiletools.commons.extensions.normalizePhoneNumber
import com.simplemobiletools.commons.extensions.showErrorToast
import com.simplemobiletools.commons.helpers.PERMISSION_READ_CALL_LOG
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.util.GsonUtil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

// more info at https://github.com/klinker41/android-smsmms
class MmsReceiver : MmsReceivedReceiver() {

    private val TAG = "MmsReceiver"
    override fun isAddressBlocked(context: Context, address: String): Boolean {
        val normalizedAddress = address.normalizePhoneNumber()
        return context.isNumberBlocked(normalizedAddress)
    }

    override fun onMessageReceived(context: Context, messageUri: Uri) {

        val mms = context.getLatestMMS() ?: return
        //手机号
        val address = mms.getSender()?.phoneNumbers?.first()?.normalizedNumber ?: ""

        Log.d(TAG, "onMessageReceived: mms = ${Gson().toJson(mms)}")

        Log.d(TAG, "onMessageReceived: address = $address")

        val size = context.resources.getDimension(R.dimen.notification_large_icon_size).toInt()
        ensureBackgroundThread {
            val glideBitmap = try {
                Glide.with(context)
                    .asBitmap()
                    .load(mms.attachment!!.attachments.first().getUri())
                    .centerCrop()
                    .into(size, size)
                    .get()
            } catch (e: Exception) {
                null
            }

            CoroutineScope(Dispatchers.Main).launch {
                var listContains = listOf<String>()
                var encryptNumberResult = ""
                var notificationUserName = ""//通讯录如果有备注则优先展示备注，其次手机号
                val conversation = context.getConversations(mms.threadId).firstOrNull() ?: return@launch
                Log.d(TAG, "onMessageReceived: conversation = ${Gson().toJson(conversation)}")
                if (!PhoneFromUtil.isNumeric(conversation.userName)) {
                    notificationUserName = conversation.userName
                }
                //切子线程
                ensureBackgroundThread {
                    encryptNumberResult = findConversationWithPhoneNumber(context, address, mms.body, mms.threadId)
                    Log.d(TAG, "onMessageReceived: encryptNumberResult = $encryptNumberResult")

                    val messages = context.getMessages(mms.threadId, true)
                    Log.d(TAG, "onMessageReceived: messages 是否为空 = ${messages.isNotEmpty()}")
                    if (messages.isNotEmpty()) {
                        listContains = messages.map { it.body }.filter { it.contains("\u200B") }
                    }

                    if (!PhoneFromUtil.isNumeric(encryptNumberResult) || mms.body.contains("\u200B") || listContains.isNotEmpty()) {
                        conversation.title = encryptNumberResult
                        conversation.isSFNumber = true
                        Log.d(TAG, "onMessageReceived: 满足号码脱敏条件  更改顺丰标识为true ")
                    }
                    context.insertOrUpdateConversation(conversation)
                    badgeTotalNumber(context)
                    refreshMessages()
                    Log.d(TAG, "onMessageReceived: 子线程 currentThread = ${Thread.currentThread()}")
                    Log.d(TAG, "handleMessage: notificationUserName = $notificationUserName  encryptNumberResult = $encryptNumberResult  address = $address")
                    if(notificationUserName.isNotBlank()){
                        context.showReceivedMessageNotification(mms.id, notificationUserName, mms.body, mms.threadId, glideBitmap)
                    }else if (encryptNumberResult.isNotBlank()) {
                        context.showReceivedMessageNotification(mms.id, encryptNumberResult, mms.body, mms.threadId, glideBitmap)
                    } else {
                        context.showReceivedMessageNotification(mms.id, address, mms.body, mms.threadId, glideBitmap)
                    }
                }

                Log.d(TAG, "onMessageReceived: UI程 currentThread = ${Thread.currentThread()}")
                Log.d(
                    TAG,
                    "SmsReceiver: notificationUserName = $notificationUserName  encryptNumberResult = $encryptNumberResult  address = $address"
                )
                if (notificationUserName.isNotBlank()) {
                    val tipPopup = MyPushWindow(context, notificationUserName, mms.body)
                    tipPopup.show()
                } else if (encryptNumberResult.isNotBlank()) {
                    val tipPopup = MyPushWindow(context, encryptNumberResult, mms.body)
                    tipPopup.show()
                } else {
                    Log.d(TAG, "SmsReceiver  短信内容  = ${mms.body}   address = $address ")
                    if (mms.body.contains("\u200B")) {
                        if (address.contains("+86")) {
                            address.replace("+86", "")
                        }
                        PhoneUtils.phoneNumberFormat(address) { itNumber ->
                            val tipPopup = MyPushWindow(context, itNumber, mms.body)
                            tipPopup.show()
                        }
                    } else {
                        val tipPopup = MyPushWindow(context, address, mms.body)
                        tipPopup.show()
                    }
                }
            }
        }
    }

    override fun onError(context: Context, error: String) = context.showErrorToast(context.getString(R.string.couldnt_download_mms))

    /**
     * 1.先从短信DB库查找
     * 2.未找到再从 通话记录中查找
     */
    private fun findConversationWithPhoneNumber(
        context: Context,
        phoneNumber: String,
        body: String,
        threadId: Long
    ): String {
        var lastNumber = ""
        Log.d(TAG, "SmsReceiver phoneNumber:${phoneNumber}   body = $body  threadId = $threadId")
        val hasPerMissionResult = context.hasPermission(PERMISSION_READ_CALL_LOG)
        if (hasPerMissionResult) {

            //1
            val listMessageData = context.getMessages(threadId, false)
            if (listMessageData.isNotEmpty()) {
                val listContains: List<Message> = listMessageData.filter { msg -> msg.body.contains("\u200B") }
                if (listContains.isNotEmpty()) {
                    PhoneUtils.phoneNumberFormat(phoneNumber) { itNumber ->
                        lastNumber = itNumber
                    }
                }
            }

            //2
            if (lastNumber.isEmpty()) {
                RecentsHelper(context = context).getRecentCalls(false, Int.MAX_VALUE) { recents: List<RecentCall> ->
                    val listCallRecent: List<RecentCall> = recents.distinctBy { it.phoneNumber }
                    Log.d(TAG, "SmsReceiver最近通话 recents:${GsonUtil.parseListToJson(listCallRecent)}")
                    val findResult = listCallRecent.filter { it.isShunFeng }.count {
                        Log.d(TAG, "SmsReceiver findResult  isNumber = ${PhoneFromUtil.isNumeric(it.phoneNumber)}")

                        if (PhoneFromUtil.isNumeric(it.phoneNumber)) {
                            if (phoneNumber.contains("+86")) {
                                it.phoneNumber == phoneNumber.replace("+86", "")
                            } else {
                                it.phoneNumber == phoneNumber
                            }
                        } else {
                            if (phoneNumber.contains("+86")) {
                                AES.decrypt(it.phoneNumber) == phoneNumber.replace("+86", "")
                            } else {
                                AES.decrypt(it.phoneNumber) == phoneNumber
                            }
                        }
                    }
                    Log.d(TAG, "SmsReceiverFindResult:${findResult}   phoneNumber = ${phoneNumber.trim()}")
                    //从最近通话记录中找到了号码 进行掩码操作
                    if (findResult > 0) {
                        PhoneUtils.phoneNumberFormat(phoneNumber) { itNumber ->
                            lastNumber = itNumber
                        }
                    }
                }
            }
            Log.d(TAG, "SmsReceiver   lastNumber = $lastNumber")
        }
        return lastNumber.ifBlank {
            phoneNumber
        }
    }

    /**
     * 统计未读消息数量
     *
     * 存储值在 Mainactivity.kt 完成
     * 此处只做获取数值操作
     * 1.未获取到值则表明没有未读短信，直接+1显示
     * 2.获取到值也要数量+1 显示
     */
    private fun badgeTotalNumber(context: Context) {

        val readTotalResult: Int = Config.newInstance(context).badgeTotalNumber
        val totalResult = readTotalResult + 1
        SmsCountUtil.setBadgeNum(context, totalResult)

        Config.newInstance(context).badgeTotalNumber = totalResult
        Log.d(TAG, "badgeTotalNumber  readTotalResult = $totalResult ")
    }


}
