package com.divya.keyspeed.viewmodel

import android.app.Application
import android.os.CountDownTimer
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.divya.keyspeed.data.AppDatabase
import com.divya.keyspeed.data.PassageRepository
import com.divya.keyspeed.data.TypingHistory
import com.divya.keyspeed.model.TypingResult
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.math.RoundingMode
import java.text.DecimalFormat
import kotlin.math.roundToInt

class TypingViewModel(application: Application) : AndroidViewModel(application) {

    private val repository = PassageRepository(application)
    
    private val _passage = MutableLiveData<String>()
    val passage: LiveData<String> = _passage
    
    private val _timeLeft = MutableLiveData<Int>()
    val timeLeft: LiveData<Int> = _timeLeft
    
    // 0: Not started, 1: Running, 2: Finished
    private val _testState = MutableLiveData<Int>(0)
    val testState: LiveData<Int> = _testState
    
    private val _wpm = MutableLiveData<Int>(0)
    val wpm: LiveData<Int> = _wpm
    
    private val _accuracy = MutableLiveData<Int>(0)
    val accuracy: LiveData<Int> = _accuracy

    private var timer: CountDownTimer? = null
    var selectedDurationSeconds: Int = 60
    
    private var totalCorrectChars = 0
    private var totalTypedChars = 0
    
    private var startTime: Long = 0

    init {
        loadNewPassage()
    }
    
    fun setDuration(seconds: Int) {
        selectedDurationSeconds = seconds
        _timeLeft.value = seconds
    }
    
    fun loadNewPassage() {
        _passage.value = repository.getRandomPassage()
        resetTest()
    }
    
    fun startTest() {
        if (_testState.value == 1) return // Already running
        
        _testState.value = 1
        startTime = System.currentTimeMillis()
        totalCorrectChars = 0
        totalTypedChars = 0
        
        timer = object : CountDownTimer(selectedDurationSeconds * 1000L, 1000) {
            override fun onTick(millisUntilFinished: Long) {
                _timeLeft.value = (millisUntilFinished / 1000).toInt()
                updateWpm()
            }

            override fun onFinish() {
                _timeLeft.value = 0
                finishTest()
            }
        }.start()
    }
    
    fun onTyping(input: String) {
        if (_testState.value == 0 && input.isNotEmpty()) {
            startTest()
        }
        
        if (_testState.value != 1) return

        val target = _passage.value ?: ""
        
        // Calculate stats
        calculateStats(input, target)
        
        if (input.length >= target.length) {
            timer?.cancel()
            finishTest()
        }
    }
    
    private fun calculateStats(input: String, target: String) {
        var correct = 0
        for (i in input.indices) {
            if (i < target.length && input[i] == target[i]) {
                correct++
            }
        }
        
        totalCorrectChars = correct
        totalTypedChars = input.length
        
        updateWpm()
        
        // Accuracy
        if (totalTypedChars > 0) {
            _accuracy.value = ((totalCorrectChars.toDouble() / totalTypedChars.toDouble()) * 100).toInt()
        } else {
            _accuracy.value = 100
        }
    }
    
    private fun updateWpm() {
        val elapsedTime = System.currentTimeMillis() - startTime
        val seconds = elapsedTime / 1000.0
        if (seconds > 0) {
            val wpmVal = ((totalCorrectChars / 5.0) / (seconds / 60.0)).toInt()
            _wpm.value = wpmVal
        }
    }
    
    private fun finishTest() {
        if (_testState.value == 2) return // Already finished
        
        timer?.cancel()
        updateWpm()
        _testState.value = 2
    }
    
    fun getFinalResult(): TypingResult {
        return TypingResult(
            wpm = _wpm.value ?: 0,
            accuracy = _accuracy.value ?: 0,
            totalCharacters = totalTypedChars,
            correctChars = totalCorrectChars,
            incorrectChars = totalTypedChars - totalCorrectChars,
            durationSeconds = selectedDurationSeconds
        )
    }

    fun saveResultToHistory() {
        val result = getFinalResult()
        val historyItem = TypingHistory(
            wpm = result.wpm,
            accuracy = result.accuracy,
            correctChars = result.correctChars,
            incorrectChars = result.incorrectChars,
            durationSeconds = result.durationSeconds
        )
        
        viewModelScope.launch(Dispatchers.IO) {
            AppDatabase.getDatabase(getApplication()).historyDao().insertResult(historyItem)
        }
    }
    
    private fun resetTest() {
        timer?.cancel()
        _testState.value = 0
        _timeLeft.value = selectedDurationSeconds
        _wpm.value = 0
        _accuracy.value = 0
        totalCorrectChars = 0
        totalTypedChars = 0
    }
    
    override fun onCleared() {
        super.onCleared()
        timer?.cancel()
    }
}
