package rasel.lunar.launcher.workers

import android.annotation.SuppressLint
import android.content.Context
import android.provider.CallLog
import androidx.work.WorkerParameters
import com.google.gson.Gson
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.query
import io.realm.kotlin.types.RealmObject
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.apps.SimpleContact
import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.utils.beforeDay
import rasel.lunar.launcher.utils.getContactId
import java.text.SimpleDateFormat
import java.util.Date



class RecentCall : RealmObject {

    constructor(count: Int, name: String?, number: String, type: Int, typeString: String, date : String, callDayTime : Long, duration : Long) {
        this.count = count
        this.name = name ?: "unknown"
        this.number = number
        this.type = type
        this.typeString = typeString
        this.date = date
        this.uniqK = number.plus("_").plus(callDayTime)
        this.callDayTime = callDayTime
        this.duration = duration
    }

    constructor()

    var callDayTime = 0L
    var uniqK : String? = ""
    var count : Int = 1
    var name : String = "how"
    var number : String = ""
    var type : Int = 0
    var typeString : String = ""
    var date : String = ""
    var duration = 0L

    fun toJson() : String {
        return Gson().toJson(this)
    }

}

class RecentCallGetter : BaseGetter {
    companion object{
            var dayRange = BaseGetter.defaultDay
        val TAG = "RecentCallGetter"
        val dateFormat = SimpleDateFormat("yyy/MM/dd-HH:mm:ss")
    }
    constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {
    }

    @SuppressLint("RestrictedApi")
    override fun realWork(): Result {

        var dateParam = beforeDay(Date(),dayRange).toString()
        var managedCursor = lActivity?.contentResolver?.query(
            CallLog.Calls.CONTENT_URI, arrayOf(
                CallLog.Calls.NUMBER,
                CallLog.Calls.TYPE,
                CallLog.Calls.DATE,
                CallLog.Calls.DURATION,
                CallLog.Calls.CACHED_NAME,
            ), CallLog.Calls.DATE + " >= ? " ,  arrayOf<String>(dateParam),  CallLog.Calls.DATE + " desc")
        //+ CallLog.Calls.TYPE + " > ?"
        //, "2"
        if(managedCursor != null && managedCursor.isClosed == false) {
            try {
                val number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER)
                val type = managedCursor.getColumnIndex(CallLog.Calls.TYPE)
                val date = managedCursor.getColumnIndex(CallLog.Calls.DATE)
                val duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION)
                val name = managedCursor.getColumnIndex(CallLog.Calls.CACHED_NAME)
                while (managedCursor.moveToNext()) {
                    val phNumber = managedCursor.getString(number) // mobile number
                    val callType = managedCursor.getString(type) // call type
                    val callDate = managedCursor.getString(date) // call date
                    val callDayTime  = callDate.toLong()
                    val callDuration = managedCursor.getString(duration)
                    val callerName = managedCursor.getString(name)

                    var dir: String = ""
                    val dircode = callType.toInt()
                    when (dircode) {
                        CallLog.Calls.INCOMING_TYPE -> { dir = "INCOMING_TYPE" }
                        CallLog.Calls.OUTGOING_TYPE -> { dir = "OUTGOING_TYPE" }
                        CallLog.Calls.MISSED_TYPE -> { dir = "MISSED_TYPE" }
                        CallLog.Calls.VOICEMAIL_TYPE -> { dir = "VOICEMAIL_TYPE" }
                        CallLog.Calls.REJECTED_TYPE -> { dir = "REJECTED_TYPE" }
                        CallLog.Calls.BLOCKED_TYPE -> { dir = "BLOCKED_TYPE" }
                        CallLog.Calls.ANSWERED_EXTERNALLY_TYPE -> { dir = "ANSWERED_EXTERNALLY_TYPE" }
                    }

                    val call = RecentCall(
                        1,
                        callerName,
                        phNumber,
                        dircode,
                        dir,
                        dateFormat.format(Date(callDayTime)),
                        callDayTime,
                        callDuration.toLong()
                    )
                    call.uniqK?.let {
//                        BLog.LOGE("${TAG} call.uniqK? >>> ${call.uniqK}")
                        WorkersDb.getRealm().writeBlocking {
                            if(query<RecentCall>().query("uniqK == $0", it).find().count() < 1) {
                                this.copyToRealm(call, UpdatePolicy.ALL)
                                var cId = getContactId(lActivity!!.contentResolver, call.number)
                                if (cId!=null && cId.length > 0) {
                                    val result = query<SimpleContact>().query("id == $0", cId).find()
                                    if(result.size > 0){
                                        var contact = result.first()
                                        contact.touchCount = contact.touchCount + 1
                                        contact.lastedTouchDateTime = Math.max(contact.lastedTouchDateTime, callDayTime)
//                                        BLog.LOGE("${TAG} updatetouch info >>>> ${contact.touchCount}")
                                    }
                                }
                            }
//                            BLog.LOGE("${TAG} updatetouch info >>>> BE ")
                        }
//                        BLog.LOGE("${TAG} updatetouch info >>>> E")
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            } finally {
                managedCursor.close()
            }
        }
        return Result.success().apply {
            dayRange = BaseGetter.defaultDay
        }
    }

}