package com.horrortv.app.presentation.detail

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.horrortv.app.domain.model.AppError
import com.horrortv.app.domain.model.Movie
import com.horrortv.app.domain.repository.MovieRepository
import com.horrortv.app.domain.repository.Result
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject

@HiltViewModel
class DetailViewModel @Inject constructor(
    private val repository: MovieRepository
) : ViewModel() {

    private companion object {
        const val TAG = "DetailViewModel"
    }

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

    private var loadJob: Job? = null
    private var lastImdbId: String = ""

    fun loadMovie(imdbId: String) {
        if (imdbId.isEmpty()) {
            Log.w(TAG, "Empty IMDB ID provided")
            _uiState.update {
                it.copy(
                    isLoading = false,
                    error = AppError.ValidationError(
                        userMessage = "ID de película inválido.",
                        debugMessage = "Empty IMDB ID provided",
                        field = "imdbId"
                    )
                )
            }
            return
        }

        lastImdbId = imdbId
        loadJob?.cancel()
        loadJob = viewModelScope.launch {
            Log.d(TAG, "Loading movie: $imdbId")
            _uiState.update { it.copy(isLoading = true, error = null, movie = null) }

            val result = withContext(Dispatchers.IO) {
                repository.getMovieById(imdbId)
            }

            when (result) {
                is Result.Success -> {
                    val movie = result.data
                    if (movie != null) {
                        Log.d(TAG, "Loaded movie: ${movie.title}")
                        _uiState.update { it.copy(movie = movie, isLoading = false, error = null) }
                    } else {
                        Log.w(TAG, "Movie not found: $imdbId")
                        _uiState.update {
                            it.copy(
                                isLoading = false,
                                error = AppError.ValidationError(
                                    userMessage = "No se encontró la película.",
                                    debugMessage = "Movie not found",
                                    field = "imdbId"
                                )
                            )
                        }
                    }
                }
                is Result.Error -> {
                    Log.e(TAG, "Error loading movie: ${result.error.debugMessage}")
                    _uiState.update { it.copy(isLoading = false, error = result.error) }
                }
            }
        }
    }

    fun retry() {
        if (lastImdbId.isNotEmpty()) {
            loadMovie(lastImdbId)
        }
    }

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

data class DetailUiState(
    val movie: Movie? = null,
    val isLoading: Boolean = false,
    val error: AppError? = null
)