package com.seven.ikar.kotlin.core.settings

import android.content.Context
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow

enum class AppThemeMode {
    System,
    Light,
    Dark,
    Auto
}

enum class AppLanguageMode {
    System,
    Russian,
    English
}

enum class AppProxyType {
    Socks5,
    MtProto,
    Http
}

data class AppSettingsSnapshot(
    val autoDownloadPhotos: Boolean = true,
    val autoDownloadVideosOnWifi: Boolean = false,
    val autoDownloadFilesOnWifi: Boolean = false,
    val saveMediaToGallery: Boolean = false,
    val lowDataCalls: Boolean = false,
    val keepMediaDays: Int = 30,
    val maxCacheMb: Int = 512,
    val themeMode: AppThemeMode = AppThemeMode.System,
    val accentColorName: String = "Telegram Blue",
    val animatedBackgrounds: Boolean = true,
    val largeEmoji: Boolean = true,
    val languageMode: AppLanguageMode = AppLanguageMode.System,
    val proxyEnabled: Boolean = false,
    val proxyType: AppProxyType = AppProxyType.Socks5,
    val proxyHost: String = "",
    val proxyPort: Int = 1080,
    val proxySecret: String = ""
)

class AndroidAppSettings(context: Context) {
    private val preferences = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE)
    private val _snapshot = MutableStateFlow(loadSnapshot())
    val snapshot: StateFlow<AppSettingsSnapshot> = _snapshot.asStateFlow()

    fun loadSnapshot(): AppSettingsSnapshot =
        AppSettingsSnapshot(
            autoDownloadPhotos = preferences.getBoolean(KEY_AUTO_DOWNLOAD_PHOTOS, true),
            autoDownloadVideosOnWifi = preferences.getBoolean(KEY_AUTO_DOWNLOAD_VIDEOS_ON_WIFI, false),
            autoDownloadFilesOnWifi = preferences.getBoolean(KEY_AUTO_DOWNLOAD_FILES_ON_WIFI, false),
            saveMediaToGallery = preferences.getBoolean(KEY_SAVE_MEDIA_TO_GALLERY, false),
            lowDataCalls = preferences.getBoolean(KEY_LOW_DATA_CALLS, false),
            keepMediaDays = preferences.getInt(KEY_KEEP_MEDIA_DAYS, 30).coerceIn(1, 365),
            maxCacheMb = preferences.getInt(KEY_MAX_CACHE_MB, 512).coerceIn(64, 8192),
            themeMode = getEnum(KEY_THEME_MODE, AppThemeMode.System),
            accentColorName = preferences.getString(KEY_ACCENT_COLOR_NAME, "Telegram Blue").orEmpty()
                .ifBlank { "Telegram Blue" },
            animatedBackgrounds = preferences.getBoolean(KEY_ANIMATED_BACKGROUNDS, true),
            largeEmoji = preferences.getBoolean(KEY_LARGE_EMOJI, true),
            languageMode = getEnum(KEY_LANGUAGE_MODE, AppLanguageMode.System),
            proxyEnabled = preferences.getBoolean(KEY_PROXY_ENABLED, false),
            proxyType = getEnum(KEY_PROXY_TYPE, AppProxyType.Socks5),
            proxyHost = preferences.getString(KEY_PROXY_HOST, "").orEmpty(),
            proxyPort = preferences.getInt(KEY_PROXY_PORT, 1080).coerceIn(1, 65_535),
            proxySecret = preferences.getString(KEY_PROXY_SECRET, "").orEmpty()
        )

    fun update(transform: (AppSettingsSnapshot) -> AppSettingsSnapshot) {
        saveSnapshot(transform(_snapshot.value))
    }

    fun saveSnapshot(snapshot: AppSettingsSnapshot) {
        val sanitized = snapshot.copy(
            keepMediaDays = snapshot.keepMediaDays.coerceIn(1, 365),
            maxCacheMb = snapshot.maxCacheMb.coerceIn(64, 8192),
            proxyPort = snapshot.proxyPort.coerceIn(1, 65_535)
        )
        preferences.edit().apply {
            putBoolean(KEY_AUTO_DOWNLOAD_PHOTOS, sanitized.autoDownloadPhotos)
            putBoolean(KEY_AUTO_DOWNLOAD_VIDEOS_ON_WIFI, sanitized.autoDownloadVideosOnWifi)
            putBoolean(KEY_AUTO_DOWNLOAD_FILES_ON_WIFI, sanitized.autoDownloadFilesOnWifi)
            putBoolean(KEY_SAVE_MEDIA_TO_GALLERY, sanitized.saveMediaToGallery)
            putBoolean(KEY_LOW_DATA_CALLS, sanitized.lowDataCalls)
            putInt(KEY_KEEP_MEDIA_DAYS, sanitized.keepMediaDays)
            putInt(KEY_MAX_CACHE_MB, sanitized.maxCacheMb)
            putString(KEY_THEME_MODE, sanitized.themeMode.name)
            putString(KEY_ACCENT_COLOR_NAME, sanitized.accentColorName)
            putBoolean(KEY_ANIMATED_BACKGROUNDS, sanitized.animatedBackgrounds)
            putBoolean(KEY_LARGE_EMOJI, sanitized.largeEmoji)
            putString(KEY_LANGUAGE_MODE, sanitized.languageMode.name)
            putBoolean(KEY_PROXY_ENABLED, sanitized.proxyEnabled)
            putString(KEY_PROXY_TYPE, sanitized.proxyType.name)
            putString(KEY_PROXY_HOST, sanitized.proxyHost)
            putInt(KEY_PROXY_PORT, sanitized.proxyPort)
            putString(KEY_PROXY_SECRET, sanitized.proxySecret)
            apply()
        }
        _snapshot.value = sanitized
    }

    fun reset() {
        preferences.edit().clear().apply()
        _snapshot.value = AppSettingsSnapshot()
    }

    private fun <T : Enum<T>> getEnum(key: String, defaultValue: T): T {
        val rawValue = preferences.getString(key, defaultValue.name).orEmpty()
        @Suppress("UNCHECKED_CAST")
        return defaultValue.declaringJavaClass.enumConstants
            ?.firstOrNull { it.name == rawValue } as? T
            ?: defaultValue
    }

    companion object {
        private const val PREFERENCES_NAME = "ikar_kotlin_app_settings"
        private const val KEY_AUTO_DOWNLOAD_PHOTOS = "auto_download_photos"
        private const val KEY_AUTO_DOWNLOAD_VIDEOS_ON_WIFI = "auto_download_videos_on_wifi"
        private const val KEY_AUTO_DOWNLOAD_FILES_ON_WIFI = "auto_download_files_on_wifi"
        private const val KEY_SAVE_MEDIA_TO_GALLERY = "save_media_to_gallery"
        private const val KEY_LOW_DATA_CALLS = "low_data_calls"
        private const val KEY_KEEP_MEDIA_DAYS = "keep_media_days"
        private const val KEY_MAX_CACHE_MB = "max_cache_mb"
        private const val KEY_THEME_MODE = "theme_mode"
        private const val KEY_ACCENT_COLOR_NAME = "accent_color_name"
        private const val KEY_ANIMATED_BACKGROUNDS = "animated_backgrounds"
        private const val KEY_LARGE_EMOJI = "large_emoji"
        private const val KEY_LANGUAGE_MODE = "language_mode"
        private const val KEY_PROXY_ENABLED = "proxy_enabled"
        private const val KEY_PROXY_TYPE = "proxy_type"
        private const val KEY_PROXY_HOST = "proxy_host"
        private const val KEY_PROXY_PORT = "proxy_port"
        private const val KEY_PROXY_SECRET = "proxy_secret"
    }
}
