package com.example.match.ui.matchdetail

import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.match.db.PredictionEntity
import com.example.match.model.Fixture
import com.example.match.model.LiveScore
import com.example.match.repository.MatchRepository
import com.example.match.repository.PredictionRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class MatchDetailViewModel @Inject constructor(
    private val matchRepository: MatchRepository,
    @ApplicationContext private val appContext: Context
) : ViewModel() {

    private val _fixtureState = MutableStateFlow<Fixture?>(null)
    val fixtureState: StateFlow<Fixture?> get() = _fixtureState

    private val _liveScoreState = MutableStateFlow<LiveScore?>(null)
    val liveScoreState: StateFlow<LiveScore?> get() = _liveScoreState

    private val _predictionSaved = MutableStateFlow<Boolean?>(null)
    val predictionSaved: StateFlow<Boolean?> get() = _predictionSaved

    private val _currentUserPrediction = MutableStateFlow<PredictionEntity?>(null)
    val currentUserPrediction: StateFlow<PredictionEntity?> get() = _currentUserPrediction

    private val _errorMessage = MutableStateFlow<String?>(null)
    val errorMessage: StateFlow<String?> = _errorMessage.asStateFlow()

    private val _statistics = MutableStateFlow<String>("")
    val statistics: StateFlow<String> = _statistics.asStateFlow()


    fun fetchMatchDetailById(matchId: String) {
        viewModelScope.launch {
            try {
                val upcoming = matchRepository.getUpcomingMatches()
                val live = matchRepository.getLiveScores()
                val foundFixture = upcoming.find { it.matchId == matchId }
                val foundLive = live.find { it.matchId == matchId }

                if (foundFixture != null) {
                    _fixtureState.value = foundFixture
                } else if (foundLive != null) {
                    _liveScoreState.value = foundLive

                    checkAndMarkPredictionIfMatchFinished()

                } else {
                    println("Match not found in upcoming or live.")
                }
            } catch (e: Exception) {
                println("Error fetching match details: ${e.message}")
            }
        }
    }


    fun fetchUserPrediction(matchId: String, userId: Int) {
        viewModelScope.launch {
            val existingPred = PredictionRepository.getPredictionForUserAndMatch(
                context = appContext,
                matchId = matchId,
                userId = userId
            )
            _currentUserPrediction.value = existingPred
        }
    }

    fun saveUserPrediction(
        matchId: String,
        userId: Int,
        homeScore: Int,
        awayScore: Int
    ) {
        viewModelScope.launch {
            val entity = PredictionEntity(
                matchId = matchId,
                userId = userId,
                homeScore = homeScore,
                awayScore = awayScore,
                timestamp = System.currentTimeMillis()
            )

            val result = PredictionRepository.savePrediction(appContext, entity)
            _predictionSaved.value = result.isSuccess

            if (result.isSuccess) {
                val newId = result.getOrNull() ?: 0
                _currentUserPrediction.value = entity.copy(id = newId.toInt())
            }
        }
    }

    fun checkAndMarkPredictionIfMatchFinished() {
        viewModelScope.launch {
            val live = _liveScoreState.value
            val pred = _currentUserPrediction.value
            if (live?.status == -1 && pred != null) {
                // match ended
                val finalHome = live.homeScore ?: 0
                val finalAway = live.awayScore ?: 0
                val correct = (finalHome == pred.homeScore && finalAway == pred.awayScore)

                val updated = PredictionRepository.updatePredictionCorrect(
                    context = appContext,
                    predictionId = pred.id,
                    isCorrect = correct
                )
                if (updated) {
                    _currentUserPrediction.value = pred.copy(isCorrect = correct)
                }
            }
        }
    }

    fun showError(message: String) {
        _errorMessage.value = message
    }

    fun clearError() {
        _errorMessage.value = null
    }



    fun fetchMatchStatistics(matchId: String) {
        viewModelScope.launch {
            try {
                val result = matchRepository.fetchMatchStatistics(matchId)
                _statistics.value = result.toString()
            } catch (e: Exception) {
                _statistics.value = "Error: ${e.message}"
            }
        }
    }
}