package de.trainingstagebuch.app.viewmodel

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import de.trainingstagebuch.app.R
import de.trainingstagebuch.app.repository.MemberContactItem
import de.trainingstagebuch.app.repository.MemberImageItem
import de.trainingstagebuch.app.repository.MemberItem
import de.trainingstagebuch.app.repository.MemberNoteItem
import de.trainingstagebuch.app.repository.MemberActionResult
import de.trainingstagebuch.app.repository.MemberImagesResult
import de.trainingstagebuch.app.repository.MemberNotesResult
import de.trainingstagebuch.app.repository.MemberSaveResult
import de.trainingstagebuch.app.repository.MemberTrainingGroupsResult
import de.trainingstagebuch.app.repository.MembersResult
import de.trainingstagebuch.app.repository.TrainingGroupItem
import de.trainingstagebuch.app.services.AppServices
import de.trainingstagebuch.app.utils.ErrorMessageFormatter
import de.trainingstagebuch.app.utils.MembersFilterUtils
import de.trainingstagebuch.app.utils.MembersSortOrder
import de.trainingstagebuch.app.utils.UiText
import de.trainingstagebuch.app.utils.ViewModelStateUtils
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

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

    private val membersService = AppServices.membersService
    private val authService = AppServices.authService

    private val _state = MutableStateFlow(MembersUiState())
    val state: StateFlow<MembersUiState> = _state.asStateFlow()

    init {
        load()
    }

    fun onSearchQueryChanged(value: String) {
        _state.update { current ->
            val updated = current.copy(searchQuery = value)
            updated.copy(
                filteredMembers = MembersFilterUtils.apply(
                    members = updated.members,
                    searchQuery = updated.searchQuery,
                    showInactive = updated.showInactive,
                    sortOrder = updated.sortOrder
                )
            )
        }
    }

    fun onShowInactiveChanged(value: Boolean) {
        _state.update { current ->
            val updated = current.copy(showInactive = value)
            updated.copy(
                filteredMembers = MembersFilterUtils.apply(
                    members = updated.members,
                    searchQuery = updated.searchQuery,
                    showInactive = updated.showInactive,
                    sortOrder = updated.sortOrder
                )
            )
        }
    }

    fun cycleSortOrder() {
        _state.update { current ->
            val nextSortOrder = when (current.sortOrder) {
                MembersSortOrder.NameAsc -> MembersSortOrder.NameDesc
                MembersSortOrder.NameDesc -> MembersSortOrder.Status
                MembersSortOrder.Status -> MembersSortOrder.NameAsc
            }
            val updated = current.copy(sortOrder = nextSortOrder)
            updated.copy(
                filteredMembers = MembersFilterUtils.apply(
                    members = updated.members,
                    searchQuery = updated.searchQuery,
                    showInactive = updated.showInactive,
                    sortOrder = updated.sortOrder
                )
            )
        }
    }

    fun load() {
        viewModelScope.launch {
            _state.update { it.copy(status = MembersStatus.Loading, errorMessage = null) }
            val session = authService.session.first()
            val currentClub = session.currentClub?.trim().orEmpty()
            if (currentClub.isBlank()) {
                _state.update {
                    it.copy(
                        status = MembersStatus.Error,
                        errorMessage = UiText(R.string.error_no_current_club),
                        members = emptyList(),
                        filteredMembers = emptyList(),
                        currentClubId = null,
                        activeMembersCount = 0,
                        testMembersCount = 0,
                        inactiveMembersCount = 0
                    )
                }
                return@launch
            }

            when (val result = membersService.loadMembers(clubId = currentClub, showAll = true)) {
                is MembersResult.Success -> {
                    val filtered = MembersFilterUtils.apply(
                        members = result.members,
                        searchQuery = _state.value.searchQuery,
                        showInactive = _state.value.showInactive,
                        sortOrder = _state.value.sortOrder
                    )
                    _state.update {
                        it.copy(
                            status = MembersStatus.Success,
                            members = result.members,
                            filteredMembers = filtered,
                            currentClubId = currentClub,
                            activeMembersCount = result.members.count { member -> member.active && !member.testMembership },
                            testMembersCount = result.members.count { member -> member.active && member.testMembership },
                            inactiveMembersCount = result.members.count { member -> !member.active }
                        )
                    }
                }

                is MembersResult.Error -> {
                    _state.update {
                        it.copy(
                            status = MembersStatus.Error,
                            errorMessage = ViewModelStateUtils.dynamicOrFallback(result.message),
                            members = emptyList(),
                            filteredMembers = emptyList(),
                            currentClubId = currentClub,
                            activeMembersCount = 0,
                            testMembersCount = 0,
                            inactiveMembersCount = 0
                        )
                    }
                }
            }
        }
    }

    fun startCreate() {
        _state.update {
            it.copy(
                selectedMemberId = null,
                editorFirstName = "",
                editorLastName = "",
                editorActive = true,
                editorTestMembership = false,
                editorMessage = null,
                memberImages = emptyList(),
                editorPhoneContacts = listOf(""),
                editorEmailContacts = listOf(""),
                memberTrainingGroups = emptyList(),
                availableTrainingGroups = emptyList(),
                memberNotes = emptyList(),
                newNoteContent = ""
            )
        }
    }

    fun selectMember(member: MemberItem) {
        _state.update {
            it.copy(
                selectedMemberId = member.id,
                editorFirstName = member.firstName,
                editorLastName = member.lastName,
                editorActive = member.active,
                editorTestMembership = member.testMembership,
                editorMessage = null,
                editorPhoneContacts = member.contacts
                    .filter { it.type == "phone" }
                    .map { it.value }
                    .ifEmpty { listOf("") },
                editorEmailContacts = member.contacts
                    .filter { it.type == "email" }
                    .map { it.value }
                    .ifEmpty { listOf("") }
            )
        }
        loadMemberImages(member.id)
        loadTrainingGroupsForMember(member.id)
        loadMemberNotesForMember(member.id)
    }

    fun onEditorFirstNameChanged(value: String) {
        _state.update { it.copy(editorFirstName = value) }
    }

    fun onEditorLastNameChanged(value: String) {
        _state.update { it.copy(editorLastName = value) }
    }

    fun onEditorActiveChanged(value: Boolean) {
        _state.update { it.copy(editorActive = value) }
    }

    fun onEditorTestMembershipChanged(value: Boolean) {
        _state.update { it.copy(editorTestMembership = value) }
    }

    fun saveMember() {
        viewModelScope.launch {
            val current = _state.value
            val clubId = current.currentClubId?.trim().orEmpty()
            val firstName = current.editorFirstName.trim()
            val lastName = current.editorLastName.trim()
            if (clubId.isBlank()) {
                _state.update { it.copy(editorMessage = UiText(R.string.error_no_current_club)) }
                return@launch
            }
            if (firstName.isBlank() || lastName.isBlank()) {
                _state.update { it.copy(editorMessage = UiText(R.string.error_required_member_name)) }
                return@launch
            }

            _state.update { it.copy(isSaving = true, editorMessage = null) }
            when (
                val result = membersService.saveMember(
                    clubId = clubId,
                    memberId = current.selectedMemberId,
                    firstName = firstName,
                    lastName = lastName,
                    active = current.editorActive,
                    testMembership = current.editorTestMembership,
                    contacts = buildList {
                        current.editorPhoneContacts
                            .map { it.trim() }
                            .filter { it.isNotBlank() }
                            .forEach { add(MemberContactItem(type = "phone", value = it)) }
                        current.editorEmailContacts
                            .map { it.trim() }
                            .filter { it.isNotBlank() }
                            .forEach { add(MemberContactItem(type = "email", value = it)) }
                    }
                )
            ) {
                is MemberSaveResult.Success -> {
                    val msg = result.message?.trim().orEmpty()
                    _state.update {
                        it.copy(
                            isSaving = false,
                            editorMessage = if (msg.isBlank()) {
                                UiText(R.string.members_save_success_default)
                            } else {
                                UiText(R.string.message_dynamic, args = listOf(msg))
                            }
                        )
                    }
                    load()
                }

                is MemberSaveResult.Error -> {
                    _state.update {
                        it.copy(
                            isSaving = false,
                            editorMessage = ViewModelStateUtils.normalizeUiText(
                                ErrorMessageFormatter.dynamicWithOptionalCode(result.message, result.code)
                            )
                        )
                    }
                }
            }
        }
    }

    fun onPhoneContactChanged(index: Int, value: String) {
        _state.update { current ->
            val updated = current.editorPhoneContacts.toMutableList()
            if (index in updated.indices) updated[index] = value
            current.copy(editorPhoneContacts = updated)
        }
    }

    fun addPhoneContact() {
        _state.update { it.copy(editorPhoneContacts = it.editorPhoneContacts + "") }
    }

    fun removePhoneContact(index: Int) {
        _state.update { current ->
            val updated = current.editorPhoneContacts.toMutableList()
            if (index in updated.indices) updated.removeAt(index)
            current.copy(editorPhoneContacts = if (updated.isEmpty()) listOf("") else updated)
        }
    }

    fun onEmailContactChanged(index: Int, value: String) {
        _state.update { current ->
            val updated = current.editorEmailContacts.toMutableList()
            if (index in updated.indices) updated[index] = value
            current.copy(editorEmailContacts = updated)
        }
    }

    fun addEmailContact() {
        _state.update { it.copy(editorEmailContacts = it.editorEmailContacts + "") }
    }

    fun removeEmailContact(index: Int) {
        _state.update { current ->
            val updated = current.editorEmailContacts.toMutableList()
            if (index in updated.indices) updated.removeAt(index)
            current.copy(editorEmailContacts = if (updated.isEmpty()) listOf("") else updated)
        }
    }

    fun loadTrainingGroupsForMember(memberId: String) {
        viewModelScope.launch {
            val clubId = _state.value.currentClubId?.trim().orEmpty()
            if (clubId.isBlank()) return@launch
            _state.update { it.copy(groupsLoading = true) }

            val allGroups = when (val result = membersService.loadTrainingGroups(clubId)) {
                is MemberTrainingGroupsResult.Success -> result.groups
                is MemberTrainingGroupsResult.Error -> {
                    _state.update {
                        it.copy(
                            groupsLoading = false,
                            editorMessage = ViewModelStateUtils.normalizeUiText(
                                ErrorMessageFormatter.dynamicWithOptionalCode(result.message, result.code)
                            )
                        )
                    }
                    return@launch
                }
            }

            val memberGroups = when (val result = membersService.loadMemberTrainingGroups(clubId, memberId)) {
                is MemberTrainingGroupsResult.Success -> result.groups
                is MemberTrainingGroupsResult.Error -> {
                    _state.update {
                        it.copy(
                            groupsLoading = false,
                            editorMessage = ViewModelStateUtils.normalizeUiText(
                                ErrorMessageFormatter.dynamicWithOptionalCode(result.message, result.code)
                            )
                        )
                    }
                    return@launch
                }
            }

            val assignedIds = memberGroups.map { it.id }.toSet()
            _state.update {
                it.copy(
                    groupsLoading = false,
                    memberTrainingGroups = memberGroups,
                    availableTrainingGroups = allGroups.filterNot { group -> group.id in assignedIds }
                )
            }
        }
    }

    fun addMemberToTrainingGroup(groupId: String) {
        updateMemberTrainingGroup(groupId, add = true)
    }

    fun removeMemberFromTrainingGroup(groupId: String) {
        updateMemberTrainingGroup(groupId, add = false)
    }

    private fun updateMemberTrainingGroup(groupId: String, add: Boolean) {
        viewModelScope.launch {
            val clubId = _state.value.currentClubId?.trim().orEmpty()
            val memberId = _state.value.selectedMemberId?.trim().orEmpty()
            if (clubId.isBlank() || memberId.isBlank() || groupId.isBlank()) return@launch
            _state.update { it.copy(groupsLoading = true) }
            val result = if (add) {
                membersService.addMemberToTrainingGroup(clubId, memberId, groupId)
            } else {
                membersService.removeMemberFromTrainingGroup(clubId, memberId, groupId)
            }
            when (result) {
                is MemberActionResult.Success -> {
                    val fallbackRes = if (add) {
                        R.string.members_group_added_default
                    } else {
                        R.string.members_group_removed_default
                    }
                    _state.update {
                        it.copy(
                            groupsLoading = false,
                            editorMessage = if (result.message.isNullOrBlank()) {
                                UiText(fallbackRes)
                            } else {
                                UiText(R.string.message_dynamic, args = listOf(result.message))
                            }
                        )
                    }
                    loadTrainingGroupsForMember(memberId)
                }

                is MemberActionResult.Error -> {
                    _state.update {
                        it.copy(
                            groupsLoading = false,
                            editorMessage = ViewModelStateUtils.normalizeUiText(
                                ErrorMessageFormatter.dynamicWithOptionalCode(result.message, result.code)
                            )
                        )
                    }
                }
            }
        }
    }

    fun quickRemoveTestMembership(memberId: String) {
        viewModelScope.launch {
            val clubId = _state.value.currentClubId?.trim().orEmpty()
            if (clubId.isBlank()) {
                _state.update { it.copy(editorMessage = UiText(R.string.error_no_current_club)) }
                return@launch
            }
            when (val result = membersService.quickRemoveTestMembership(clubId = clubId, memberId = memberId)) {
                is MemberActionResult.Success -> {
                    val msg = result.message?.trim().orEmpty()
                    _state.update {
                        it.copy(
                            editorMessage = if (msg.isBlank()) {
                                UiText(R.string.members_action_test_removed_default)
                            } else {
                                UiText(R.string.message_dynamic, args = listOf(msg))
                            }
                        )
                    }
                    load()
                }

                is MemberActionResult.Error -> {
                    _state.update {
                        it.copy(
                            editorMessage = ViewModelStateUtils.normalizeUiText(
                                ErrorMessageFormatter.dynamicWithOptionalCode(result.message, result.code)
                            )
                        )
                    }
                }
            }
        }
    }

    fun quickDeactivateMember(memberId: String) {
        viewModelScope.launch {
            val clubId = _state.value.currentClubId?.trim().orEmpty()
            if (clubId.isBlank()) {
                _state.update { it.copy(editorMessage = UiText(R.string.error_no_current_club)) }
                return@launch
            }
            when (val result = membersService.quickDeactivateMember(clubId = clubId, memberId = memberId)) {
                is MemberActionResult.Success -> {
                    val msg = result.message?.trim().orEmpty()
                    _state.update {
                        it.copy(
                            editorMessage = if (msg.isBlank()) {
                                UiText(R.string.members_action_deactivated_default)
                            } else {
                                UiText(R.string.message_dynamic, args = listOf(msg))
                            }
                        )
                    }
                    load()
                }

                is MemberActionResult.Error -> {
                    _state.update {
                        it.copy(
                            editorMessage = ViewModelStateUtils.normalizeUiText(
                                ErrorMessageFormatter.dynamicWithOptionalCode(result.message, result.code)
                            )
                        )
                    }
                }
            }
        }
    }

    fun updateRatings() {
        viewModelScope.launch {
            val clubId = _state.value.currentClubId?.trim().orEmpty()
            if (clubId.isBlank()) {
                _state.update { it.copy(editorMessage = UiText(R.string.error_no_current_club)) }
                return@launch
            }
            _state.update { it.copy(isSaving = true) }
            when (val result = membersService.updateRatings(clubId)) {
                is MemberActionResult.Success -> {
                    _state.update {
                        it.copy(
                            isSaving = false,
                            editorMessage = if (result.message.isNullOrBlank()) {
                                UiText(R.string.members_ratings_updated_default)
                            } else {
                                UiText(R.string.message_dynamic, args = listOf(result.message))
                            }
                        )
                    }
                    load()
                }

                is MemberActionResult.Error -> {
                    _state.update {
                        it.copy(
                            isSaving = false,
                            editorMessage = ViewModelStateUtils.normalizeUiText(
                                ErrorMessageFormatter.dynamicWithOptionalCode(result.message, result.code)
                            )
                        )
                    }
                }
            }
        }
    }

    fun loadMemberImages(memberId: String) {
        viewModelScope.launch {
            val clubId = _state.value.currentClubId?.trim().orEmpty()
            if (clubId.isBlank()) {
                _state.update { it.copy(editorMessage = UiText(R.string.error_no_current_club)) }
                return@launch
            }
            _state.update { it.copy(imagesLoading = true) }
            when (val result = membersService.loadMemberImages(clubId = clubId, memberId = memberId)) {
                is MemberImagesResult.Success -> {
                    _state.update { it.copy(imagesLoading = false, memberImages = result.images) }
                }

                is MemberImagesResult.Error -> {
                    _state.update {
                        it.copy(
                            imagesLoading = false,
                            memberImages = emptyList(),
                            editorMessage = ViewModelStateUtils.normalizeUiText(
                                ErrorMessageFormatter.dynamicWithOptionalCode(result.message, result.code)
                            )
                        )
                    }
                }
            }
        }
    }

    fun uploadMemberImage(fileName: String, bytes: ByteArray) {
        viewModelScope.launch {
            val current = _state.value
            val clubId = current.currentClubId?.trim().orEmpty()
            val memberId = current.selectedMemberId?.trim().orEmpty()
            if (clubId.isBlank() || memberId.isBlank()) {
                _state.update { it.copy(editorMessage = UiText(R.string.error_select_member_for_images)) }
                return@launch
            }
            _state.update { it.copy(imagesLoading = true, editorMessage = null) }
            when (
                val result = membersService.uploadMemberImage(
                    clubId = clubId,
                    memberId = memberId,
                    fileName = fileName,
                    bytes = bytes
                )
            ) {
                is MemberActionResult.Success -> {
                    _state.update {
                        it.copy(
                            imagesLoading = false,
                            editorMessage = if (result.message.isNullOrBlank()) {
                                UiText(R.string.members_image_uploaded_default)
                            } else {
                                UiText(R.string.message_dynamic, args = listOf(result.message))
                            }
                        )
                    }
                    loadMemberImages(memberId)
                }

                is MemberActionResult.Error -> {
                    _state.update {
                        it.copy(
                            imagesLoading = false,
                            editorMessage = ViewModelStateUtils.normalizeUiText(
                                ErrorMessageFormatter.dynamicWithOptionalCode(result.message, result.code)
                            )
                        )
                    }
                }
            }
        }
    }

    fun setPrimaryMemberImage(imageId: String) {
        runMemberImageAction(imageId) { clubId, memberId ->
            membersService.setPrimaryMemberImage(clubId = clubId, memberId = memberId, imageId = imageId)
        }
    }

    fun deleteMemberImage(imageId: String) {
        runMemberImageAction(imageId) { clubId, memberId ->
            membersService.deleteMemberImage(clubId = clubId, memberId = memberId, imageId = imageId)
        }
    }

    private fun runMemberImageAction(
        imageId: String,
        action: suspend (clubId: String, memberId: String) -> MemberActionResult
    ) {
        viewModelScope.launch {
            val current = _state.value
            val clubId = current.currentClubId?.trim().orEmpty()
            val memberId = current.selectedMemberId?.trim().orEmpty()
            if (clubId.isBlank() || memberId.isBlank()) {
                _state.update { it.copy(editorMessage = UiText(R.string.error_select_member_for_images)) }
                return@launch
            }
            _state.update { it.copy(imagesLoading = true, editorMessage = null) }
            when (val result = action(clubId, memberId)) {
                is MemberActionResult.Success -> {
                    val fallbackRes = if (imageId.isNotBlank()) {
                        R.string.members_image_action_success_default
                    } else {
                        R.string.members_image_action_success_default
                    }
                    _state.update {
                        it.copy(
                            imagesLoading = false,
                            editorMessage = if (result.message.isNullOrBlank()) {
                                UiText(fallbackRes)
                            } else {
                                UiText(R.string.message_dynamic, args = listOf(result.message))
                            }
                        )
                    }
                    loadMemberImages(memberId)
                }

                is MemberActionResult.Error -> {
                    _state.update {
                        it.copy(
                            imagesLoading = false,
                            editorMessage = ViewModelStateUtils.normalizeUiText(
                                ErrorMessageFormatter.dynamicWithOptionalCode(result.message, result.code)
                            )
                        )
                    }
                }
            }
        }
    }

    fun onNewNoteContentChanged(value: String) {
        _state.update { it.copy(newNoteContent = value) }
    }

    fun loadMemberNotesForMember(memberId: String) {
        viewModelScope.launch {
            val clubId = _state.value.currentClubId?.trim().orEmpty()
            if (clubId.isBlank() || memberId.isBlank()) return@launch
            _state.update { it.copy(notesLoading = true) }
            when (val result = membersService.loadMemberNotes(clubId = clubId, memberId = memberId)) {
                is MemberNotesResult.Success -> {
                    _state.update {
                        it.copy(
                            notesLoading = false,
                            memberNotes = result.notes
                        )
                    }
                }

                is MemberNotesResult.Error -> {
                    _state.update {
                        it.copy(
                            notesLoading = false,
                            editorMessage = ViewModelStateUtils.normalizeUiText(
                                ErrorMessageFormatter.dynamicWithOptionalCode(result.message, result.code)
                            )
                        )
                    }
                }
            }
        }
    }

    fun addMemberNote() {
        viewModelScope.launch {
            val clubId = _state.value.currentClubId?.trim().orEmpty()
            val memberId = _state.value.selectedMemberId?.trim().orEmpty()
            val content = _state.value.newNoteContent.trim()
            if (clubId.isBlank() || memberId.isBlank()) {
                _state.update { it.copy(editorMessage = UiText(R.string.error_select_member_for_notes)) }
                return@launch
            }
            if (content.isBlank()) {
                _state.update { it.copy(editorMessage = UiText(R.string.error_note_content_required)) }
                return@launch
            }
            _state.update { it.copy(notesLoading = true, editorMessage = null) }
            when (val result = membersService.addMemberNote(clubId = clubId, memberId = memberId, content = content)) {
                is MemberNotesResult.Success -> {
                    _state.update {
                        it.copy(
                            notesLoading = false,
                            memberNotes = result.notes,
                            newNoteContent = ""
                        )
                    }
                }

                is MemberNotesResult.Error -> {
                    _state.update {
                        it.copy(
                            notesLoading = false,
                            editorMessage = ViewModelStateUtils.normalizeUiText(
                                ErrorMessageFormatter.dynamicWithOptionalCode(result.message, result.code)
                            )
                        )
                    }
                }
            }
        }
    }

    fun deleteMemberNote(noteId: String) {
        viewModelScope.launch {
            val clubId = _state.value.currentClubId?.trim().orEmpty()
            if (clubId.isBlank() || noteId.isBlank()) return@launch
            _state.update { it.copy(notesLoading = true) }
            when (val result = membersService.deleteMemberNote(clubId = clubId, noteId = noteId)) {
                is MemberNotesResult.Success -> {
                    _state.update {
                        it.copy(
                            notesLoading = false,
                            memberNotes = result.notes
                        )
                    }
                }

                is MemberNotesResult.Error -> {
                    _state.update {
                        it.copy(
                            notesLoading = false,
                            editorMessage = ViewModelStateUtils.normalizeUiText(
                                ErrorMessageFormatter.dynamicWithOptionalCode(result.message, result.code)
                            )
                        )
                    }
                }
            }
        }
    }
}

data class MembersUiState(
    val status: MembersStatus = MembersStatus.Idle,
    val members: List<MemberItem> = emptyList(),
    val filteredMembers: List<MemberItem> = emptyList(),
    val currentClubId: String? = null,
    val activeMembersCount: Int = 0,
    val testMembersCount: Int = 0,
    val inactiveMembersCount: Int = 0,
    val searchQuery: String = "",
    val showInactive: Boolean = false,
    val sortOrder: MembersSortOrder = MembersSortOrder.NameAsc,
    val selectedMemberId: String? = null,
    val editorFirstName: String = "",
    val editorLastName: String = "",
    val editorActive: Boolean = true,
    val editorTestMembership: Boolean = false,
    val editorPhoneContacts: List<String> = listOf(""),
    val editorEmailContacts: List<String> = listOf(""),
    val isSaving: Boolean = false,
    val imagesLoading: Boolean = false,
    val groupsLoading: Boolean = false,
    val notesLoading: Boolean = false,
    val memberImages: List<MemberImageItem> = emptyList(),
    val memberTrainingGroups: List<TrainingGroupItem> = emptyList(),
    val availableTrainingGroups: List<TrainingGroupItem> = emptyList(),
    val memberNotes: List<MemberNoteItem> = emptyList(),
    val newNoteContent: String = "",
    val editorMessage: UiText? = null,
    val errorMessage: UiText? = null
)

enum class MembersStatus {
    Idle,
    Loading,
    Success,
    Error
}
