package com.base.browserwhite.ui.activity.mediabrowser

import android.graphics.Color
import android.net.Uri
import android.widget.SeekBar
import android.widget.SeekBar.OnSeekBarChangeListener
import androidx.activity.addCallback
import androidx.core.view.updatePadding
import androidx.lifecycle.lifecycleScope
import androidx.media3.common.MediaItem
import androidx.media3.common.Player
import androidx.media3.exoplayer.ExoPlayer
import com.base.browserwhite.databinding.ActivityMediaVideoDetailBinding
import com.base.browserwhite.ui.activity.BaseActivity
import com.base.browserwhite.ui.views.DialogViews.showDeleteTipDialog
import com.base.browserwhite.utils.BarUtils
import com.base.browserwhite.utils.IntentEx.shareAction
import com.base.browserwhite.utils.LogEx
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import java.io.File

class MediaVideoDetailActivity : BaseActivity<ActivityMediaVideoDetailBinding>() {
    private val TAG = "MediaVideoDetailActivity"

    override val binding: ActivityMediaVideoDetailBinding by lazy {
        ActivityMediaVideoDetailBinding.inflate(layoutInflater)
    }
    private lateinit var player: ExoPlayer
    private var job: Job? = null
    private var playEnd: Boolean = false
    private var uri: String = ""

    override fun initView() {
        BarUtils.setStatusBarLightMode(this, true)
        BarUtils.setStatusBarColor(this, Color.TRANSPARENT)
        binding.root.updatePadding(top = BarUtils.getStatusBarHeight())

        uri = intent.extras?.getString("uri") ?: ""
        LogEx.logDebug(TAG, "uri=$uri")

        player = ExoPlayer.Builder(this).build()
        binding.playerView.player = player

        val mediaItem = MediaItem.fromUri(uri)

        player.setMediaItem(mediaItem)
//        player.playWhenReady = false
        player.addListener(object : Player.Listener {
            override fun onIsPlayingChanged(isPlaying: Boolean) {
                super.onIsPlayingChanged(isPlaying)
                binding.ivPlayPause.isSelected = isPlaying
            }

            override fun onPlaybackStateChanged(playbackState: Int) {
                super.onPlaybackStateChanged(playbackState)
                LogEx.logDebug(TAG, "playbackState=$playbackState")
                //2,3,4
                if (playbackState == Player.STATE_READY) {
                    playEnd = false
                    if (job == null) {
                        job = upDatePositionJob()
                    }
                    // 获取总时长
                    binding.root.post {
                        val duration = player.duration
                        binding.seekbar.max = duration.toInt()
                        binding.tvDuration.text = duration.toTimeString()
                    }

                } else if (playbackState == Player.STATE_ENDED) {
                    playEnd = true
                    job?.cancel()
                    job = null
                }
            }

            override fun onPositionDiscontinuity(oldPosition: Player.PositionInfo, newPosition: Player.PositionInfo, reason: Int) {
                super.onPositionDiscontinuity(oldPosition, newPosition, reason)
                // 播放位置发生不连续变化
            }

        })
        player.prepare()
        player.play()

    }

    fun upDatePositionJob() = lifecycleScope.launch(Dispatchers.Main) {
        while (isActive) {
            val currentPosition = player.currentPosition
            binding.seekbar.progress = currentPosition.toInt()
            binding.tvCurrentPosition.text = currentPosition.toTimeString()
            delay(100)
        }
    }

    override fun initListener() {
        super.initListener()

        onBackPressedDispatcher.addCallback {
            finishToMain()
        }
        binding.ivFanhui.setOnClickListener {
            onBackPressedDispatcher.onBackPressed()
        }

        binding.ivPlayPause.setOnClickListener {
            if (player.isPlaying) {
                player.pause()
                job?.cancel()
                job = null
            } else {
                if (playEnd) {
                    player.seekTo(0)
                } else {
                    player.play()
                    if (job == null) {
                        job = upDatePositionJob()
                    }
                }
            }
        }
        binding.seekbar.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                if (fromUser) {
                    player.seekTo(progress.toLong())
                }
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {
            }

            override fun onStopTrackingTouch(seekBar: SeekBar?) {

            }
        })
        binding.ivDelete.setOnClickListener {
            showDeleteTipDialog {
                val path = intent.extras?.getString("path") ?: ""
                val file = File(path)
                runCatching {
                    file.delete()
                }
                finish()
            }
        }
        binding.ivShare.setOnClickListener {
            this.shareAction(Uri.parse(uri), intent.extras?.getString("mimeType") ?: "")
        }
    }

    override fun onPause() {
        super.onPause()
        player.pause()

        job?.cancel()
        job = null
    }

    override fun onResume() {
        super.onResume()
        if (player.isPlaying && job == null) {
            job = upDatePositionJob()
        }
    }

    fun Long.toTimeString(): String {
        val seconds = this / 1000
        val minutes = seconds / 60
        val hours = minutes / 60

        val secondsStr = if (seconds % 60 < 10) "0${seconds % 60}" else "${seconds % 60}"
        val minutesStr = if (minutes % 60 < 10) "0${minutes % 60}" else "${minutes % 60}"
        val hoursStr = if (hours < 10) "0$hours" else hours.toString()

        return if (hours > 0) "$hoursStr:$minutesStr:$secondsStr" else "$minutesStr:$secondsStr"
    }
}