Android. Kotlin. Запоминай код, который я тебе пришлю. package ru.maxi.mobile.repositories.delivery.inmemory

import io.reactivex.BackpressureStrategy
import io.reactivex.Completable
import io.reactivex.Flowable
import io.reactivex.Single
import io.reactivex.schedulers.Schedulers
import io.reactivex.subjects.BehaviorSubject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import ru.maxi.mobile.entity.delivery.clientadress.ClientAddress
import ru.maxi.mobile.entity.delivery.order.EditOrder
import ru.maxi.mobile.entity.delivery.order.onlinepayment.OnlinePaymentCard
import ru.maxi.mobile.feature.delivery.latestComments.model.CommentsData
import ru.maxi.mobile.feature.delivery.model.MakeOrderFieldsData

/**
 * Репозиторий для хранения данных для оформления заказа в памяти
 */
class InMemoryOrderRepository {

    private val subjectClientAddressList = BehaviorSubject.create<List<ClientAddress>>()
    private val _needOrderListUpdate = MutableStateFlow(false)
    private val _onlinePaymentCardList = MutableStateFlow<List<OnlinePaymentCard>>(emptyList())
    private val _makeOrderFields = MutableStateFlow<MakeOrderFieldsData>(MakeOrderFieldsData.Fields.defaultViewState)
    private val _latestCommentsDataFlow = MutableStateFlow<CommentsData?>(null)

    private var editOrdersList = listOf<EditOrder>()

    /** Флаг необходимости обновления списка заказов */
    val needOrderListUpdate: Flow<Boolean> = _needOrderListUpdate.asStateFlow()

    /** Подписка на список карт для оплаты **/
    val onlinePaymentCardList: Flow<List<OnlinePaymentCard>> = _onlinePaymentCardList.asStateFlow()

    /** Подписка на данные полей экрана оформления заказа */
    val makeOrderFields: Flow<MakeOrderFieldsData> = _makeOrderFields.asStateFlow()

    /** Подписка на данные последних комментариев **/
    val latestCommentsDataFlow: Flow<CommentsData?> = _latestCommentsDataFlow.asStateFlow()

    /**
     * Сохранить данные полей [data] экрана оформления заказа
     */
    fun saveMakeOrderFields(data: MakeOrderFieldsData) {
        _makeOrderFields.tryEmit(data)
    }

    /**
     * Очистить данные полей оформления заказа
     */
    fun clearMakeOrderFields() {
        _makeOrderFields.tryEmit(MakeOrderFieldsData.Fields.defaultViewState)
    }

    /**
     * Очистить кастомный адрес клиента
     */
    fun clearCustomAddress() {
        val oldData = (_makeOrderFields.value as? MakeOrderFieldsData.Fields) ?: return
        _makeOrderFields.update {
            oldData.copy(
                customAddressBlock = MakeOrderFieldsData.Fields.CustomAddressBlock(
                    apartment = "",
                    entrance = "",
                    floor = "",
                ),
            )
        }
    }

    /**
     * Обновить список клиентских адресов для экрана "Мои Адреса" [clientAddressList]
     */
    fun updateClientAddressList(clientAddressList: List<ClientAddress>) =
        Completable.fromAction {
            subjectClientAddressList.onNext(clientAddressList)
        }.subscribeOn(Schedulers.io())

    /**
     * Получить подписку на список клиентских адресов для экрана "Мои Адреса"
     */
    fun getClientAddressFlowable(): Flowable<List<ClientAddress>> {
        return subjectClientAddressList.toFlowable(BackpressureStrategy.LATEST)
    }

    /**
     * Добавить клиентский адрес [clientAddress] в список адресов
     */
    fun addClientAddress(clientAddress: ClientAddress) = Completable.fromAction {
        val clientAddressList = (subjectClientAddressList.value ?: emptyList()).toMutableList()
        clientAddressList.add(0, clientAddress)
        subjectClientAddressList.onNext(clientAddressList)
    }.subscribeOn(Schedulers.io())

    /**
     * Удалить адрес по идентификатору [id]
     */
    fun deleteClientAddressById(id: Long) = Completable.fromAction {
        val clientAddressList = (subjectClientAddressList.value ?: emptyList()).filter { it.id != id }
        subjectClientAddressList.onNext(clientAddressList)
    }

    /**
     * Получить список заказов с возможностью редактирования списка товаров
     */
    fun getEditOrdersList(): Single<List<EditOrder>> = Single.just(editOrdersList)

    /**
     * Получить список заказов с возможностью редактирования списка товаров
     */
    fun saveEditOrdersList(list: List<EditOrder>) = Completable.fromAction {
        editOrdersList = list
    }.subscribeOn(Schedulers.io())

    /**
     * Задать нужно ли обновлять список заказов
     */
    fun setNeedUpdateOrderList(needUpdate: Boolean) {
        _needOrderListUpdate.value = needUpdate
    }

    /**
     * Сохранить список карт [cardList] для онлайн оплаты
     */
    fun saveOnlinePaymentCardList(cardList: List<OnlinePaymentCard>) {
        _onlinePaymentCardList.update { cardList }
    }

    /**
     * Удалить карту по [bindingId] из списка карт для онлайн оплаты
     */
    fun removeOnlinePaymentCard(bindingId: String) {
        _onlinePaymentCardList.update { cardList ->
            cardList.filterNot { it.bindingId == bindingId }
        }
    }

    /**
     * Сохранить данные [commentsData] последних комментариев
     */
    fun saveLatestCommentsData(commentsData: CommentsData?) {
        _latestCommentsDataFlow.update { commentsData }
    }
}