package ru.forbion.f7cloud.feature.calendar

import android.content.Context
import org.json.JSONArray
import org.json.JSONObject

data class CalendarSyncMapping(
    val ncUid: String,
    val ncHref: String,
    val ncEtag: String,
    val deviceEventId: Long,
    val deviceCalendarId: Long,
)

class CalendarSyncStore(context: Context) {
    private val prefs = context.applicationContext.getSharedPreferences(PREFS, Context.MODE_PRIVATE)

    fun isEnabled(accountKey: String): Boolean =
        prefs.getBoolean(keyEnabled(accountKey), false)

    fun setEnabled(accountKey: String, enabled: Boolean) {
        prefs.edit().putBoolean(keyEnabled(accountKey), enabled).apply()
    }

    fun getDeviceCalendarId(accountKey: String): Long =
        prefs.getLong(keyDeviceCal(accountKey), -1L)

    fun setDeviceCalendarId(accountKey: String, calendarId: Long) {
        prefs.edit().putLong(keyDeviceCal(accountKey), calendarId).apply()
    }

    fun getLastSyncAt(accountKey: String): Long =
        prefs.getLong(keyLastSync(accountKey), 0L)

    fun setLastSyncAt(accountKey: String, epochMilli: Long) {
        prefs.edit().putLong(keyLastSync(accountKey), epochMilli).apply()
    }

    fun loadMappings(accountKey: String): List<CalendarSyncMapping> {
        val raw = prefs.getString(keyMappings(accountKey), null) ?: return emptyList()
        return runCatching {
            val arr = JSONArray(raw)
            buildList {
                for (i in 0 until arr.length()) {
                    val o = arr.getJSONObject(i)
                    add(
                        CalendarSyncMapping(
                            ncUid = o.getString("ncUid"),
                            ncHref = o.getString("ncHref"),
                            ncEtag = o.optString("ncEtag", ""),
                            deviceEventId = o.getLong("deviceEventId"),
                            deviceCalendarId = o.getLong("deviceCalendarId"),
                        ),
                    )
                }
            }
        }.getOrDefault(emptyList())
    }

    fun saveMappings(accountKey: String, mappings: List<CalendarSyncMapping>) {
        val arr = JSONArray()
        mappings.forEach { m ->
            arr.put(
                JSONObject()
                    .put("ncUid", m.ncUid)
                    .put("ncHref", m.ncHref)
                    .put("ncEtag", m.ncEtag)
                    .put("deviceEventId", m.deviceEventId)
                    .put("deviceCalendarId", m.deviceCalendarId),
            )
        }
        prefs.edit().putString(keyMappings(accountKey), arr.toString()).apply()
    }

    fun accountKey(serverUrl: String, username: String): String =
        "${serverUrl.trimEnd('/')}|$username"

    companion object {
        private const val PREFS = "f7_calendar_sync"

        private fun keyEnabled(account: String) = "enabled::$account"
        private fun keyDeviceCal(account: String) = "device_cal::$account"
        private fun keyMappings(account: String) = "mappings::$account"
        private fun keyLastSync(account: String) = "last_sync::$account"
    }
}
