package com.adealink.weparty.profile.dynamic.viewmodel

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.adealink.frame.base.CommonDataNullError
import com.adealink.frame.base.Rlt
import com.adealink.frame.log.Log
import com.adealink.frame.mvvm.livedata.OnceMutableLiveData
import com.adealink.frame.mvvm.viewmodel.BaseViewModel
import com.adealink.frame.oss.data.UploadFile
import com.adealink.frame.util.AppUtil
import com.adealink.frame.util.FileProvider7
import com.adealink.weparty.App
import com.adealink.weparty.commonui.ext.isSuccess
import com.adealink.weparty.commonui.mediapicker.imageselect.util.getVideoThumbnail
import com.adealink.weparty.commonui.mediapicker.videoselect.util.getVideoDuration
import com.adealink.weparty.commonui.toast.util.showFailedToast
import com.adealink.weparty.commonui.toast.util.showToast
import com.adealink.weparty.image.PHOTO_WALL_IMAGE_MAX_HEIGHT
import com.adealink.weparty.image.PHOTO_WALL_IMAGE_MAX_SIZE_KB
import com.adealink.weparty.image.PHOTO_WALL_IMAGE_MAX_WIDTH
import com.adealink.weparty.image.PHOTO_WALL_IMAGE_MIN_QUALITY
import com.adealink.weparty.module.image.data.MediaData
import com.adealink.weparty.module.image.data.PhotoData
import com.adealink.weparty.module.image.data.VideoData
import com.adealink.weparty.profile.R
import com.adealink.weparty.profile.datasource.remote.DynamicHttpService
import com.adealink.weparty.profile.dynamic.data.DynamicMediaData
import com.adealink.weparty.profile.dynamic.data.MediaType
import com.adealink.weparty.profile.dynamic.data.PublishDynamicReq
import com.adealink.weparty.profile.dynamic.data.publishNewDynamicLD
import com.adealink.weparty.profile.edit.data.AddPhotoItemData
import com.adealink.weparty.profile.edit.data.BaseMediaItemData
import com.adealink.weparty.profile.edit.data.PhotoItemData
import com.adealink.weparty.profile.edit.data.VideoItemData
import com.adealink.weparty.util.uploadPhotos
import com.adealink.weparty.util.uploadVideo
import kotlinx.coroutines.launch
import java.io.File

class PublishDynamicViewModel : BaseViewModel() {

    companion object {
        private const val TAG = "PublishDynamicViewModel"
        const val MAX_PHOTO_COUNT = 6
    }

    private val dynamicHttpService by lazy {
        App.instance.networkService.getHttpService(DynamicHttpService::class.java)
    }

    val mediaList = mutableListOf<MediaData>()

    val mediaItemList = mutableListOf<BaseMediaItemData>()
    val mediaItemListLD = MutableLiveData<MutableList<BaseMediaItemData>>()

    init {
        onMediaListChanged()
    }

    fun addPhoto(path: String?, uri: String?) {
        viewModelScope.launch {
            mediaList.add(
                PhotoData(
                    url = null,
                    path = path,
                    uri = uri
                )
            )
            onMediaListChanged()
        }
    }

    fun addVideo(path: String?, uri: String?) {
        viewModelScope.launch {
            if (path == null) {
                mediaList.clear()
                onMediaListChanged()
                return@launch
            }
            //检查所选视频的时长
            getVideoDuration(path).let { rlt ->
                when (rlt) {
                    is Rlt.Failed -> {
                        showFailedToast(rlt)
                        mediaList.clear()
                        onMediaListChanged()
                        return@launch
                    }

                    is Rlt.Success -> {
                        val duration = rlt.data
                        if (duration > 60_000L) { //60s
                            //视频时长大于60s
                            mediaList.clear()
                            onMediaListChanged()
                            showToast(R.string.profile_dynamic_video_duration_too_long)
                            return@launch
                        }
                    }
                }
            }
            val videoData = VideoData(
                url = null,
                path = path,
                uri = uri
            )
            val videoFramePath = (getVideoThumbnail(path) as? Rlt.Success)?.data
            if (!videoFramePath.isNullOrEmpty()) {
                videoData.cover =
                    PhotoData(
                        null,
                        videoFramePath,
                        FileProvider7.getUriForFile(AppUtil.appContext, File(videoFramePath))
                            ?.toString()
                    )
            }
            mediaList.clear()
            mediaList.add(videoData)
            onMediaListChanged()
        }
    }

    fun removePhoto(data: PhotoData) {
        viewModelScope.launch {
            mediaList.remove(data)
            onMediaListChanged()
        }
    }

    fun deleteVideo() {
        viewModelScope.launch {
            mediaList.clear()
            onMediaListChanged()
        }
    }

    fun isVideoDynamic(): Boolean {
        return mediaList.size == 1 && mediaList.first() is VideoData
    }

    private fun onMediaListChanged() {
        if (isVideoDynamic()) {
            mediaItemList.clear()
            mediaItemList.add(VideoItemData(mediaList.first() as VideoData))
            mediaItemListLD.send(mediaItemList)
            return
        }
        val photoList = mediaList.take(MAX_PHOTO_COUNT)
        mediaItemList.clear()
        for ((i, data) in photoList.withIndex()) {
            if (data is PhotoData) {
                mediaItemList.add(PhotoItemData(data))
            } else if (data is VideoData) {
                mediaItemList.add(VideoItemData(data))
            }
        }
        //小于9张图片,可以继续添加图片
        if (mediaItemList.size < MAX_PHOTO_COUNT) {
            mediaItemList.add(AddPhotoItemData)
        }
        mediaItemListLD.send(mediaItemList)
    }

    //调整勋章位置
    val adjustPhotoPositionLD = MutableLiveData<Pair<Int, Int>>()
    fun adjustPhotoPosition(fromPosition: Int, toPosition: Int) {
        Log.d(TAG, "adjustPhotoPosition, from:$fromPosition, to:$toPosition")
        if (fromPosition < 0 || toPosition < 0) return
        val itemCount = mediaItemList.size
        if (fromPosition > itemCount || toPosition > itemCount) return

        viewModelScope.launch {
            mediaItemList.add(toPosition, mediaItemList.removeAt(fromPosition))
            mediaList.clear()
            for (itemData in mediaItemList) {
                if (itemData is PhotoItemData) {
                    mediaList.add(itemData.data)
                }
            }
            adjustPhotoPositionLD.send(Pair(fromPosition, toPosition))
        }
    }


    fun publish(content: String?): LiveData<Rlt<Any>> {
        val liveData = OnceMutableLiveData<Rlt<Any>>()
        viewModelScope.launch {
            if (content.isNullOrEmpty() && mediaList.isEmpty()) {
                liveData.send(Rlt.Failed(CommonDataNullError()))
                return@launch
            }
            val photoItems = mediaList.mapNotNull {
                it as? PhotoData
            }
            val videoItems = mediaList.mapNotNull {
                it as? VideoData
            }

            val rlt = if (videoItems.isNotEmpty()) {
                //上传视频
                val uploadVideoRlt = uploadVideo(
                    videoItems
                )
                when (uploadVideoRlt) {
                    is Rlt.Failed -> {
                        liveData.send(uploadVideoRlt)
                        return@launch
                    }

                    is Rlt.Success -> {
                    }
                }
                val videoMediaReqList = videoItems.mapNotNull { item ->
                    val remoteUrl = item.url
                    if (remoteUrl.isNullOrEmpty()) {
                        null
                    } else {
                        DynamicMediaData(remoteUrl, MediaType.VIDEO.type, item.cover?.url)
                    }
                }
                if (content.isNullOrEmpty() && videoMediaReqList.isEmpty()) {
                    Rlt.Failed(CommonDataNullError())
                } else {
                    dynamicHttpService.publishDynamic(
                        PublishDynamicReq(
                            content = content,
                            medias = videoMediaReqList,
                        )
                    )
                }
            } else {
                //上传图片
                val uploadPhotoRlt = uploadPhotos(
                    photoItems,
                    PHOTO_WALL_IMAGE_MAX_WIDTH,
                    PHOTO_WALL_IMAGE_MAX_HEIGHT,
                    PHOTO_WALL_IMAGE_MAX_SIZE_KB,
                    PHOTO_WALL_IMAGE_MIN_QUALITY,
                    UploadFile.FileType.IMAGE
                )
                when (uploadPhotoRlt) {
                    is Rlt.Failed -> {
                        liveData.send(uploadPhotoRlt)
                        return@launch
                    }

                    is Rlt.Success -> {
                    }
                }
                val photoMediaReqList = photoItems.mapNotNull { item ->
                    val remoteUrl = item.url
                    if (remoteUrl.isNullOrEmpty()) {
                        null
                    } else {
                        DynamicMediaData(remoteUrl, MediaType.PHOTO.type, null)
                    }
                }
                if (content.isNullOrEmpty() && photoMediaReqList.isEmpty()) {
                    Rlt.Failed(CommonDataNullError())
                } else {
                    dynamicHttpService.publishDynamic(
                        PublishDynamicReq(
                            content = content,
                            medias = photoMediaReqList
                        )
                    )
                }
            }

            if (rlt.isSuccess) {
                publishNewDynamicLD.send(Unit)
            }
            liveData.send(rlt)
        }
        return liveData
    }

}