package com.safecheckin.app.ui.screens.home

import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.safecheckin.app.data.repository.CloudRepository
import com.safecheckin.app.service.CheckInNotificationService
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
import java.util.*

data class HomeUiState(
    val isLoading: Boolean = true,
    val isCheckedInToday: Boolean = false,
    val lastCheckInTime: String = "",
    val checkInCount: Int = 0,
    val consecutiveDays: Int = 0,
    val gracePeriodHours: Int = 24,
    val gracePeriodMinutes: Int = 0,
    val presetMessage: String = "如果你收到这条消息，说明我可能出事了，请尽快联系我或报警。",
    val isServiceRunning: Boolean = true,
    val errorMessage: String? = null
)

/**
 * v1: 统一使用云端数据，所有数据每次进入页面都从服务器拉取
 * 打卡完成后立即上传至服务器，并重新刷新云端数据
 */
class HomeViewModel(
    private val repository: CloudRepository,
    private val context: Context
) : ViewModel() {

    private val _uiState = MutableStateFlow(HomeUiState())
    val uiState: StateFlow<HomeUiState> = _uiState.asStateFlow()

    init {
        loadData()
    }

    fun loadData() {
        viewModelScope.launch {
            _uiState.update { it.copy(isLoading = true, errorMessage = null) }
            try {
                // 一次性从云端拉取所有数据
                val userStats = repository.getUserStats()
                val checkIns = repository.getCheckIns()
                val gracePeriod = repository.getGracePeriod()

                val checkInCount = (userStats["check_in_count"] as? Int) ?: 0
                val lastCheckInStr = (userStats["last_check_in"] as? String) ?: ""
                val gracePeriodHours = gracePeriod.first
                val gracePeriodMinutes = gracePeriod.second
                val presetMessage = (userStats["preset_message"] as? String)
                    ?: "如果你收到这条消息，说明我可能出事了，请尽快联系我或报警。"

                // 判断今天是否已打卡
                val today = Calendar.getInstance().apply {
                    set(Calendar.HOUR_OF_DAY, 0); set(Calendar.MINUTE, 0)
                    set(Calendar.SECOND, 0); set(Calendar.MILLISECOND, 0)
                }.timeInMillis

                val isCheckedInToday = checkIns.any { record ->
                    val cal = Calendar.getInstance().apply { timeInMillis = record.timestamp }
                    cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0)
                    cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0)
                    cal.timeInMillis == today
                }

                // 格式化最后打卡时间
                val lastCheckInTime = if (lastCheckInStr.isNotBlank()) {
                    try {
                        val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
                        val date = sdf.parse(lastCheckInStr)
                        if (date != null) SimpleDateFormat("MM-dd HH:mm", Locale.getDefault()).format(date) else ""
                    } catch (e: Exception) { lastCheckInStr }
                } else ""

                // 计算连续打卡天数
                val consecutiveDays = calculateConsecutiveDays(checkIns)

                _uiState.update {
                    it.copy(
                        isLoading = false,
                        isCheckedInToday = isCheckedInToday,
                        lastCheckInTime = lastCheckInTime,
                        checkInCount = checkInCount,
                        consecutiveDays = consecutiveDays,
                        gracePeriodHours = gracePeriodHours,
                        gracePeriodMinutes = gracePeriodMinutes,
                        presetMessage = presetMessage,
                        errorMessage = null
                    )
                }
            } catch (e: Exception) {
                e.printStackTrace()
                _uiState.update {
                    it.copy(isLoading = false, errorMessage = "加载数据失败: ${e.message}")
                }
            }
        }
    }

    /**
     * 打卡：上传至服务器，成功后刷新云端数据
     */
    fun checkIn(note: String = "") {
        viewModelScope.launch {
            _uiState.update { it.copy(isLoading = true, errorMessage = null) }
            try {
                val success = repository.insertCheckIn(note)
                if (success) {
                    loadData()
                } else {
                    _uiState.update {
                        it.copy(isLoading = false, errorMessage = "打卡失败，请检查网络连接")
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
                _uiState.update {
                    it.copy(isLoading = false, errorMessage = "打卡失败: ${e.message}")
                }
            }
        }
    }

    fun startService() {
        CheckInNotificationService.start(context)
        _uiState.update { it.copy(isServiceRunning = true) }
    }

    fun stopService() {
        CheckInNotificationService.stop(context)
        _uiState.update { it.copy(isServiceRunning = false) }
    }

    fun sendTestNotification() {
        CheckInNotificationService.sendTestNotification(context)
    }

    fun clearError() {
        _uiState.update { it.copy(errorMessage = null) }
    }

    private fun calculateConsecutiveDays(checkIns: List<com.safecheckin.app.data.model.CheckInRecord>): Int {
        if (checkIns.isEmpty()) return 0
        val dates = checkIns.map { record ->
            Calendar.getInstance().apply {
                timeInMillis = record.timestamp
                set(Calendar.HOUR_OF_DAY, 0); set(Calendar.MINUTE, 0)
                set(Calendar.SECOND, 0); set(Calendar.MILLISECOND, 0)
            }.timeInMillis
        }.distinct().sortedDescending()

        val today = Calendar.getInstance().apply {
            set(Calendar.HOUR_OF_DAY, 0); set(Calendar.MINUTE, 0)
            set(Calendar.SECOND, 0); set(Calendar.MILLISECOND, 0)
        }.timeInMillis

        if (dates.firstOrNull() != today) {
            val yesterday = today - 86400000L
            if (dates.firstOrNull() != yesterday) return 0
        }

        var consecutive = 1
        for (i in 1 until dates.size) {
            if (dates[i] == dates[i - 1] - 86400000L) consecutive++ else break
        }
        return consecutive
    }

    class Factory(private val context: Context) : ViewModelProvider.Factory {
        @Suppress("UNCHECKED_CAST")
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return HomeViewModel(CloudRepository(context), context) as T
        }
    }
}
