package com.gh.gamecenter.feature.selector

import android.database.Cursor
import android.view.View
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import com.gh.gamecenter.livedata.Event
import com.zhihu.matisse.internal.entity.Album
import com.zhihu.matisse.internal.entity.Item
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch

class LocalMediaViewModel(val maxSelectionSize: Int) : ViewModel() {

    private val _previewMediaLiveData = MutableLiveData<Event<PreviewData>>()
    val previewMediaLiveData: LiveData<Event<PreviewData>> = _previewMediaLiveData

    private val _resultLiveData = MutableLiveData<Boolean>()
    val resultLiveData: LiveData<Boolean> = _resultLiveData

    val localMediaRepo: LocalMediaRepository = LocalMediaRepository()

    val selectedCountLiveData: LiveData<Int> =
        localMediaRepo.selectedItemListFlow.map { it.size }.asLiveData()

    val selectedMediaListLiveData: LiveData<List<Item>> =
        localMediaRepo.selectedItemListFlow.asLiveData()

    val dataListLiveData: LiveData<List<Item>> =
        localMediaRepo.itemListFlow.asLiveData()

    val selectedItemList
        get() = localMediaRepo.selectedItemListFlow.value

    private var mediaAlbum: Album? = null

    fun updateAlbum(album: Album) {
        mediaAlbum = album
    }

    fun updateAlbumCursor(cursor: Cursor?) {
        localMediaRepo.updateAlbumCursor(cursor)
    }

    fun previewImage(
        onlySelected: Boolean,
        positionInAlbum: Int = 0,
        previewItem: Item? = null,
        urlAndViewMap: Map<String, View> = emptyMap()
    ) {
        if (onlySelected) {
            _previewMediaLiveData.value = Event(PreviewData(selectedItemList, null, 0, previewItem, urlAndViewMap))
        } else {
            _previewMediaLiveData.value =
                Event(PreviewData(selectedItemList, mediaAlbum, positionInAlbum, previewItem, urlAndViewMap))
        }
    }

    fun addSelection(item: Item): Boolean {
        if (selectedItemList.size >= maxSelectionSize) {
            return false
        }

        localMediaRepo.addSelection(item)

        return true
    }

    fun setSelection(item: Item) {
        localMediaRepo.setSelection(item)
    }

    fun removeSelection(item: Item) {
        localMediaRepo.removeSelection(item)
    }

    fun isSelected(item: Item): Boolean {
        return selectedItemList.contains(item)
    }

    fun indexOfSelected(item: Item): Int {
        return selectedItemList.indexOf(item)
    }

    fun refreshAlbumMediaData() {
        viewModelScope.launch {
            localMediaRepo.refreshAlbumMediaData()
        }
    }

    /**
     * 发送选择完成事件
     */
    fun postSelectedResult() {
        _resultLiveData.postValue(true)
    }

    override fun onCleared() {
        super.onCleared()

        localMediaRepo.closeCursor()
    }

    class Factory(private val maxSelectionSize: Int) : ViewModelProvider.NewInstanceFactory() {
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return LocalMediaViewModel(maxSelectionSize) as T
        }
    }

}