package com.safecheckin.app.data.local

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.*
import androidx.datastore.preferences.preferencesDataStore
import com.safecheckin.app.data.model.Contact
import com.safecheckin.app.data.model.CheckInRecord
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.serialization.encodeToString
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json

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

class LocalDataSource(private val context: Context) {

    companion object {
        val CHECK_INS_KEY = stringPreferencesKey("check_ins")
        val CONTACTS_KEY = stringPreferencesKey("contacts")
        val PRESET_MESSAGE_KEY = stringPreferencesKey("preset_message")
        val GRACE_PERIOD_HOURS_KEY = intPreferencesKey("grace_period_hours")
        val GRACE_PERIOD_MINUTES_KEY = intPreferencesKey("grace_period_minutes")
        val SMTP_HOST_KEY = stringPreferencesKey("smtp_host")
        val SMTP_PORT_KEY = intPreferencesKey("smtp_port")
        val SMTP_USERNAME_KEY = stringPreferencesKey("smtp_username")
        val SMTP_PASSWORD_KEY = stringPreferencesKey("smtp_password")
        val SMTP_SECURITY_KEY = stringPreferencesKey("smtp_security")
        
        private val json = Json { ignoreUnknownKeys = true }
        const val DEFAULT_PRESET_MESSAGE = "如果你收到这条消息，说明我可能出事了，请尽快联系我或报警。"
    }

    // Check-ins
    val checkIns: Flow<List<CheckInRecord>> = context.dataStore.data.map { prefs ->
        prefs[CHECK_INS_KEY]?.let { json.decodeFromString(it) } ?: emptyList()
    }

    suspend fun addCheckIn(record: CheckInRecord) {
        context.dataStore.edit { prefs ->
            val current = prefs[CHECK_INS_KEY]?.let { json.decodeFromString<List<CheckInRecord>>(it) } ?: emptyList()
            val updated = current + record
            prefs[CHECK_INS_KEY] = json.encodeToString(updated)
        }
    }

    // Contacts
    val contacts: Flow<List<Contact>> = context.dataStore.data.map { prefs ->
        prefs[CONTACTS_KEY]?.let { json.decodeFromString(it) } ?: emptyList()
    }

    suspend fun addContact(contact: Contact) {
        context.dataStore.edit { prefs ->
            val current = prefs[CONTACTS_KEY]?.let { json.decodeFromString<List<Contact>>(it) } ?: emptyList()
            val updated = current + contact
            prefs[CONTACTS_KEY] = json.encodeToString(updated)
        }
    }

    suspend fun updateContact(updatedContact: Contact) {
        context.dataStore.edit { prefs ->
            val current = prefs[CONTACTS_KEY]?.let { json.decodeFromString<List<Contact>>(it) } ?: emptyList()
            val updated = current.map { if (it.id == updatedContact.id) updatedContact else it }
            prefs[CONTACTS_KEY] = json.encodeToString(updated)
        }
    }

    suspend fun deleteContact(contact: Contact) {
        context.dataStore.edit { prefs ->
            val current = prefs[CONTACTS_KEY]?.let { json.decodeFromString<List<Contact>>(it) } ?: emptyList()
            val updated = current.filter { it.id != contact.id }
            prefs[CONTACTS_KEY] = json.encodeToString(updated)
        }
    }

    // Settings
    val presetMessage: Flow<String> = context.dataStore.data.map { it[PRESET_MESSAGE_KEY] ?: DEFAULT_PRESET_MESSAGE }
    val gracePeriodHours: Flow<Int> = context.dataStore.data.map { it[GRACE_PERIOD_HOURS_KEY] ?: 24 }
    val gracePeriodMinutes: Flow<Int> = context.dataStore.data.map { it[GRACE_PERIOD_MINUTES_KEY] ?: 0 }
    
    suspend fun setPresetMessage(message: String) {
        context.dataStore.edit { it[PRESET_MESSAGE_KEY] = message }
    }
    
    suspend fun setGracePeriod(hours: Int, minutes: Int) {
        context.dataStore.edit { 
            it[GRACE_PERIOD_HOURS_KEY] = hours
            it[GRACE_PERIOD_MINUTES_KEY] = minutes
        }
    }

    // SMTP Settings
    val smtpHost: Flow<String> = context.dataStore.data.map { it[SMTP_HOST_KEY] ?: "" }
    val smtpPort: Flow<Int> = context.dataStore.data.map { it[SMTP_PORT_KEY] ?: 587 }
    val smtpUsername: Flow<String> = context.dataStore.data.map { it[SMTP_USERNAME_KEY] ?: "" }
    val smtpPassword: Flow<String> = context.dataStore.data.map { it[SMTP_PASSWORD_KEY] ?: "" }
    val smtpSecurity: Flow<String> = context.dataStore.data.map { it[SMTP_SECURITY_KEY] ?: "TLS" }

    suspend fun setSmtpConfig(host: String, port: Int, username: String, password: String, security: String) {
        context.dataStore.edit { prefs ->
            prefs[SMTP_HOST_KEY] = host
            prefs[SMTP_PORT_KEY] = port
            prefs[SMTP_USERNAME_KEY] = username
            prefs[SMTP_PASSWORD_KEY] = password
            prefs[SMTP_SECURITY_KEY] = security
        }
    }
}