package com.seven.ikar.kotlin.feature.profile

import android.net.Uri
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.seven.ikar.kotlin.app.AppContainer
import com.seven.ikar.kotlin.core.model.AuthSessionDto
import com.seven.ikar.kotlin.core.model.UserSummaryDto
import com.seven.ikar.kotlin.core.network.ServerConfig
import com.seven.ikar.kotlin.core.network.UploadFileSource
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

data class ProfileUiState(
    val session: AuthSessionDto? = null,
    val displayName: String = "",
    val phoneNumber: String = "",
    val about: String = "",
    val avatarUrl: String? = null,
    val isLoading: Boolean = false,
    val isSaving: Boolean = false,
    val errorMessage: String? = null,
    val infoMessage: String? = null
)

class ProfileViewModel(private val container: AppContainer) : ViewModel() {
    private val _uiState = MutableStateFlow(ProfileUiState(session = container.sessionStore.read()))
    val uiState: StateFlow<ProfileUiState> = _uiState.asStateFlow()

    init {
        refresh()
    }

    fun updateDisplayName(value: String) {
        _uiState.value = _uiState.value.copy(displayName = value)
    }

    fun updateAbout(value: String) {
        _uiState.value = _uiState.value.copy(about = value)
    }

    fun refresh() {
        if (container.sessionStore.read() == null) return
        viewModelScope.launch {
            _uiState.value = _uiState.value.copy(isLoading = true, errorMessage = null, infoMessage = null)
            runCatching {
                container.executeAuthorized { session ->
                    session to container.apiClient.getMe(session.accessToken)
                }
            }.onSuccess { (session, user) ->
                applyUser(session, user, infoMessage = null)
            }.onFailure { error ->
                _uiState.value = _uiState.value.copy(isLoading = false, errorMessage = error.message)
            }
        }
    }

    fun save() {
        val state = _uiState.value
        if (state.displayName.isBlank()) {
            _uiState.value = state.copy(errorMessage = "Укажите отображаемое имя.")
            return
        }

        viewModelScope.launch {
            _uiState.value = state.copy(isSaving = true, errorMessage = null, infoMessage = null)
            runCatching {
                container.executeAuthorized { session ->
                    session to container.apiClient.updateMyProfile(
                        accessToken = session.accessToken,
                        displayName = state.displayName.trim(),
                        about = state.about.trim().ifBlank { null }
                    )
                }
            }.onSuccess { (session, user) ->
                applyUser(session, user, infoMessage = "Профиль сохранён.")
            }.onFailure { error ->
                _uiState.value = _uiState.value.copy(isSaving = false, errorMessage = error.message)
            }
        }
    }

    fun uploadAvatar(uri: Uri) {
        if (container.sessionStore.read() == null) return
        viewModelScope.launch {
            val state = _uiState.value
            _uiState.value = state.copy(isSaving = true, errorMessage = null, infoMessage = null)
            runCatching {
                val contentResolver = container.appContext.contentResolver
                val contentType = contentResolver.getType(uri)
                val fileName = contentType?.substringAfter('/')?.let { "avatar.$it" } ?: "avatar.jpg"
                container.executeAuthorized { session ->
                    session to container.apiClient.uploadMyAvatar(
                        accessToken = session.accessToken,
                        file = UploadFileSource(
                            fileName = fileName,
                            contentType = contentType
                        ) {
                            contentResolver.openInputStream(uri)
                                ?: throw IllegalStateException("Не удалось открыть выбранное изображение.")
                        }
                    )
                }
            }.onSuccess { (session, user) ->
                applyUser(session, user, infoMessage = "Аватар обновлён.")
            }.onFailure { error ->
                _uiState.value = _uiState.value.copy(isSaving = false, errorMessage = error.message)
            }
        }
    }

    fun deleteAvatar() {
        if (container.sessionStore.read() == null) return
        viewModelScope.launch {
            val state = _uiState.value
            _uiState.value = state.copy(isSaving = true, errorMessage = null, infoMessage = null)
            runCatching {
                container.executeAuthorized { session ->
                    session to container.apiClient.deleteMyAvatar(session.accessToken)
                }
            }.onSuccess { (session, user) ->
                applyUser(session, user, infoMessage = "Аватар удалён.")
            }.onFailure { error ->
                _uiState.value = _uiState.value.copy(isSaving = false, errorMessage = error.message)
            }
        }
    }

    private fun applyUser(session: AuthSessionDto, user: UserSummaryDto, infoMessage: String?) {
        val updatedSession = session.copy(user = user)
        container.sessionStore.save(updatedSession)
        _uiState.value = _uiState.value.copy(
            session = updatedSession,
            displayName = user.displayName,
            phoneNumber = user.phoneNumber.orEmpty(),
            about = user.about.orEmpty(),
            avatarUrl = ServerConfig.normalizeMediaUrl(user.avatarPath),
            isLoading = false,
            isSaving = false,
            errorMessage = null,
            infoMessage = infoMessage
        )
    }
}
