package dev.kaizen.app.settings

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dev.kaizen.app.net.AppDevice
import dev.kaizen.app.net.FetchResult
import dev.kaizen.app.net.KaizenApi
import dev.kaizen.app.net.SecureStore
import dev.kaizen.app.net.ServerConfig
import dev.kaizen.app.ui.theme.themes.KaizenThemeId
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

enum class AppAppearance { Light, Dark, System }

class SettingsViewModel(private val store: SecureStore? = null) : ViewModel() {

    private val _selectedTheme = MutableStateFlow(
        store?.loadThemeId()?.let { KaizenThemeId.fromString(it) } ?: KaizenThemeId.AMBER
    )
    val selectedTheme: StateFlow<KaizenThemeId> = _selectedTheme.asStateFlow()

    private val _appearanceMode = MutableStateFlow(
        store?.loadAppearance()?.let { runCatching { AppAppearance.valueOf(it) }.getOrNull() } ?: AppAppearance.System
    )
    val appearanceMode: StateFlow<AppAppearance> = _appearanceMode.asStateFlow()

    private val _userName = MutableStateFlow(store?.loadUserName() ?: "")
    val userName: StateFlow<String> = _userName.asStateFlow()

    private val _userEmail = MutableStateFlow("")
    val userEmail: StateFlow<String> = _userEmail.asStateFlow()

    private val _locale = MutableStateFlow(store?.loadLocale() ?: "system")
    val locale: StateFlow<String> = _locale.asStateFlow()

    fun selectTheme(themeId: KaizenThemeId) {
        _selectedTheme.value = themeId
        store?.saveThemeId(themeId.value)
    }

    fun selectAppearance(mode: AppAppearance) {
        _appearanceMode.value = mode
        store?.saveAppearance(mode.name)
    }

    fun updateUserName(name: String) {
        if (name.isNotBlank()) {
            _userName.value = name.trim()
            store?.saveUserName(name.trim())
        }
    }

    fun updateUserEmail(email: String) {
        _userEmail.value = email
    }

    fun selectLocale(locale: String, activity: android.app.Activity? = null) {
        _locale.value = locale
        store?.saveLocale(locale)
        val localeList = if (locale == "system") {
            android.os.LocaleList.getDefault()
        } else {
            android.os.LocaleList(java.util.Locale.forLanguageTag(locale))
        }
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
            activity?.getSystemService(android.app.LocaleManager::class.java)?.applicationLocales = localeList
        } else {
            val config = android.content.res.Configuration(activity?.resources?.configuration)
            config.setLocales(localeList)
            @Suppress("DEPRECATION")
            activity?.resources?.updateConfiguration(config, activity.resources.displayMetrics)
            activity?.recreate()
        }
    }

    // ── Security ────────────────────────────────────────────────────────────

    private val _biometricEnabled = MutableStateFlow(store?.loadBiometricEnabled() ?: true)
    val biometricEnabled: StateFlow<Boolean> = _biometricEnabled.asStateFlow()

    private val _devices = MutableStateFlow<List<AppDevice>>(emptyList())
    val devices: StateFlow<List<AppDevice>> = _devices.asStateFlow()

    private val _devicesLoading = MutableStateFlow(false)
    val devicesLoading: StateFlow<Boolean> = _devicesLoading.asStateFlow()

    private val _passwordChangeResult = MutableStateFlow<String?>(null)
    val passwordChangeResult: StateFlow<String?> = _passwordChangeResult.asStateFlow()

    fun setBiometricEnabled(enabled: Boolean) {
        _biometricEnabled.value = enabled
        store?.saveBiometricEnabled(enabled)
    }

    fun loadDevices(config: ServerConfig) {
        viewModelScope.launch {
            _devicesLoading.value = true
            _devices.value = KaizenApi.fetchDevices(config.baseUrl, config.token)
            _devicesLoading.value = false
        }
    }

    fun revokeDevice(config: ServerConfig, deviceId: String) {
        viewModelScope.launch {
            if (KaizenApi.revokeDevice(config.baseUrl, config.token, deviceId)) {
                _devices.value = _devices.value.filter { it.id != deviceId }
            }
        }
    }

    fun changePassword(config: ServerConfig, currentPassword: String, newPassword: String) {
        viewModelScope.launch {
            _passwordChangeResult.value = null
            when (val r = KaizenApi.changePassword(config.baseUrl, config.token, currentPassword, newPassword)) {
                is FetchResult.Ok -> _passwordChangeResult.value = "ok"
                is FetchResult.Fail -> _passwordChangeResult.value = r.reason
            }
        }
    }

    fun clearPasswordResult() { _passwordChangeResult.value = null }
}
