package com.example.ops_android.data.local

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import com.example.ops_android.data.model.Cookie
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "ops_settings")

class SessionManager(private val context: Context) {

    companion object {
        private val KEY_API_BASE_URL = stringPreferencesKey("api_base_url")
        private val KEY_COOKIE_VALUE = stringPreferencesKey("cookie_value")
        private val KEY_COOKIE_NAME = stringPreferencesKey("cookie_name")
        private val KEY_COOKIE_EXPIRES_AT = stringPreferencesKey("cookie_expires_at")
        private val KEY_COOKIE_REMEMBER = booleanPreferencesKey("cookie_remember")
        private val KEY_PRINTER_BLACK_MARK = booleanPreferencesKey("printer_black_mark")
        private val KEY_PRINTER_UNWIND_MM = intPreferencesKey("printer_unwind_mm")
        private val KEY_LABEL_WIDTH_MM = intPreferencesKey("label_width_mm")
        private val KEY_LABEL_HEIGHT_MM = intPreferencesKey("label_height_mm")
        private val KEY_PRINT_RETRACT_MM = intPreferencesKey("print_retract_mm")
    }

    @Volatile
    var cachedBaseUrl: String = ""
        private set

    @Volatile
    var cachedCookieValue: String = ""
        private set

    @Volatile
    var cachedBlackMarkEnabled: Boolean = true
        private set

    @Volatile
    var cachedUnwindMm: Int = 40
        private set

    @Volatile
    var cachedLabelWidthMm: Int = 53
        private set

    @Volatile
    var cachedLabelHeightMm: Int = 40
        private set

    @Volatile
    var cachedPrintRetractMm: Int = 10
        private set

    fun clearCookieCache() {
        cachedCookieValue = ""
    }

    val apiBaseUrl: Flow<String> = context.dataStore.data.map { prefs -> prefs[KEY_API_BASE_URL] ?: "" }
    val cookieValue: Flow<String> = context.dataStore.data.map { prefs -> prefs[KEY_COOKIE_VALUE] ?: "" }

    suspend fun init() {
        val prefs = context.dataStore.data.first()
        cachedBaseUrl = prefs[KEY_API_BASE_URL] ?: ""
        cachedCookieValue = prefs[KEY_COOKIE_VALUE] ?: ""
        cachedBlackMarkEnabled = prefs[KEY_PRINTER_BLACK_MARK] ?: true
        cachedUnwindMm = prefs[KEY_PRINTER_UNWIND_MM] ?: 40
        cachedLabelWidthMm = prefs[KEY_LABEL_WIDTH_MM] ?: 53
        cachedLabelHeightMm = prefs[KEY_LABEL_HEIGHT_MM] ?: 40
        cachedPrintRetractMm = prefs[KEY_PRINT_RETRACT_MM] ?: 10
    }

    suspend fun getApiBaseUrl(): String = cachedBaseUrl.ifEmpty {
        context.dataStore.data.first()[KEY_API_BASE_URL]?.also { cachedBaseUrl = it } ?: ""
    }

    suspend fun setApiBaseUrl(url: String) {
        cachedBaseUrl = url
        context.dataStore.edit { it[KEY_API_BASE_URL] = url }
    }

    suspend fun getCookieValue(): String = cachedCookieValue

    suspend fun saveCookie(cookie: Cookie) {
        cachedCookieValue = cookie.value ?: ""
        context.dataStore.edit {
            it[KEY_COOKIE_VALUE] = cookie.value ?: ""
            it[KEY_COOKIE_NAME] = cookie.name ?: ""
            it[KEY_COOKIE_EXPIRES_AT] = cookie.expiresAt ?: ""
            it[KEY_COOKIE_REMEMBER] = cookie.remember
        }
    }

    suspend fun clearCookie() {
        cachedCookieValue = ""
        context.dataStore.edit {
            it.remove(KEY_COOKIE_VALUE)
            it.remove(KEY_COOKIE_NAME)
            it.remove(KEY_COOKIE_EXPIRES_AT)
            it.remove(KEY_COOKIE_REMEMBER)
        }
    }

    suspend fun isCookieExpired(): Boolean {
        val expiresAt = context.dataStore.data.first()[KEY_COOKIE_EXPIRES_AT] ?: return true
        return try {
            SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US).parse(expiresAt)?.before(Date()) ?: true
        } catch (e: Exception) { true }
    }

    suspend fun isLoggedIn(): Boolean {
        if (cachedCookieValue.isEmpty()) return false
        return !isCookieExpired()
    }

    suspend fun logout() = clearCookie()

    suspend fun setBlackMarkEnabled(enabled: Boolean) {
        cachedBlackMarkEnabled = enabled
        context.dataStore.edit { it[KEY_PRINTER_BLACK_MARK] = enabled }
    }

    suspend fun setUnwindMm(mm: Int) {
        cachedUnwindMm = mm
        context.dataStore.edit { it[KEY_PRINTER_UNWIND_MM] = mm }
    }

    suspend fun setLabelWidthMm(mm: Int) {
        cachedLabelWidthMm = mm
        context.dataStore.edit { it[KEY_LABEL_WIDTH_MM] = mm }
    }

    suspend fun setLabelHeightMm(mm: Int) {
        cachedLabelHeightMm = mm
        context.dataStore.edit { it[KEY_LABEL_HEIGHT_MM] = mm }
    }

    suspend fun setPrintRetractMm(mm: Int) {
        cachedPrintRetractMm = mm
        context.dataStore.edit { it[KEY_PRINT_RETRACT_MM] = mm }
    }
}
