package com.adealink.weparty.commonui.mediapicker.videoselect.viewmodel

import android.database.Cursor
import android.os.Build
import android.provider.MediaStore
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.adealink.frame.base.CommonDataNullError
import com.adealink.frame.base.CommonIOError
import com.adealink.frame.base.Rlt
import com.adealink.frame.coroutine.dispatcher.Dispatcher
import com.adealink.frame.mvvm.viewmodel.BaseViewModel
import com.adealink.frame.util.AppUtil
import com.adealink.frame.util.FileProvider7
import com.adealink.frame.util.closeQuietly
import com.adealink.weparty.commonui.mediapicker.videoselect.data.VideoItem
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File

class VideoSelectViewModel : BaseViewModel() {

    val videosLD: LiveData<Rlt<List<VideoItem>>> = MutableLiveData()

    fun loadVideos() {
        viewModelScope.launch {
            withContext(Dispatcher.WENEXT_THREAD_POOL) {
                val videos = arrayListOf<VideoItem>()
                val projection: Array<String> = getMediaProjection()
                val selection = MediaStore.Files.FileColumns.MEDIA_TYPE + "=?"
//                AND ${MediaStore.Images.Media.DATA} like ?
                val argsList = arrayListOf<String>()
                argsList.add(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO.toString())
//                argsList.add("%video%")
                val orderBy = MediaStore.Files.FileColumns._ID

                var cursor: Cursor? = null
                try {
                    cursor = AppUtil.appContext.contentResolver.query(
                        MediaStore.Files.getContentUri("external"),
                        projection, selection, argsList.toTypedArray(), orderBy
                    )
                    if (cursor == null) {
                        videosLD.send(Rlt.Failed(CommonDataNullError()))
                        return@withContext
                    }

                    val idIndex = cursor.getColumnIndex(MediaStore.Files.FileColumns._ID)
                    val dataIndex = cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA)
                    val durationIndex = cursor.getColumnIndex(MediaStore.Video.Media.DURATION)
                    val sizeIndex = cursor.getColumnIndex(MediaStore.Files.FileColumns.SIZE)

                    while (cursor.moveToNext()) {
                        val path = cursor.getString(dataIndex)
                        if (path.isNullOrEmpty()) {
                            continue
                        }

                        val url =
                            FileProvider7.getUriForFile(AppUtil.appContext, File(path))?.toString()
                        if (url.isNullOrEmpty()) {
                            continue
                        }

                        val id = cursor.getInt(idIndex)
                        val duration = cursor.getInt(durationIndex)
                        val size = cursor.getLong(sizeIndex)
                        videos.add(VideoItem(id, path, url, duration, size))
                    }

                    videosLD.send(Rlt.Success(videos))
                } catch (e: Exception) {
                    Rlt.Failed(CommonIOError(e))
                } finally {
                    closeQuietly(cursor)
                }

            }
        }

    }

    private fun getMediaProjection(): Array<String> {
        val projection: Array<String> = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            arrayOf(
                MediaStore.Files.FileColumns._ID,
                MediaStore.Files.FileColumns.MEDIA_TYPE,
                MediaStore.Files.FileColumns.DATA,
                MediaStore.Images.ImageColumns.ORIENTATION,
                MediaStore.Video.Media.DURATION,
                MediaStore.Files.FileColumns.DATE_MODIFIED,
                MediaStore.Images.Thumbnails.WIDTH,
                MediaStore.Images.Thumbnails.HEIGHT,
                MediaStore.MediaColumns.SIZE,
                MediaStore.MediaColumns.DISPLAY_NAME,
                MediaStore.MediaColumns.MIME_TYPE
            )
        } else {
            arrayOf(
                MediaStore.Files.FileColumns._ID,
                MediaStore.Files.FileColumns.MEDIA_TYPE,
                MediaStore.Files.FileColumns.DATA,
                MediaStore.Images.ImageColumns.ORIENTATION,
                MediaStore.Video.Media.DURATION,
                MediaStore.Files.FileColumns.DATE_MODIFIED,
                MediaStore.Video.Media.RESOLUTION,
                MediaStore.Images.Thumbnails.WIDTH,
                MediaStore.Images.Thumbnails.HEIGHT,
                MediaStore.MediaColumns.SIZE,
                MediaStore.MediaColumns.DISPLAY_NAME,
                MediaStore.MediaColumns.MIME_TYPE
            )
        }
        return projection
    }

}