package dominando.android.domain

import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import dominando.android.data.BooksRepository
import dominando.android.data.model.Book

class SaveBookUseCase(private val repository: BooksRepository) {
    private val bookToBeSave = MutableLiveData<Book>()
    private val saveStatus = MutableLiveData<Result>()
    private val savingOperation: LiveData<Result> =
            Transformations.switchMap(bookToBeSave){ book ->
                Transformations.map(repository.saveBook(book)) { success ->
                    if (success) {
                        Result.Success()
                    } else {
                        Result.GenericError()
                    }
                }
            }

    private val mediatorLiveData = MediatorLiveData<Result>().apply {
        addSource(saveStatus) { result ->
            value = result
        }
        addSource(savingOperation) { result ->
            value = result
        }
    }

    fun saveBook(book: Book): LiveData<Result> {
        when {
            book.title.isBlank() -> saveStatus.value = Result.InvalidTitle()
            book.author.isBlank() -> saveStatus.value = Result.InvalidAuthor()
            book.pages == 0 -> saveStatus.value = Result.InvalidPages()
            book.year < 1900 -> saveStatus.value = Result.InvalidYear()
            else -> bookToBeSave.value = book
        }
        return mediatorLiveData
    }

    sealed class Result {
        class Success : Result()
        class InvalidTitle : Result()
        class InvalidAuthor : Result()
        class InvalidYear : Result()
        class InvalidPages : Result()
        class GenericError : Result()

        fun toLiveData(): LiveData<Result> {
            return MutableLiveData<Result>().apply { value = this@Result }
        }
    }
}