package com.adealink.weparty.image.preview

import android.Manifest
import android.annotation.SuppressLint
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.GestureDetector
import android.view.MotionEvent
import android.webkit.URLUtil
import androidx.fragment.app.viewModels
import com.adealink.frame.aab.util.getCompatString
import com.adealink.frame.base.Rlt
import com.adealink.frame.base.fastLazy
import com.adealink.frame.effect.video.controller.VideoScalingMode
import com.adealink.frame.mvvm.view.viewBinding
import com.adealink.weparty.commonui.BaseFragment
import com.adealink.weparty.commonui.dialogfragment.CommonTextActionDialog
import com.adealink.weparty.commonui.ext.gone
import com.adealink.weparty.commonui.ext.show
import com.adealink.weparty.commonui.toast.util.showToast
import com.adealink.weparty.commonui.widget.CommonDialog
import com.adealink.weparty.image.R
import com.adealink.weparty.image.data.TAG_IMAGE_PREVIEW
import com.adealink.weparty.image.databinding.FragmentVideoPreviewBinding
import com.adealink.weparty.image.viewmodel.ImagePreviewExtensionViewModel
import com.adealink.weparty.image.viewmodel.Resource
import com.adealink.weparty.image.viewmodel.VideoViewModel
import com.adealink.weparty.module.image.data.VideoItem
import com.adealink.weparty.permission.PermissionUtils
import com.adealink.weparty.R as APP_R

class VideoPreviewFragment : BaseFragment(R.layout.fragment_video_preview) {

    companion object {
        private const val KEY_VIDEO = "video"
        private const val STORAGE_PERMISSION_DIALOG = "storage_permission_dialog"

        fun newInstance(video: VideoItem): VideoPreviewFragment {
            val fragment = VideoPreviewFragment()
            val bundle = Bundle()
            bundle.putParcelable(KEY_VIDEO, video)
            fragment.arguments = bundle
            return fragment
        }
    }

    private val videoViewModel by viewModels<VideoViewModel>()
    private val imagePreviewExtensionViewModel by viewModels<ImagePreviewExtensionViewModel>()
    private val binding by viewBinding(FragmentVideoPreviewBinding::bind)
    private var videoItem: VideoItem? = null
    private var isVideoReady: Boolean = false
    private var videoLocalPath: String? = null
    //长按和下滑检测
    private val gestureDetector by fastLazy {
        GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
            private val SWIPE_THRESHOLD = 100
            private val SWIPE_VELOCITY_THRESHOLD = 100

            override fun onFling(
                e1: MotionEvent?,
                e2: MotionEvent,
                velocityX: Float,
                velocityY: Float
            ): Boolean {
                if (e1 == null) return false
                val deltaY = e2.y - e1.y
                if (deltaY > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    activity?.finish()
                    return true
                }
                return false
            }

            override fun onLongPress(e: MotionEvent) {
                super.onLongPress(e)
                if (!isVideoReady) {
                    return
                }
                showLongClickActionDialog()
            }
        })
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        videoItem = arguments?.getParcelable(KEY_VIDEO)
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun initViews() {
        super.initViews()
        binding.videoView.setOnTouchListener { _, event ->
            gestureDetector.onTouchEvent(event)
            true
        }
    }

    override fun observeViewModel() {
        super.observeViewModel()
        imagePreviewExtensionViewModel.saveResult.observe(viewLifecycleOwner) {
            when(it) {
                is Resource.Success -> {
                    showToast(R.string.image_save_success)
                }
                is Resource.Error -> {
                    Log.e(TAG_IMAGE_PREVIEW, "saveResult error, e:${it.error?.message}")
                    showToast(R.string.image_save_failed)
                }
                is Resource.Loading -> {
                    //Ntd.
                }
            }
        }
    }

    override fun loadData() {
        super.loadData()
        val videoUrl = videoItem?.url?: return
        if (URLUtil.isNetworkUrl(videoUrl)) {
            binding.vVideoLoading.show()
            videoViewModel.downloadVideo(videoUrl).observe(viewLifecycleOwner) {
                binding.vVideoLoading.gone()
                when(it) {
                    is Rlt.Success -> {
                        videoLocalPath = it.data.use()
                    }
                    is Rlt.Failed -> {

                    }
                }
                videoLocalPath?.let { path ->
                    playVideo(path)
                }
            }
            return
        }
        videoLocalPath = videoUrl
        playVideo(videoUrl)
    }

    private fun playVideo(url: String) {
        binding.videoView.setVideoScalingMode(VideoScalingMode.ScaleToFit)
        binding.videoView.setAutoPlay(true)
        binding.videoView.setLoopCount(1)
        binding.videoView.setShowControllerBar(true)
        binding.videoView.setUri(url)
    }

    private fun showLongClickActionDialog() {
        if (!isAdded) {
            return
        }
        CommonTextActionDialog.Builder()
            .addItem(R.id.image_preview_save, APP_R.string.common_save)
            .actionListener(object : CommonTextActionDialog.CommonTextActionListener {
                override fun onActionClick(viewId: Int) {
                    when (viewId) {
                        R.id.image_preview_save -> {
                            checkStoragePermissionAndSaveVideo()
                        }
                    }
                }
            }).build().show(childFragmentManager)
    }

    //保存视频需要检查存储权限
    @SuppressLint("CheckResult")
    private fun checkStoragePermissionAndSaveVideo() {
        val act = activity ?: return
        val permission = getVideoPermission()
        if (PermissionUtils.hasPermissions(act, *permission)) {
            imagePreviewExtensionViewModel.saveLocalVideoToAlbum(videoLocalPath)
        } else {
            PermissionUtils.getRxPermissions(act)
                .request(*permission).subscribe { granted ->
                    if (granted) {
                        imagePreviewExtensionViewModel.saveLocalVideoToAlbum(videoLocalPath)
                    } else {
                        showPermissionNoGrantedDialog()
                    }
                }
        }
    }

    private fun getVideoPermission(): Array<String> {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            arrayOf(Manifest.permission.READ_MEDIA_VIDEO)
        } else {
            arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE)
        }
    }

    private fun showPermissionNoGrantedDialog() {
        childFragmentManager.findFragmentByTag(STORAGE_PERMISSION_DIALOG)?.let {
            childFragmentManager.beginTransaction().remove(it).commitNowAllowingStateLoss()
        }
        val permissionDialog = CommonDialog.Builder()
            .message(getCompatString(R.string.image_video_save_storage_permission_no_granted))
            .onPositive {
                PermissionUtils.startPermissionSettingActivity(this)
            }
            .dismissAfterClick(true)
            .setShowDefaultCancel(true)
            .build()
        permissionDialog.show(childFragmentManager, STORAGE_PERMISSION_DIALOG)
    }

}