package com.rugvedsarika.easymath.viewmodel

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.asLiveData
import com.rugvedsarika.easymath.data.db.MathHistoryEntity
import com.rugvedsarika.easymath.data.db.UserEntity
import com.rugvedsarika.easymath.data.repository.MathRepository
import com.rugvedsarika.easymath.model.Question
import com.rugvedsarika.easymath.utils.MathGenerator
import kotlinx.coroutines.launch
import android.os.CountDownTimer

import com.rugvedsarika.easymath.utils.AudioManager

class MathViewModel(private val repository: MathRepository, private val audioManager: AudioManager) : ViewModel() {

    private val _currentQuestion = MutableLiveData<Question>()
    val currentQuestion: LiveData<Question> = _currentQuestion

    private val _score = MutableLiveData(0)
    val score: LiveData<Int> = _score

    private val _totalQuestions = MutableLiveData(0)
    val totalQuestions: LiveData<Int> = _totalQuestions

    // Timer logic
    private var timer: CountDownTimer? = null
    private val _timeLeft = MutableLiveData<Long>()
    val timeLeft: LiveData<Long> = _timeLeft
    private val _isGameFinished = MutableLiveData<Boolean>()
    val isGameFinished: LiveData<Boolean> = _isGameFinished

    private var currentCategory: String = "Addition"
    private var currentLevel: String = "Easy"
    var isExamMode: Boolean = false

    fun startGame(category: String, level: String, durationInMillis: Long? = null) {
        currentCategory = category
        currentLevel = level
        isExamMode = (category == "Exam")
        
        _score.value = 0
        _totalQuestions.value = 0
        _isGameFinished.value = false
        
        loadNextQuestion()

        if (durationInMillis != null) {
            startTimer(durationInMillis)
        }
    }

    private fun startTimer(duration: Long) {
        timer?.cancel()
        timer = object : CountDownTimer(duration, 1000) {
            override fun onTick(millisUntilFinished: Long) {
                _timeLeft.value = millisUntilFinished / 1000
            }

            override fun onFinish() {
                _timeLeft.value = 0
                _isGameFinished.value = true
                saveSession()
            }
        }.start()
    }

    override fun onCleared() {
        super.onCleared()
        timer?.cancel()
    }

    fun loadNextQuestion() {
        if (_isGameFinished.value == true) return
        val q = MathGenerator.generateQuestion(currentCategory, currentLevel)
        _currentQuestion.value = q
        
        // Speak question logic: e.g. "What is 5 plus 3?" from "5 + 3 = ?"
        val speakText = q.text.replace("?", "").trim() // Simple heuristic
        audioManager.speak(speakText)
    }

    fun checkAnswer(userAnswer: Int): Boolean {
        if (_isGameFinished.value == true) return false
        val correct = _currentQuestion.value?.correctAnswer == userAnswer
        if (correct) {
            _score.value = (_score.value ?: 0) + 1
            if (!isExamMode) audioManager.playCorrectSound()
        } else {
            if (!isExamMode) audioManager.playWrongSound()
        }
        _totalQuestions.value = (_totalQuestions.value ?: 0) + 1
        return correct
    }

    // User Session
    private var currentUserId: Int = 1 // Default

    val allUsers: LiveData<List<UserEntity>> = repository.allUsers.asLiveData()

    // We need to switch history when user changes. 
    // For simplicity, let's just expose a function to get history for current user
    // or better, use a transformation switchMap if we had LiveData for userId.
    // For now, let's just expose a function or Flow that the UI can collect.
    
    val history: LiveData<List<MathHistoryEntity>>
        get() = repository.getAllHistory(currentUserId).asLiveData()

    val accuracy: LiveData<Float?>
        get() = repository.getOverallAccuracy(currentUserId).asLiveData()

    private val _currentUser = MutableLiveData<UserEntity?>()
    val currentUser: LiveData<UserEntity?> = _currentUser

    fun setUserId(userId: Int) {
        currentUserId = userId
        viewModelScope.launch {
            _currentUser.postValue(repository.getUserById(userId))
        }
    }

    fun addUser(name: String) {
        viewModelScope.launch {
            val user = UserEntity(name = name, avatarId = 1) // Default avatar
            repository.insertUser(user)
        }
    }

    val achievements: LiveData<List<com.rugvedsarika.easymath.data.db.AchievementEntity>>
        get() = repository.getAchievements(currentUserId).asLiveData()

    fun saveSession() {
        viewModelScope.launch {
            val total = _totalQuestions.value ?: 0
            if (total > 0) {
                val currentScore = _score.value ?: 0
                val accuracy = if (total > 0) (currentScore.toFloat() / total.toFloat()) * 100 else 0f
                val history = MathHistoryEntity(
                    userId = currentUserId,
                    timestamp = System.currentTimeMillis(),
                    score = currentScore,
                    totalQuestions = total,
                    category = currentCategory,
                    level = currentLevel,
                    accuracy = accuracy
                )
                repository.insertHistory(history)
                
                // Check Achievements
                com.rugvedsarika.easymath.utils.AchievementManager.checkAchievements(repository, currentUserId)
                com.rugvedsarika.easymath.utils.AchievementManager.checkGameAchievements(
                    repository, currentUserId, currentScore, total, currentCategory
                )
            }
        }
    }
}

class MathViewModelFactory(private val repository: MathRepository, private val audioManager: AudioManager) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(MathViewModel::class.java)) {
            @Suppress("UNCHECKED_CAST")
            return MathViewModel(repository, audioManager) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}
