package com.xplora.contactprovider.provider

import android.annotation.SuppressLint
import android.content.ContentProvider
import android.content.ContentUris
import android.content.ContentValues
import android.content.UriMatcher
import android.net.Uri
import androidx.room.Room
import com.google.gson.Gson
import com.xplora.contactprovider.dao.BaseEntity
import com.xplora.contactprovider.dao.ContactDatabase
import com.xplora.contactprovider.dao.ContactInfo

class WatchContactProvider : ContentProvider() {
    companion object {
        private const val AUTHORITIES = "com.xplora.WatchContactProvider"
        const val CONTACT_DIR = 0
        const val CONTACT_ITEM = 1

        const val TABLE_NAME_CONTACT = "contact"
    }

    private var db: ContactDatabase? = null

    private val sUriMatcher by lazy {
        val matcher = UriMatcher(UriMatcher.NO_MATCH)
        matcher.addURI(AUTHORITIES, TABLE_NAME_CONTACT, CONTACT_DIR)
        matcher.addURI(AUTHORITIES, "$TABLE_NAME_CONTACT/#", CONTACT_ITEM)
        matcher
    }

    override fun onCreate() = context?.let {
        db = Room.databaseBuilder(it, ContactDatabase::class.java, TABLE_NAME_CONTACT)
            .build()

/*        val contentValues1 = ContentValues()
        contentValues1.put("id", "1")
        contentValues1.put("userId", "4e6f7g8h")
        contentValues1.put("name", "test_Guardian_1")
        contentValues1.put("phoneNumber", "13500000000")
        contentValues1.put("countryPN", "+86")
        contentValues1.put("sim", 2)
        contentValues1.put("type", 1)
        insert(Uri.parse("content://com.xplora.WatchContactProvider/contact"), contentValues1)

        val contentValues2 = ContentValues()
        contentValues2.put("id", "2")
        contentValues2.put("userId", "f8f9f0f1f2")
        contentValues2.put("name", "test_Guardian_2")
        contentValues2.put("phoneNumber", "13500000001")
        contentValues2.put("countryPN", "+1")
        contentValues2.put("sim", 1)
        contentValues2.put("type", 2)
        insert(Uri.parse("content://com.xplora.WatchContactProvider/contact"), contentValues2)

        val contentValues3 = ContentValues()
        contentValues3.put("name", "test_General")
        contentValues3.put("phoneNumber", "13500000002")
        contentValues3.put("countryPN", "+66")
        contentValues3.put("sim", 2)
        contentValues3.put("type", 3)
        insert(Uri.parse("content://com.xplora.WatchContactProvider/contact"), contentValues3)

        val contentValues4 = ContentValues()
        contentValues2.put("userId", "xxxxpppp")
        contentValues4.put("name", "test_Friend")
        contentValues4.put("phoneNumber", "13500000003")
        contentValues4.put("countryPN", "+886")
        contentValues4.put("sim", 2)
        contentValues4.put("type", 4)
        insert(Uri.parse("content://com.xplora.WatchContactProvider/contact"), contentValues4)*/
        true
    } ?: false

    @SuppressLint("Range")
    override fun query(
        uri: Uri,
        projection: Array<String>?,
        selection: String?,
        selectionArgs: Array<String>?,
        sortOrder: String?
    ) = db?.let { db ->
        val dao = db.contactDao()
        when (sUriMatcher.match(uri)) {
            CONTACT_DIR -> dao.query()
            CONTACT_ITEM -> dao.queryByIdForApp(ContentUris.parseId(uri))
            else -> null
        }?.let { c ->
            while (c.moveToNext()) {
                c.setNotificationUri(context!!.contentResolver, uri)
            }
            c
        }
    }

    override fun getType(uri: Uri): String? = null

    override fun insert(uri: Uri, contentValues: ContentValues?) = db?.let { db ->
        val dao = db.contactDao()
        val mValues = Gson().fromJson(Gson().toJson(contentValues), BaseEntity::class.java).mValues
        val id: Long = when (sUriMatcher.match(uri)) {
            CONTACT_DIR -> {
                val info = Gson().fromJson(mValues, ContactInfo::class.java)
                dao.insert(info)
            }
            else -> -1
        }
        val result = ContentUris.withAppendedId(uri, id)
        context!!.contentResolver.notifyChange(result, null)
        result
    }

    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?) =
        db?.let { db ->
            when (sUriMatcher.match(uri)) {
                CONTACT_ITEM -> {
                    val dao = db.contactDao()
                    val id = ContentUris.parseId(uri)
                    val result = dao.delete(dao.queryById(id))
                    context!!.contentResolver.notifyChange(
                        ContentUris.withAppendedId(uri, id),
                        null
                    )
                    result
                }
                else -> 0
            }
        } ?: 0

    override fun update(
        uri: Uri,
        contentValues: ContentValues?,
        selection: String?,
        selectionArgs: Array<String>?
    ) = db?.let { db ->
        when (sUriMatcher.match(uri)) {
            CONTACT_ITEM -> {
                val dao = db.contactDao()
                val mValues =
                    Gson().fromJson(Gson().toJson(contentValues), BaseEntity::class.java).mValues
                val info = Gson().fromJson(mValues, ContactInfo::class.java)
                val id = ContentUris.parseId(uri)
                val infoFin = dao.queryById(id)
                infoFin.merge(info)
                val result = dao.update(infoFin)
                context!!.contentResolver.notifyChange(ContentUris.withAppendedId(uri, id), null)
                result
            }
            else -> 0
        }
    } ?: 0
}