package bou.amine.apps.readerforselfossv2.service

import com.russhwolf.settings.Settings
import io.github.aakira.napier.Napier
import io.ktor.client.plugins.*

class AppSettingsService {
    val settings: Settings = Settings()

    // Api related
    private var _apiVersion: Int = -1
    private var _baseUrl: String = ""
    private var _userName: String = ""
    private var _password: String = ""

    // User settings related
    private var _itemsCaching: Boolean? = null
    private var _articleViewer: Boolean? = null
    private var _shouldBeCardView: Boolean? = null
    private var _displayUnreadCount: Boolean? = null
    private var _displayAllCount: Boolean? = null
    private var _fullHeightCards: Boolean? = null
    private var _updateSources: Boolean? = null
    private var _periodicRefresh: Boolean? = null
    private var _refreshWhenChargingOnly: Boolean? = null
    private var _infiniteLoading: Boolean? = null
    private var _notifyNewItems: Boolean? = null
    private var _itemsNumber: Int? = null
    private var _apiTimeout: Long? = null
    private var _hiddenTags: List<String>? = null
    private var _refreshMinutes: Long = 360
    private var _markOnScroll: Boolean? = null
    private var _activeAlignment: Int? = null

    private var _fontSize: Int? = null
    private var _staticBar: Boolean? = null
    private var _font: String = ""


    init {
        refreshApiSettings()
        refreshUserSettings()
    }

    fun logApiCalls(message: String) {
        Napier.d(message, tag = "LogApiCalls")
    }

    fun getApiVersion(): Int {
        if (_apiVersion == -1) {
            refreshApiVersion()
            return _apiVersion
        }
        return _apiVersion
    }

    fun refreshApiVersion() {
        _apiVersion = settings.getInt("apiVersionMajor", -1)
    }

    fun getBaseUrl(): String {
        if (_baseUrl.isEmpty()) {
            refreshBaseUrl()
        }
        return _baseUrl
    }

    fun getUserName(): String {
        if (_userName.isEmpty()) {
            refreshUsername()
        }
        return _userName
    }

    fun getPassword(): String {
        if (_password.isEmpty()) {
            refreshPassword()
        }
        return _password
    }

    fun getItemsNumber(): Int {
        if (_itemsNumber == null) {
            refreshItemsNumber()
        }
        return _itemsNumber!!
    }

    fun refreshItemsNumber() {
        _itemsNumber = settings.getString("prefer_api_items_number", "20").toInt()
    }

    fun getApiTimeout(): Long {
        if (_apiTimeout == null) {
            refreshApiTimeout()
        }
        return _apiTimeout!!
    }

    private fun refreshApiTimeout() {
        val settingsTimeout = settings.getLong("api_timeout", HttpTimeout.INFINITE_TIMEOUT_MS)
        _apiTimeout = if (settingsTimeout > 0) settingsTimeout else HttpTimeout.INFINITE_TIMEOUT_MS
    }

    private fun refreshBaseUrl() {
        _baseUrl = settings.getString("url", "")
    }

    private fun refreshUsername() {
        _userName = settings.getString("login", "")
    }

    private fun refreshPassword() {
        _password = settings.getString("password", "")
    }

    private fun refreshArticleViewerEnabled() {
        _articleViewer = settings.getBoolean("prefer_article_viewer", true)
    }

    fun isArticleViewerEnabled(): Boolean {
        if (_articleViewer != null) {
            refreshArticleViewerEnabled()
        }
        return _articleViewer == true
    }
    private fun refreshShouldBeCardViewEnabled() {
        _shouldBeCardView = settings.getBoolean("card_view_active", false)
    }

    fun isCardViewEnabled(): Boolean {
        if (_shouldBeCardView != null) {
            refreshShouldBeCardViewEnabled()
        }
        return _shouldBeCardView == true
    }
    private fun refreshDisplayUnreadCountEnabled() {
        _displayUnreadCount = settings.getBoolean("display_unread_count", true)
    }

    fun isDisplayUnreadCountEnabled(): Boolean {
        if (_displayUnreadCount != null) {
            refreshDisplayUnreadCountEnabled()
        }
        return _displayUnreadCount == true
    }
    private fun refreshDisplayAllCountEnabled() {
        _displayAllCount = settings.getBoolean("display_other_count", false)
    }

    fun isDisplayAllCountEnabled(): Boolean {
        if (_displayAllCount != null) {
            refreshDisplayAllCountEnabled()
        }
        return _displayAllCount == true
    }
    private fun refreshFullHeightCardsEnabled() {
        _fullHeightCards = settings.getBoolean("full_height_cards", false)
    }

    fun isFullHeightCardsEnabled(): Boolean {
        if (_fullHeightCards != null) {
            refreshFullHeightCardsEnabled()
        }
        return _fullHeightCards == true
    }
    private fun refreshUpdateSourcesEnabled() {
        _updateSources = settings.getBoolean("update_sources", true)
    }

    fun isUpdateSourcesEnabled(): Boolean {
        if (_updateSources != null) {
            refreshUpdateSourcesEnabled()
        }
        return _updateSources == true
    }
    private fun refreshPeriodicRefreshEnabled() {
        _periodicRefresh = settings.getBoolean("periodic_refresh", false)
    }

    fun isPeriodicRefreshEnabled(): Boolean {
        if (_periodicRefresh != null) {
            refreshPeriodicRefreshEnabled()
        }
        return _periodicRefresh == true
    }

    private fun refreshRefreshWhenChargingOnlyEnabled() {
        _refreshWhenChargingOnly = settings.getBoolean("refresh_when_charging", false)
    }

    fun isRefreshWhenChargingOnlyEnabled(): Boolean {
        if (_refreshWhenChargingOnly != null) {
            refreshRefreshWhenChargingOnlyEnabled()
        }
        return _refreshWhenChargingOnly == true
    }

    private fun refreshRefreshMinutes() {
        _refreshMinutes = settings.getString("periodic_refresh_minutes", "360").toLong()
        if (_refreshMinutes <= 15) {
            _refreshMinutes = 15
        }
    }

    fun getRefreshMinutes(): Long {
        if (_refreshMinutes != null) {
            refreshRefreshMinutes()
        }
        return _refreshMinutes
    }

    private fun refreshHiddenTags() {
        if (settings.getString("hidden_tags", "").isNotEmpty()) {
            _hiddenTags = settings.getString("hidden_tags", "").replace("\\s".toRegex(), "").split(",")
        }
    }

    fun getHiddenTags(): List<String> {
        if (_hiddenTags != null) {
            refreshHiddenTags()
        }
        return _hiddenTags.orEmpty()
    }

    private fun refreshInfiniteLoadingEnabled() {
        _infiniteLoading = settings.getBoolean("infinite_loading", false)
    }

    fun isInfiniteLoadingEnabled(): Boolean {
        if (_infiniteLoading != null) {
            refreshInfiniteLoadingEnabled()
        }
        return _infiniteLoading == true
    }

    private fun refreshItemCachingEnabled() {
        _itemsCaching = settings.getBoolean("items_caching", false)
    }

    fun isItemCachingEnabled(): Boolean {
        if (_itemsCaching != null) {
            refreshItemCachingEnabled()
        }
        return _itemsCaching == true
    }

    private fun refreshNotifyNewItemsEnabled() {
        _notifyNewItems = settings.getBoolean("notify_new_items", false)
    }

    fun isNotifyNewItemsEnabled(): Boolean {
        if (_notifyNewItems != null) {
            refreshNotifyNewItemsEnabled()
        }
        return _notifyNewItems == true
    }


    private fun refreshMarkOnScrollEnabled() {
        _markOnScroll = settings.getBoolean("mark_on_scroll", false)
    }

    fun isMarkOnScrollEnabled(): Boolean {
        if (_markOnScroll != null) {
            refreshMarkOnScrollEnabled()
        }
        return _markOnScroll == true
    }


    private fun refreshActiveAllignment() {
        _activeAlignment = settings.getInt("text_align", JUSTIFY)
    }

    fun getActiveAllignment(): Int {
        if (_activeAlignment != null) {
            refreshActiveAllignment()
        }
        return _activeAlignment ?: JUSTIFY
    }

    fun changeAllignment(allignment: Int) {
        settings.putInt("text_align", allignment)
        _activeAlignment = allignment
    }

    private fun refreshFontSize() {
        _fontSize = settings.getString("reader_font_size", "16").toInt()
    }

    fun getFontSize(): Int {
        if (_fontSize != null) {
            refreshFontSize()
        }
        return _fontSize ?: 16
    }

    private fun refreshStaticBarEnabled() {
        _staticBar = settings.getBoolean("reader_static_bar", false)
    }

    fun isStaticBarEnabled(): Boolean {
        if (_staticBar != null) {
            refreshStaticBarEnabled()
        }
        return _staticBar == true
    }

    private fun refreshFont() {
        _font = settings.getString("reader_font", "")
    }

    fun getFont(): String {
        if (_font != null) {
            refreshFont()
        }
        return _font
    }

    fun refreshApiSettings() {
        refreshPassword()
        refreshUsername()
        refreshBaseUrl()
        refreshApiVersion()
    }

    fun refreshUserSettings() {
        refreshItemsNumber()
        refreshApiTimeout()
        refreshArticleViewerEnabled()
        refreshShouldBeCardViewEnabled()
        refreshDisplayUnreadCountEnabled()
        refreshDisplayAllCountEnabled()
        refreshFullHeightCardsEnabled()
        refreshUpdateSourcesEnabled()
        refreshPeriodicRefreshEnabled()
        refreshRefreshWhenChargingOnlyEnabled()
        refreshRefreshMinutes()
        refreshHiddenTags()
        refreshInfiniteLoadingEnabled()
        refreshItemCachingEnabled()
        refreshNotifyNewItemsEnabled()
        refreshMarkOnScrollEnabled()
        refreshActiveAllignment()
        refreshFontSize()
        refreshFont()
        refreshStaticBarEnabled()
    }

    fun refreshLoginInformation(
        url: String,
        login: String,
        password: String
    ) {
        settings.putString("url", url)
        settings.putString("login", login)
        settings.putString("password", password)
        refreshApiSettings()
    }

    fun resetLoginInformation() {
        settings.remove("url")
        settings.remove("login")
        settings.remove("password")
        refreshApiSettings()
    }

    fun updateApiVersion(apiMajorVersion: Int) {
        settings.putInt("apiVersionMajor", apiMajorVersion)
        refreshApiVersion()
    }

    fun clearAll() {
        settings.clear()
        refreshApiSettings()
        refreshUserSettings()
    }

    fun disableArticleViewer() {
        settings.putBoolean("prefer_article_viewer", false)
        refreshArticleViewerEnabled()
    }

    companion object {
        const val translationUrl = "https://crwd.in/readerforselfoss"

        const val sourceUrl = "https://gitea.amine-louveau.fr/Louvorg/ReaderForSelfoss-multiplatform"

        const val trackerUrl = "https://gitea.amine-louveau.fr/Louvorg/ReaderForSelfoss-multiplatform/issues"

        const val syncChannelId = "sync-channel-id"

        const val newItemsChannelId = "new-items-channel-id"

        const val JUSTIFY = 1

        const val ALIGN_LEFT = 2
    }
}