package com.seatel.mobilehall.util.lang

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.os.Build
import android.text.TextUtils
import android.util.Log
import com.seatel.mobilehall.data.network.GetLanguage
import com.seatel.mobilehall.data.prefs.LanguagePreference
import com.seatel.mobilehall.data.realm.WordRealmObject
import io.realm.Case
import io.realm.Realm
import io.realm.RealmConfiguration
import io.realm.RealmObject
import org.json.JSONObject
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream
import java.util.*

class LanguageManager(context: Context) {
    private val TAG = "LanguageManager"
    private var mContext: Context? = null
    private var realmConfig: RealmConfiguration? = null

    private val EXPORT_REALM_FILE_NAME = "SeatelLanguageV2.realm"

    companion object {
        @SuppressLint("StaticFieldLeak")
        @Volatile
        private var instance: LanguageManager? = null

        fun getInstance(context: Context): LanguageManager {
            if (instance == null)  // NOT thread safe!
                instance = LanguageManager(context)

            return instance as LanguageManager
        }
    }


    init {
        this.mContext = context
        Realm.init(context)
        realmConfig =
            RealmConfiguration.Builder().name(EXPORT_REALM_FILE_NAME).deleteRealmIfMigrationNeeded()
                .schemaVersion(2).build()
//        val word = Realm.getInstance(getRealmConfig()).where(WordRealmObject::class.java!!).count()
    }

    private fun getRealmConfig(): RealmConfiguration? {
        return realmConfig
    }

    fun getRealm(context: Context): Realm {
        return getInstance(context).getRealm()
    }

    private fun getRealm(): Realm {
        return Realm.getInstance(getRealmConfig()!!)
    }

    fun saveAll(objects: List<RealmObject>) {
        if (objects.isEmpty())
            return
        val realm: Realm = Realm.getInstance(getRealmConfig()!!)
        realm.isAutoRefresh = true
        realm.beginTransaction()
        realm.copyToRealmOrUpdate(objects)
        realm.commitTransaction()
        realm.close()
    }

    fun updateResources(activity: Activity) {
        val languageCode =
            LanguagePreference.getInstance(activity)?.getAppSharedLanguageCodePreference()
        val locale = Locale(languageCode)
        Locale.setDefault(locale)

        val configuration = activity.resources.configuration
        configuration?.setLocale(locale)
        configuration?.setLayoutDirection(locale)


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            activity.createConfigurationContext(configuration)
        } else {
            activity.resources.updateConfiguration(configuration, null)
        }
        activity.recreate()
    }

    fun translateWords(context: Context, text: String): String {
        var textTranslate: String = text
        val languageCode: String = getInstance(context).getLanguageCode().toString()
        val word: WordRealmObject? =
            getInstance(context).getRealm().where(WordRealmObject::class.java)
                .equalTo("languageCode", languageCode)
                .equalTo("key", text, Case.INSENSITIVE).findFirst()
        if (word != null) {
            textTranslate = word.getValue().toString()
        } else {
            Log.e(TAG, "$text  Missing \" $textTranslate \" in ")
        }
        return textTranslate
    }

    fun getLanguageCode(): String? {
        return LanguagePreference.getInstance(this.mContext!!)?.getAppSharedLanguageCodePreference()
            ?.lowercase(Locale.getDefault())
    }

    fun setSelectedLanguage(languageCode: String) {
        LanguagePreference.getInstance(this.mContext!!)
            ?.setAppSharedLanguageCodePreference(languageCode)
    }

    fun updateLanguage(response: JSONObject?) {
        LanguageReadAsynctask(this.mContext!!, response).execute()
    }

    fun checkUpdate(version: String) {
        if (TextUtils.equals(
                version,
                LanguagePreference.getInstance(this.mContext!!)?.getLanguageVersion()
            )
        ) {
            // api get language new version
            GetLanguage(mContext).execute()
        }
    }

    fun clearAll(): LanguageManager {
        val realm = Realm.getInstance(getRealmConfig()!!)
        if (!realm.isEmpty) {
            realm.isAutoRefresh = true
            realm.beginTransaction()
            realm.deleteAll()
            realm.commitTransaction()
            realm.close()
        }
        return this
    }

    fun backup() {
        val realm = Realm.getInstance(getRealmConfig()!!)
        val exportRealmFile =
            File(mContext?.getExternalFilesDir(null)?.absolutePath, EXPORT_REALM_FILE_NAME)
        if (exportRealmFile.exists())
            exportRealmFile.delete()
        realm.writeCopyTo(exportRealmFile)
        realm.close()
        Log.d("BACKUP_LANGUAGE", exportRealmFile.path)
    }

    fun restore(context: Context) {

        val file = File(mContext?.applicationContext?.filesDir, EXPORT_REALM_FILE_NAME)
        if (!file.exists()) {
            copyBundledRealmFile(
                context,
                context.assets.open("db/$EXPORT_REALM_FILE_NAME"),
                EXPORT_REALM_FILE_NAME
            )
        }
    }

    private fun copyBundledRealmFile(
        context: Context,
        inputStream: InputStream,
        outFileName: String
    ): String {
        if (!context.applicationContext.filesDir.exists()) {
            context.applicationContext.filesDir.mkdirs()
        }

        val file = File(context.applicationContext.filesDir, outFileName)
        if (file.exists()) {
            file.delete()
        }
        val outputStream = FileOutputStream(file)
        val buf = ByteArray(1024)
        val bytesRead: Int = inputStream.read(buf)
        while (bytesRead > 0) {
            outputStream.write(buf, 0, bytesRead)
        }
        outputStream.close()
        return file.absolutePath
    }

}