package com.secspace.sms.receivers

import android.annotation.SuppressLint
import android.content.Context
import android.database.ContentObserver
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.provider.Telephony
import android.provider.Telephony.Sms
import android.util.Log
import com.secspace.sms.extensions.*
import com.secspace.sms.helpers.refreshMessages
import com.secspace.sms.models.Conversation
import com.secspace.sms.models.Message
import com.simplemobiletools.commons.extensions.getLongValue
import com.simplemobiletools.commons.extensions.getMyContactsCursor
import com.simplemobiletools.commons.extensions.getStringValue
import com.simplemobiletools.commons.extensions.isNumberBlocked
import com.simplemobiletools.commons.helpers.SimpleContactsHelper
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.models.PhoneNumber
import com.simplemobiletools.commons.models.SimpleContact

class SmsSendObserver(private val context: Context, handler: Handler?) : ContentObserver(handler) {
    private val TAG = "SmsObserver"

    private val SMS_PROJECTION = arrayOf("address", "person", "date", "type", "body")
    private val sortOrder = "${Sms.DATE} DESC LIMIT 1"

    @SuppressLint("Range")
    override fun onChange(selfChange: Boolean) {
        super.onChange(selfChange)
        Log.d(TAG, "SmsObserver:   onChange  ")

        val cursor = context.contentResolver.query(
            Uri.parse("content://sms/sent"),
            SMS_PROJECTION,
            " type=?",
            arrayOf("2"),
            sortOrder
        )
        if (cursor == null) return

        if (cursor.moveToFirst()) {
            val body = cursor.getStringValue(Sms.BODY)
            val address = cursor.getStringValue(Sms.ADDRESS)    //cursor.getString(cursor.getColumnIndex("address")).toString()
            val date = cursor.getLongValue(Sms.DATE)    //cursor.getString(cursor.getColumnIndex("date")).toLong()
            val threadId = context.getThreadId(address)
            com.secspace.log.Log.d(TAG, "获取当前日期  threadId   = $threadId")

            ensureBackgroundThread {
                val listContainsDate: List<Int> = context.messagesDB.getAll().map { it.date }.distinct()
                val convDate = (date / 1000).toInt()
//                com.secspace.log.Log.d(TAG, "获取当前日期  convDate   = $convDate")
//                com.secspace.log.Log.d(TAG, "获取数据库Date集合  isContains  = ${listContainsDate.contains(convDate)}   listContainsDate   = $listContainsDate")

                if (!listContainsDate.contains(convDate) || listContainsDate.isEmpty()) {
                    handleMessage(context, address, body, date, threadId, Telephony.Sms.MESSAGE_TYPE_SENT, 0, 0)
                }
                cursor.close()
            }
        }

    }

    private fun handleMessage(
        context: Context,
        address: String,
        body: String,
        date: Long,
        threadId: Long,
        type: Int,
        subscriptionId: Int,
        status: Int,
    ) {
        val photoUri = SimpleContactsHelper(context).getPhotoUriFromPhoneNumber(address)
        Handler(Looper.getMainLooper()).post {
            if (!context.isNumberBlocked(address)) {
                val privateCursor = context.getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true)
                ensureBackgroundThread {
                    val conversation: Conversation = context.getConversations(threadId).firstOrNull() ?: return@ensureBackgroundThread
                    try {
                        context.insertOrUpdateConversation(conversation)
                    } catch (ignored: Exception) {
                    }
                    val senderName = context.getNameFromAddress(address, privateCursor)
                    val phoneNumber = PhoneNumber(address, 0, "", address)

                    val participant = SimpleContact(0, 0, senderName, photoUri, arrayListOf(phoneNumber), ArrayList(), ArrayList())
                    val participants = arrayListOf(participant)
                    val messageDate = (date / 1000).toInt()

                    var newMessageId = 0L
                    val msgResult: List<Message> = context.messagesDB.getAllById()
                    if (msgResult.isNotEmpty()) {
                        newMessageId = msgResult.last().id
                        newMessageId++
                    }
                    val message =
                        Message(
                            newMessageId,
                            body,
                            type,
                            status,
                            participants,
                            messageDate,
                            true,
                            threadId,
                            false,
                            null,
                            address,
                            senderName,
                            photoUri,
                            subscriptionId
                        )
//                    Log.d(TAG, "SmsObserver    handleMessage message:${GsonUtil.parseBeanToJson(message)}")
                    context.messagesDB.insertOrUpdate(message)
                    if (context.config.isArchiveAvailable) {
                        context.updateConversationArchivedStatus(threadId, false)
                    }
                    refreshMessages()
                }
            }
        }
    }
}
