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 = ""
    private var _theme: Int? = null
    private var _enableAnalytics: Boolean? = null


    init {
        refreshApiSettings()
        refreshUserSettings()
    }

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

    private fun refreshApiVersion() {
        _apiVersion = settings.getInt(API_VERSION_MAJOR, -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!!
    }

    private fun refreshItemsNumber() {
        _itemsNumber = settings.getString(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(BASE_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 != 360L) {
            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 refreshAnalyticsEnabled() {
        _enableAnalytics = settings.getBoolean(ENABLE_ANALYTICS, true)
    }

    fun isAnalyticsEnabled(): Boolean {
        if (_enableAnalytics != null) {
            refreshAnalyticsEnabled()
        }
        return _enableAnalytics == true
    }

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

    fun getFont(): String {
        if (_font.isEmpty()) {
            refreshFont()
        }
        return _font
    }

    private fun refreshCurrentTheme() {
        _theme = settings.getString(CURRENT_THEME, "-1").toInt()
    }

    fun getCurrentTheme(): Int {
        if (_theme == null) {
            refreshCurrentTheme()
        }
        return _theme ?: -1
    }

    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()
        refreshCurrentTheme()
        refreshAnalyticsEnabled()
    }

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

    fun resetLoginInformation() {
        settings.remove(BASE_URL)
        settings.remove(LOGIN)
        settings.remove(PASSWORD)
        refreshApiSettings()
    }

    fun updateApiVersion(apiMajorVersion: Int) {
        settings.putInt(API_VERSION_MAJOR, 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

        const val API_VERSION_MAJOR = "apiVersionMajor"

        const val API_ITEMS_NUMBER = "prefer_api_items_number"

        const val API_TIMEOUT = "api_timeout"

        const val BASE_URL = "url"

        const val LOGIN = "login"

        const val PASSWORD = "password"

        const val PREFER_ARTICLE_VIEWER = "prefer_article_viewer"

        const val CARD_VIEW_ACTIVE = "card_view_active"

        const val DISPLAY_UNREAD_COUNT = "display_unread_count"

        const val DISPLAY_OTHER_COUNT = "display_other_count"

        const val FULL_HEIGHT_CARDS = "full_height_cards"

        const val UPDATE_SOURCES = "update_sources"

        const val PERIODIC_REFRESH = "periodic_refresh"

        const val REFRESH_WHEN_CHARGING = "refresh_when_charging"

        const val READER_FONT = "reader_font"

        const val READER_STATIC_BAR = "reader_static_bar"

        const val READER_FONT_SIZE = "reader_font_size"

        const val TEXT_ALIGN = "text_align"

        const val MARK_ON_SCROLL = "mark_on_scroll"

        const val NOTIFY_NEW_ITEMS = "notify_new_items"

        const val PERIODIC_REFRESH_MINUTES = "periodic_refresh_minutes"

        const val HIDDEN_TAGS = "hidden_tags"

        const val INFINITE_LOADING = "infinite_loading"

        const val ITEMS_CACHING = "items_caching"

        const val CURRENT_THEME = "currentMode"

        const val ENABLE_ANALYTICS = "enable_analytics"
    }
}