package com.airbnb.lottie.samples

import androidx.fragment.app.FragmentActivity
import com.airbnb.epoxy.EpoxyController
import com.airbnb.lottie.samples.model.AnimationData
import com.airbnb.lottie.samples.model.AnimationResponse
import com.airbnb.lottie.samples.model.CompositionArgs
import com.airbnb.lottie.samples.views.loadingView
import com.airbnb.lottie.samples.views.lottiefilesTabBar
import com.airbnb.lottie.samples.views.marquee
import com.airbnb.lottie.samples.views.searchInputItemView
import com.airbnb.mvrx.*


data class LottiefilesState(
        val mode: LottiefilesMode = LottiefilesMode.Recent,
        val items: List<AnimationData> = emptyList(),
        val request: Async<AnimationResponse> = Uninitialized,
        val query: String = ""
) : MvRxState

class LottiefilesViewModel(
        initialState: LottiefilesState,
        private val service: LottiefilesService) : MvRxViewModel<LottiefilesState>(initialState
) {
    init {
        selectSubscribe(LottiefilesState::mode) { fetchMoreItems() }
    }

    fun fetchMoreItems() = withState { state ->
        if (state.request is Loading) return@withState
        val page = (state.request()?.currentPage ?: -1) + 1
        if (state.request()?.lastPage == page && page > 0) return@withState

        when (state.mode) {
            LottiefilesMode.Recent -> service.getRecent(page)
            LottiefilesMode.Popular -> service.getPopular(page)
            LottiefilesMode.Search -> service.search(state.query)
        }.execute { copy(request = it, items = items + (it()?.data ?: emptyList())) }
    }

    fun setMode(mode: LottiefilesMode, query: String = "") = setState {
        if (this.mode == mode && mode != LottiefilesMode.Search) return@setState this
        if (this.mode == mode && mode == LottiefilesMode.Search && this.query == query) return@setState this

        copy(mode = mode, request = Uninitialized, items = emptyList(), query = query)
    }

    companion object : MvRxViewModelFactory<LottiefilesState> {
        @JvmStatic
        override fun create(activity: FragmentActivity, state: LottiefilesState): LottiefilesViewModel {
            val service = (activity.applicationContext as LottieApplication).lottiefilesService
            return LottiefilesViewModel(state, service)
        }

    }
}

class LottiefilesFragment : BaseEpoxyFragment() {
    private val viewModel: LottiefilesViewModel by fragmentViewModel()

    override fun EpoxyController.buildModels() = withState(viewModel) { state ->
        marquee {
            id("lottiefiles")
            title(R.string.lottiefiles)
            subtitle(R.string.lottiefiles_airbnb)
        }

        lottiefilesTabBar {
            id("mode")
            mode(state.mode)
            recentClickListener { _ -> viewModel.setMode(LottiefilesMode.Recent) }
            popularClickListener { _ -> viewModel.setMode(LottiefilesMode.Popular) }
            searchClickListener { _ -> viewModel.setMode(LottiefilesMode.Search) }
        }

        if (state.mode == LottiefilesMode.Search) {
            searchInputItemView {
                id("search")
                searchClickListener { viewModel.setMode(LottiefilesMode.Search, it) }
            }
        }

        state.items.forEach {
            val args = CompositionArgs(animationData = it)
            animationItemView {
                id(it.id)
                animationData(it)
                clickListener { _ ->
                    startActivity(PlayerActivity.intent(requireContext(), args))
                }
                onBind { _, _, _ -> viewModel.fetchMoreItems() }
            }
        }

        if (state.request is Loading) {
            loadingView {
                id("loading")
                onBind { _, _, _ -> viewModel.fetchMoreItems() }
            }
        }
    }
}