package com.gh.gamecenter.video.upload.view

import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Paint
import android.media.MediaMetadataRetriever
import android.media.ThumbnailUtils
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.TextPaint
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.view.Gravity
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.CheckedTextView
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import com.gh.common.util.*
import com.gh.common.util.LogUtils
import com.gh.gamecenter.CropImageActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.common.*
import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
import com.gh.gamecenter.common.callback.CancelListener
import com.gh.gamecenter.common.callback.ConfirmListener
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.entity.NotificationUgc
import com.gh.gamecenter.common.entity.SimpleGameEntity
import com.gh.gamecenter.common.mvvm.Status
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.DrawableView
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.databinding.ActivityVideoUplaodBinding
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.newsdetail.NewsDetailActivity
import com.gh.gamecenter.qa.editor.GameActivity
import com.gh.gamecenter.video.label.VideoLabelActivity
import com.gh.gamecenter.video.poster.video.VideoPosterFragment
import com.gh.gamecenter.video.upload.OnUploadListener
import com.gh.gamecenter.video.upload.UploadManager
import com.google.android.flexbox.FlexboxLayout
import com.lightgame.utils.Util_System_Keyboard
import com.lightgame.utils.Utils
import com.therouter.TheRouter
import com.zhihu.matisse.Matisse
import com.zhihu.matisse.internal.utils.PathUtils
import org.json.JSONArray
import java.io.File
import java.io.FileOutputStream

class UploadVideoActivity : ToolBarActivity() {

    private lateinit var mBinding: ActivityVideoUplaodBinding

    private lateinit var mViewModel: UploadVideoViewModel

    private lateinit var mDraftMenu: MenuItem

    private var mProcessingDialog: WaitingDialogFragment? = null

    private var mVideoLink: VideoLinkEntity? = null

    private var mVideoFileEntity: VideoFileEntity? = null

    private var mUpdatedPosterPath = ""

    // 仅用于数据统计
    private lateinit var mEntranceLink: String
    private lateinit var mPath: String
    private var mActivityLabelEntity: ActivityLabelEntity? = null


    override fun getLayoutId(): Int {
        return R.layout.activity_video_uplaod
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_GAME_CODE && resultCode == Activity.RESULT_OK) {
            val game = data?.getParcelableExtra<GameEntity>(GameEntity::class.java.simpleName)
            if (game != null) {
                mViewModel.gameEntity = SimpleGameEntity(game.id, game.name ?: "")
                mBinding.gameName.text = game.name
                mBinding.gameName.setTextColor(resources.getColor(com.gh.gamecenter.common.R.color.text_primary))
            }
        } else if (requestCode == REQUEST_CODE_IMAGE_CROP && resultCode == Activity.RESULT_OK) {
            if (data != null) {
                val imagePath = data.getStringExtra(CropImageActivity.RESULT_CLIP_PATH)
                mUpdatedPosterPath = imagePath ?: ""
                mBinding.videoPoster.setImageURI("file://$imagePath")
                LogUtils.logVideoStreamingUpload("更换封面", mPath, mEntranceLink, "")
                checkPostButtonStatus()
            }
        } else if (requestCode == REQUEST_CODE_CHOOSE_LABEL && resultCode == Activity.RESULT_OK) {
            if (data != null) {
                mActivityLabelEntity = data.getParcelableExtra(ActivityLabelEntity::class.java.simpleName)
                mBinding.activityContainer.visibility = View.VISIBLE
                mBinding.activityTv.text = mActivityLabelEntity?.name
                mBinding.activityTv.requestLayout()
                checkPostButtonStatus()
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        VideoPosterFragment.clearVideoCoverCache(this)
        mVideoLink = intent.getParcelableExtra(VideoLinkEntity::class.java.simpleName)
        mEntranceLink = intent.getStringExtra(EntranceConsts.KEY_ENTRANCE_LINK) ?: ""
        mPath = intent.getStringExtra(EntranceConsts.KEY_PATH) ?: "其他"

        // toolbar
        setToolbarMenu(R.menu.menu_text)
        mDraftMenu = getMenuItem(R.id.menu_text)
        val container = mDraftMenu.actionView?.findViewById<View>(R.id.menu_text)
        val text = container?.findViewById<TextView>(R.id.layout_menu_text)
        text?.text = "存草稿"

        // view
        mBinding = ActivityVideoUplaodBinding.bind(mContentView)
        mBinding.gameNameHint.text = resources.getString(R.string.upload_game_name_hint).fromHtml()
        mBinding.gameTitleHint.text = resources.getString(R.string.upload_game_title_hint).fromHtml()
        mBinding.gameCategoryHint.text = resources.getString(R.string.upload_game_category_hint).fromHtml()
        mBinding.videoSource.text = resources.getString(R.string.upload_game_video_source_hint).fromHtml()
        mBinding.gameTitle.filters = arrayOf(TextHelper.getFilter(100, "最多输入100个字"))
        mBinding.gameTitle.setTextChangedListener { _, _, _, _ ->
            checkPostButtonStatus()
        }

        mBinding.gameTitle.setTextChangedListener(action = { s, _, _, _ ->
            mBinding.titleCounter.text = (s.length.toString() + "/100")
        })
        mBinding.gameName.setOnClickListener {
            startActivityForResult(GameActivity.getIntent(this, GameActivity.SELECT_GAME_TITLE), REQUEST_GAME_CODE)
        }
        mBinding.postButton.setOnClickListener {
            verifyData(false)
            LogUtils.logVideoStreamingUpload("点击提交", mPath, mEntranceLink, "")
            LogUtils.logVideoStreamingUpload("提交视频", mPath, mEntranceLink, "")
        }
        mBinding.videoPosterPatchHint.setOnClickListener {
            startMediaStore()
            MtaHelper.onEvent("上传视频", "上传视频", "换封面")
            LogUtils.logVideoStreamingUpload("换封面", mPath, mEntranceLink, "")
        }
        mBinding.chooseActivityIv.setOnClickListener {
            Util_System_Keyboard.hideSoftKeyboard(this, mBinding.gameTitle)
            if (mBinding.reprintTv.isChecked) {
                ToastUtils.showToast("必须是原创才能参加活动")
                return@setOnClickListener
            }

            startActivityForResult(
                VideoLabelActivity.getIntent(
                    this, mActivityLabelEntity?.id
                        ?: ""
                ), REQUEST_CODE_CHOOSE_LABEL
            )
            LogUtils.logVideoStreamingUpload("查看活动标签", mPath, mEntranceLink, "")
        }
        mBinding.deleteActivity.setOnClickListener {
            mActivityLabelEntity = null
            mBinding.activityTv.text = ""
            mBinding.activityContainer.visibility = View.GONE
            checkPostButtonStatus()
        }

        mBinding.originalTv.setOnClickListener {
            switchVideoSource(true)
        }
        mBinding.reprintTv.setOnClickListener {
            if (mActivityLabelEntity != null) {
                DialogHelper.showDialog(this, "温馨提示", "修改的内容将导致取消参与活动哦～", "确定修改", "暂不修改", {
                    switchVideoSource(false)
                    mActivityLabelEntity = null
                    mBinding.activityContainer.visibility = View.GONE
                    mBinding.activityTv.text = ""
                })
            } else {
                switchVideoSource(false)
            }
        }

        uploadProtocolHandle()
        initViewModel()
        initDataAndUpload()

        if (mViewModel.videoPatch != null) {
            setNavigationTitle("视频编辑")
            LogUtils.logVideoStreamingUpload("进入视频编辑页", mPath, mEntranceLink, "")
        } else {
            setNavigationTitle("视频上传")
            LogUtils.logVideoStreamingUpload("进入视频上传页", mPath, mEntranceLink, "")
        }

        if (mViewModel.gameEntity != null) {
            mBinding.gameName.text = mViewModel.gameEntity?.name ?: ""
            mBinding.gameName.setTextColor(resources.getColor(com.gh.gamecenter.common.R.color.text_primary))
        }
    }

    private fun switchVideoSource(isOriginal: Boolean) {
        Util_System_Keyboard.hideSoftKeyboard(this, mBinding.gameTitle)
        if (isOriginal) {
            mBinding.originalTv.isChecked = true
            mBinding.reprintTv.isChecked = false
            mBinding.watermarkGroup.visibility = View.VISIBLE
            mBinding.videoSourceEt.visibility = View.GONE
            mBinding.gameVideoSourceLine.visibility = View.VISIBLE
            mBinding.chooseActivityIv.setImageDrawable(
                ContextCompat.getDrawable(
                    this,
                    R.drawable.ic_upload_video_activity_enable
                )
            )
            mBinding.chooseActivityIv.background =
                ContextCompat.getDrawable(this, R.drawable.bg_upload_video_choose_activity_enable)
        } else {
            mBinding.originalTv.isChecked = false
            mBinding.reprintTv.isChecked = true
            mBinding.watermarkGroup.visibility = View.GONE
            mBinding.videoSourceEt.visibility = View.VISIBLE
            mBinding.gameVideoSourceLine.visibility = View.GONE
            mBinding.videoSourceEt.requestFocus()
            mBinding.chooseActivityIv.setImageDrawable(
                ContextCompat.getDrawable(
                    this,
                    R.drawable.ic_upload_video_activity_unenable
                )
            )
            mBinding.chooseActivityIv.background =
                ContextCompat.getDrawable(this, com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_999)
        }
    }

    private fun initViewModel() {
        // viewModel
        mViewModel = ViewModelProviders.of(this).get(UploadVideoViewModel::class.java)
        mViewModel.videoDraft = intent.getParcelableExtra(VideoDraftEntity::class.java.simpleName)
        mViewModel.videoPatch = intent.getParcelableExtra(VideoEntity::class.java.simpleName)
        mViewModel.gameEntity = intent.getParcelableExtra(SimpleGameEntity::class.java.simpleName)
        mViewModel.tagsLiveData.observe(this, Observer {
            createFlexContent(mBinding.gameTag, it, clickListener = { v, _ ->
                if (v is CheckedTextView) {
                    if (v.isChecked) {
                        v.isChecked = false
                    } else {
                        val gameTag = mBinding.gameTag
                        var selectCount = 0
                        for (index in 0 until gameTag.childCount) {
                            val cell = gameTag.getChildAt(index)
                            if (cell is CheckedTextView && cell.isChecked) selectCount++
                        }
                        if (selectCount >= 5) {
                            toast("最多选择5个标签")
                        } else {
                            v.isChecked = true
                        }
                    }
                }
            })
        })
        mViewModel.categoryLiveData.observe(this, Observer {
            val gameCategory = mBinding.gameCategory
            createFlexContent(gameCategory, it, clickListener = { v, _ ->
                if (v is CheckedTextView) {
                    for (index in 0 until gameCategory.childCount) {
                        val cell = gameCategory.getChildAt(index)
                        if (cell is CheckedTextView) cell.isChecked = false
                    }
                    v.isChecked = !v.isChecked
                }
            })
        })
        mViewModel.activityTagLiveData.observe(this, Observer {
            mBinding.activityFlexbox.goneIf(!it)
            if (it && !mVideoLink?.tagActivityId.isNullOrEmpty() && !mVideoLink?.tagActivityName.isNullOrEmpty()) {
                mActivityLabelEntity = ActivityLabelEntity(
                    mVideoLink?.tagActivityId
                        ?: "", mVideoLink?.tagActivityName ?: ""
                )
                mBinding.activityContainer.visibility = View.VISIBLE
                mBinding.activityTv.text = mActivityLabelEntity?.name
            }
        })
        mViewModel.processDialog.observeNonNull(this) {
            if (it.isShow) {
                if (mProcessingDialog?.dialog?.isShowing == true) {
                    mProcessingDialog?.uploadWaitingHint(it.msg)
                } else {
                    mProcessingDialog = WaitingDialogFragment.newInstance(it.msg, false)
                    mProcessingDialog?.show(supportFragmentManager, null)
                }
            } else {
                mProcessingDialog?.dismiss()
            }
        }
        mViewModel.postLiveData.observeNonNull(this) {
            if (it.status == Status.SUCCESS) {
                toast("提交成功，审核通过即可生效")

                if (it.data?.id.isNullOrEmpty()) {
                    setResult(RESULT_CODE_VIDEO)
                } else {
                    val intent = Intent()
                    intent.putExtra(MyVideoEntity::class.java.simpleName, it.data)
                    setResult(RESULT_CODE_VIDEO, intent)
                }
                finish()
                AppExecutor.uiExecutor.executeWithDelay(Runnable {
                    NotificationHelper.showNotificationHintDialog(NotificationUgc.VIDEO)
                }, 1000)
                LogUtils.logVideoStreamingUpload("提交成功", mPath, mEntranceLink, it.data?.id)
                UploadManager.deleteUploadData(mVideoFileEntity?.path)
            } else if (it.status == Status.ERROR) {
                ErrorHelper.handleError(this@UploadVideoActivity, it.exception?.response()?.errorBody()?.string())
            }
        }
        mViewModel.postDraftLiveData.observeNonNull(this) {
            if (it.status == Status.SUCCESS) {
                toast("保存成功")
                setResult(RESULT_CODE_DRAFT)
                finish()
            } else if (it.status == Status.ERROR) {
                ErrorHelper.handleError(this@UploadVideoActivity, it.exception?.response()?.errorBody()?.string())
            }
        }
        mViewModel.deleteDraftLiveData.observe(this, Observer {
            setResult(RESULT_CODE_DRAFT)
            finish()
        })
    }

    private fun initDataAndUpload() {
        val videoDraft = mViewModel.videoDraft
        val videoPatch = mViewModel.videoPatch
        if (videoPatch != null) {
            mBinding.gameName.text = videoPatch.gameName
            mBinding.gameName.setTextColor(resources.getColor(com.gh.gamecenter.common.R.color.text_tertiary))
            mBinding.gameTitle.setText(videoPatch.title)
            mBinding.gameTitle.setSelection(mBinding.gameTitle.text.toString().length)
            mBinding.gameName.isEnabled = false
            mDraftMenu.isVisible = false
            if (videoPatch.tagActivityId.isNotEmpty() && videoPatch.tagActivityName.isNotEmpty()) {
                mActivityLabelEntity = ActivityLabelEntity(videoPatch.tagActivityId, videoPatch.tagActivityName)
                mBinding.activityContainer.visibility = View.VISIBLE
                mBinding.activityTv.text = mActivityLabelEntity?.name
            }
            if (videoPatch.original == "yes") {
                switchVideoSource(true)
            } else if (videoPatch.original == "no") {
                switchVideoSource(false)
                mBinding.videoSourceEt.setText(videoPatch.source)
                mBinding.videoSourceEt.isEnabled = false
            }
            mBinding.originalTv.isEnabled = false
            mBinding.reprintTv.isEnabled = false
            ImageUtils.display(mBinding.videoPoster, videoPatch.poster)
            handleUploadSuccess(videoPatch.url)

            mBinding.watermarkSb.isChecked = videoPatch.watermark
            mBinding.watermarkClick.visibility = View.VISIBLE
            mBinding.watermarkClick.setOnClickListener {
                toast("不支持修改水印")
            }

            mBinding.postButton.isEnabled = false
            mBinding.postButton.setBackgroundResource(R.drawable.border_round_eee_999)
        } else if (videoDraft != null) {
            if (videoDraft.gameId.isNotEmpty()) {
                mViewModel.gameEntity = SimpleGameEntity(videoDraft.gameId, videoDraft.gameName)
                mBinding.gameName.text = videoDraft.gameName
                mBinding.gameName.setTextColor(resources.getColor(com.gh.gamecenter.common.R.color.text_primary))
            }
            if (videoDraft.tagActivityId.isNotEmpty() && videoDraft.tagActivityName.isNotEmpty()) {
                mActivityLabelEntity = ActivityLabelEntity(videoDraft.tagActivityId, videoDraft.tagActivityName)
                mBinding.activityContainer.visibility = View.VISIBLE
                mBinding.activityTv.text = mActivityLabelEntity?.name
            }
            if (videoDraft.original == "yes") {
                switchVideoSource(true)
            } else if (videoDraft.original == "no") {
                switchVideoSource(false)
                mBinding.videoSourceEt.setText(videoDraft.source)
            }
            mBinding.gameTitle.setText(videoDraft.title)
            mBinding.gameTitle.setSelection(mBinding.gameTitle.text.toString().length)
            initUpload(videoDraft.localPath)
        } else {
            if (mVideoLink != null) {
                mBinding.gameTitle.setText(mVideoLink?.title)
                mBinding.gameTitle.setSelection(mBinding.gameTitle.text.toString().length)
            }

            initUpload(intent.getStringExtra(EntranceConsts.KEY_PATH_VIDEO))
        }
    }

    private fun startMediaStore() {
        try {
            PermissionHelper.checkStoragePermissionBeforeAction(this) {
                val postcard = TheRouter.build(RouteConsts.activity.videoCoverEditActivity)

                val videoPath = if (mViewModel.videoDraft != null) {
                    mViewModel.videoDraft?.localPath
                } else {
                    intent.getStringExtra(EntranceConsts.KEY_PATH_VIDEO)
                }

                if (!videoPath.isNullOrEmpty()) {
                    postcard.withString(EntranceConsts.KEY_PATH_VIDEO, videoPath)
                } else {
                    val videoPatch = mViewModel.videoPatch
                    if (videoPatch != null) {
                        postcard.withParcelable(EntranceConsts.KEY_VIDEO_ENTITY, videoPatch)
                    } else {
                        throwExceptionInDebug("video not found")
                    }
                }
                postcard.navigation(this, REQUEST_CODE_IMAGE_CROP)
            }
        } catch (e: Exception) {
            toast(R.string.media_image_hint)
            e.printStackTrace()
        }
    }

    override fun onMenuItemClick(item: MenuItem): Boolean {
        if (item.itemId == R.id.menu_text) {
            LogUtils.logVideoStreamingUpload("存草稿", mPath, mEntranceLink, "")
            MtaHelper.onEvent("上传视频", "上传视频", "存草稿")
            if (mVideoFileEntity?.path.isNullOrEmpty() || !File(mVideoFileEntity?.path).exists()) {
                toast("保存失败，视频文件不存在")
                handleFileNotFound()
            } else {
                DialogUtils.showUploadDraftDialog(this@UploadVideoActivity,
                    object : CancelListener {
                        override fun onCancel() {
                            if (!File(mVideoFileEntity?.path).exists()) {
                                toast("上传失败，视频文件不存在")
                                handleFileNotFound()
                            }
                            MtaHelper.onEvent("上传视频", "上传视频-存草稿", "继续上传")
                            LogUtils.logVideoStreamingUpload("存草稿-取消", mPath, mEntranceLink, "")
                        }
                    }, object : ConfirmListener {
                        override fun onConfirm() {
                            verifyData(true)
                            MtaHelper.onEvent("上传视频", "上传视频-存草稿", "确定保存")
                            LogUtils.logVideoStreamingUpload("存草稿-确定", mPath, mEntranceLink, "")
                        }
                    })
            }
        }
        return super.onMenuItemClick(item)
    }

    // todo 逻辑混乱 有时间重新整理
    private fun verifyData(isDraft: Boolean) {
        if (ClickUtils.isFastDoubleClick()) return

        if (mViewModel.videoPatch == null) {
            if (mVideoFileEntity != null && !File(mVideoFileEntity?.path).exists()) {
                if (isDraft) {
                    toast("保存失败，视频文件不存在")
                } else {
                    toast("提交失败，视频文件不存在")
                }
                handleFileNotFound()
                return
            }

            if (!isDraft && mVideoFileEntity?.url == null) {
                toast("视频尚未上传完成")
                return
            }

            if (!isDraft && (mViewModel.gameEntity == null || mViewModel.gameEntity?.id?.isEmpty() == true)) {
                toast("请选择游戏")
                return
            }
        }

        val title = mBinding.gameTitle.text.trim()
        if (!isDraft && title.isEmpty()) {
            toast("请填写标题")
            return
        }

        var gameCategory = ""
        val gameCategoryView = mBinding.gameCategory
        if (gameCategoryView.childCount > 0) {
            for (index in 0 until gameCategoryView.childCount) {
                val cell = gameCategoryView.getChildAt(index)
                if (cell is CheckedTextView && cell.isChecked) {
                    gameCategory = cell.tag.toString()
                }
            }
            if (!isDraft && gameCategory.isEmpty()) {
                toast("请选择分类")
                return
            }
        }

        if (!isDraft && !mBinding.originalTv.isChecked && !mBinding.reprintTv.isChecked) {
            toast("请选择视频来源")
            return
        }

        if (!isDraft && mBinding.reprintTv.isChecked && mBinding.videoSourceEt.text.isEmpty()) {
            toast("请填写转载来源")
            return
        }

        if (!isDraft) {
            if (mBinding.uploadConfirm.isChecked) {
                SPUtils.setBoolean(getConfirmUpdateProtocolKey(), true)
            } else {
                ToastUtils.showToast("请先同意《视频上传服务准则》")
                return
            }
        }

        val gameTags = JSONArray()
        val gameTagsView = mBinding.gameTag
        if (gameTagsView.childCount > 0) {
            for (index in 0 until gameTagsView.childCount) {
                val cell = gameTagsView.getChildAt(index)
                if (cell is CheckedTextView && cell.isChecked) {
                    gameTags.put(cell.tag.toString())
                }
            }
        }

        val videoData = if (mViewModel.videoPatch != null) {
            // 允许修改的数据
            mViewModel.videoPatch!!.title = title.toString()
            mViewModel.videoPatch!!.categoryId = gameCategory
            mViewModel.videoPatch!!.tagsId = GsonUtils.fromJsonList(gameTags)
            mViewModel.videoPatch!!.tagActivityId = mActivityLabelEntity?.id ?: ""
            mViewModel.videoPatch!!
        } else {
            VideoEntity(
                id = mViewModel.videoDraft?.id ?: "",
                title = title.toString(),
                url = mVideoFileEntity?.url ?: "",
                gameId = mViewModel.gameEntity?.id ?: "",
                size = mVideoFileEntity?.size ?: 0,
                length = mVideoFileEntity?.length ?: 0,
                poster = mViewModel.videoDraft?.poster ?: "",
                categoryId = gameCategory,
                format = mVideoFileEntity?.format ?: "",
                tagsId = GsonUtils.fromJsonList(gameTags),
                original = if (mBinding.originalTv.isChecked) "yes" else if (mBinding.reprintTv.isChecked) "no" else "",
                source = if (mBinding.reprintTv.isChecked) mBinding.videoSourceEt.text.toString() else "",
                tagActivityId = if (mBinding.originalTv.isChecked && mActivityLabelEntity != null) mActivityLabelEntity?.id
                    ?: "" else ""
            )
        }

        if (mUpdatedPosterPath.isEmpty() && videoData.poster.isNotEmpty()) {
            mViewModel.postContent(
                isDraft,
                videoData,
                mVideoFileEntity?.path,
                mBinding.originalTv.isChecked && mBinding.watermarkSb.isChecked
            )
        } else {
            val posterPath = if (mUpdatedPosterPath.isNotEmpty()) {
                mUpdatedPosterPath
            } else {
                val localVideoPoster =
                    application.cacheDir.absolutePath + File.separator + System.currentTimeMillis() + ".jpg"
                try {
                    val bmp = ThumbnailUtils.createVideoThumbnail(
                        mVideoFileEntity?.path
                            ?: "", MediaStore.Images.Thumbnails.MINI_KIND
                    )
                    // bmp 可能为空
                    FileOutputStream(localVideoPoster).use { out ->
                        bmp?.compress(Bitmap.CompressFormat.PNG, 100, out)
                    }
                } catch (e: java.lang.Exception) {
                    e.printStackTrace()
                    Utils.toast(application, "视频封面操作失败")
                    return
                }
                localVideoPoster
            }
            mViewModel.postVideoPosterAndContent(
                isDraft,
                videoData,
                mVideoFileEntity?.path,
                posterPath,
                mBinding.originalTv.isChecked && mBinding.watermarkSb.isChecked
            )
        }
    }

    private fun createFlexContent(
        flexView: FlexboxLayout,
        contentList: List<VideoTagEntity>,
        clickListener: (View, VideoTagEntity) -> Unit
    ) {
        flexView.removeAllViews()

        for (index in 0 until contentList.count()) {
            val videoTagEntity = contentList[index]
            val flexCell = CheckedTextView(this)
            flexView.addView(flexCell)

            val videoDraft = mViewModel.videoDraft
            if (videoDraft != null) {
                if (videoDraft.tagsId?.contains(videoTagEntity.id) == true) flexCell.isChecked = true
                if (videoDraft.categoryId == videoTagEntity.id) flexCell.isChecked = true
            }

            val videoPatch = mViewModel.videoPatch
            if (videoPatch != null) {
                if (videoPatch.tagsId.contains(videoTagEntity.id)) flexCell.isChecked = true
                if (videoPatch.categoryId == videoTagEntity.id) flexCell.isChecked = true
            }

            if (mVideoLink?.categoryId == videoTagEntity.id) flexCell.isChecked = true

            val params = FlexboxLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 28F.dip2px())
            params.setMargins(0, 16F.dip2px(), 8F.dip2px(), 0)
            flexCell.layoutParams = params
            flexCell.textSize = 12f
            flexCell.gravity = Gravity.CENTER
            flexCell.text = videoTagEntity.name
            flexCell.tag = videoTagEntity.id
            flexCell.setTextColor(
                DrawableView.getSelectorColorStyle(
                    com.gh.gamecenter.common.R.color.text_secondary,
                    com.gh.gamecenter.common.R.color.white
                )
            )
            flexCell.background = DrawableView.getOvalSelectorStyle(
                com.gh.gamecenter.common.R.color.text_f2f2f2,
                com.gh.gamecenter.common.R.color.primary_theme
            )
            flexCell.setPadding(12F.dip2px(), 0, 12F.dip2px(), 0)
            flexCell.setOnClickListener {
                Util_System_Keyboard.hideSoftKeyboard(this, mBinding.gameTitle)
                clickListener.invoke(it, videoTagEntity)
                checkPostButtonStatus()
            }
        }
    }

    private fun uploadProtocolHandle() {
        val uploadProtocolText = SpannableStringBuilder(mBinding.updateProtocol.text)
        uploadProtocolText.setSpan(object : ClickableSpan() {
            override fun updateDrawState(ds: TextPaint) {
                super.updateDrawState(ds)
                ds.color = resources.getColor(com.gh.gamecenter.common.R.color.text_theme)
                ds.isUnderlineText = false
            }

            override fun onClick(widget: View) {
                startActivity(
                    WebActivity.getWebIntent(
                        this@UploadVideoActivity,
                        this@UploadVideoActivity.getString(R.string.upload_protocol_title),
                        this@UploadVideoActivity.getString(R.string.upload_protocol_url)
                    )
                )
            }
        }, uploadProtocolText.length - 10, uploadProtocolText.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        mBinding.updateProtocol.text = uploadProtocolText
        mBinding.updateProtocol.movementMethod = LinkMovementMethod()
        mBinding.uploadConfirm.isChecked = SPUtils.getBoolean(getConfirmUpdateProtocolKey(), false)

        mBinding.uploadExposureHint.paint.flags = Paint.UNDERLINE_TEXT_FLAG
        mBinding.uploadExposureHint.paint.isAntiAlias = true
        mBinding.uploadExposureHint.setOnClickListener {
            // 固定跳转
            startActivity(NewsDetailActivity.getIntentById(this, "5ed9e65d86775716ac16205a", mEntrance))
        }
    }

    private fun initUpload(videoPath: String?) {
        if (videoPath == null || !File(videoPath).exists()) {
            handleFileNotFound()
            return
        }

        if (!mViewModel.videoDraft?.poster.isNullOrEmpty()) {
            ImageUtils.display(mBinding.videoPoster, mViewModel.videoDraft?.poster)
        } else {
            val poster = intent.getStringExtra(EntranceConsts.KEY_POSTER_PATH)
            if (poster.isNullOrEmpty()) {
                val thumbnail = ThumbnailUtils.createVideoThumbnail(videoPath, MediaStore.Images.Thumbnails.MINI_KIND)
                mBinding.videoPoster.setImageBitmap(thumbnail)
            } else {
                mBinding.videoPoster.setImageURI(Uri.fromFile(File(poster)))
                mUpdatedPosterPath = poster
            }
        }

        mBinding.uploadButton.setOnClickListener {
            if (UploadManager.isUploading(videoPath)) {
                mBinding.uploadStatus.text = "上传已暂停"
                mBinding.uploadSpeed.visibility = View.GONE
                mBinding.uploadButton.setImageResource(R.drawable.upload_resume)
                mBinding.uploadButton.visibility = View.VISIBLE
                UploadManager.cancelTask(videoPath)
                MtaHelper.onEvent("上传视频", "上传视频", "上传暂停")
                LogUtils.logVideoStreamingUpload("暂停上传", mPath, mEntranceLink, "")
            } else if (File(videoPath).exists()) {
                mBinding.uploadStatus.text = "视频上传中..."
                mBinding.uploadButton.setImageResource(R.drawable.upload_pause)
                mBinding.uploadButton.visibility = View.VISIBLE
                createUploadTask(videoPath)
                MtaHelper.onEvent("上传视频", "上传视频", "上传继续")
                LogUtils.logVideoStreamingUpload("恢复上传", mPath, mEntranceLink, "")
            } else {
                handleFileNotFound()
                toast("上传失败，视频文件不存在")
            }
        }

        val videoFile = File(videoPath)
        val retriever = MediaMetadataRetriever()
        val fileUri = Uri.fromFile(videoFile)
        retriever.setDataSource(this@UploadVideoActivity, fileUri)
        val time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)
        val timeInSecond = java.lang.Long.parseLong(time) / 1000
        retriever.release()

        var format = ""
        tryWithDefaultCatch {
            val mimeType = FileUtils.getFileMimeType(applicationContext, videoPath)
            if (mimeType != null) {
                val split = mimeType.split("/")
                if (split.count() >= 2) {
                    format = split[1]
                } else {
                    format = mimeType
                }
            }
        }
        mVideoFileEntity = VideoFileEntity(videoPath, null, "", timeInSecond, videoFile.length(), format)

        createUploadTask(videoPath)
    }

    private fun createUploadTask(videoPath: String) {
        mBinding.uploadStatus.text = "视频上传中..."
        UploadManager.createUploadTask(videoPath, object : OnUploadListener {
            override fun onProgressChanged(uploadFilePath: String, currentSize: Long, totalSize: Long, speed: Long) {
                mBaseHandler.post {
                    mBinding.uploadStatus.text = "视频上传中..."
                    mBinding.uploadSpeed.visibility = View.VISIBLE
                    mBinding.uploadButton.visibility = View.VISIBLE
                    mBinding.uploadSpeed.text =
                        (SpeedUtils.getSpeed(speed) + "预计还需" + SpeedUtils.getRemainTime(
                            totalSize,
                            currentSize,
                            speed
                        ))
                    mBinding.uploadProgress.update(((360 * currentSize) / totalSize).toInt(), "")
                }
            }

            override fun onUploadSuccess(uploadFilePath: String, url: String) {
                runOnUiThread {
                    handleUploadSuccess(url)
                    MtaHelper.onEvent("上传视频", "上传视频", "上传成功")
                    LogUtils.logVideoStreamingUpload("视频上传完毕", mPath, mEntranceLink, "")
                }
            }

            override fun onUploadFailure(uploadFilePath: String, errorMsg: String) {
                runOnUiThread {
                    if (!File(uploadFilePath).exists()) {
                        handleFileNotFound()
                        MtaHelper.onEvent("上传视频", "上传视频", "上传失败")
                        toast("上传失败，视频文件不存在")
                    } else {
                        mBinding.uploadStatus.text = "网络错误，中断上传"
                        mBinding.uploadButton.setImageResource(R.drawable.upload_resume)
                        mBinding.uploadButton.visibility = View.VISIBLE
                        MtaHelper.onEvent("上传视频", "上传视频", "网络错误")
                        toast("网络错误，请检查网络正常后再重试")
                    }
                    mBinding.uploadSpeed.visibility = View.GONE
                }
            }
        })
    }

    private fun handleUploadSuccess(url: String) {
        mBinding.uploadStatus.text = "视频已上传完成"
        mBinding.uploadStatusContainer.visibility = View.GONE
        mBinding.uploadProgress.visibility = View.GONE
        mBinding.uploadButton.visibility = View.GONE
        mBinding.videoPosterMask.visibility = View.GONE
        mBinding.uploadProgress.update(360, "")
        mVideoFileEntity?.url = url
    }

    private fun handleFileNotFound() {
        mBinding.uploadStatus.text = "上传失败，视频文件不存在"
        mBinding.uploadButton.setImageResource(R.drawable.upload_warning)
        mBinding.uploadButton.visibility = View.VISIBLE
    }

    override fun handleBackPressed(): Boolean {
        LogUtils.logVideoStreamingUpload("返回", mPath, mEntranceLink, "")

        if (mViewModel.videoPatch != null) return false

        if (mVideoFileEntity?.path.isNullOrEmpty() || !File(mVideoFileEntity?.path).exists()) {
            val id = mViewModel.videoDraft?.id ?: return false
            DialogHelper.showDialog(this,
                "提示", "视频文件不存在，无法完成上传",
                "退出并删除草稿", "", {
                    // delete draft
                    mViewModel.deleteDraft(id)
                })
            return true
        }

        if (mVideoFileEntity?.url.isNullOrEmpty()) {
            DialogHelper.showDialog(this, "提示",
                "视频正在上传中，确定要退出吗？", "确定退出",
                "暂时不了", confirmClickCallback = {
                    finish()
                    LogUtils.logVideoStreamingUpload("返回-确定返回", mPath, mEntranceLink, "")
                }, cancelClickCallback = {
                    LogUtils.logVideoStreamingUpload("返回-暂时不了", mPath, mEntranceLink, "")
                })
        } else {
            DialogHelper.showDialog(this, "提示",
                "视频已上传完毕，确定退出并放弃提交吗？", "确定退出",
                "继续提交", confirmClickCallback = {
                    LogUtils.logVideoStreamingUpload("返回-确定返回", mPath, mEntranceLink, "")
                    finish()
                }, cancelClickCallback = {
                    LogUtils.logVideoStreamingUpload("返回-继续提交", mPath, mEntranceLink, "")
                })
        }

        return true
    }

    private fun checkPostButtonStatus() {
        val videoPatch = mViewModel.videoPatch ?: return
        var isContentChanged = false
        if (mUpdatedPosterPath.isNotEmpty()) {
            isContentChanged = true
        }

        if (!isContentChanged && videoPatch.title != mBinding.gameTitle.text.toString()) {
            isContentChanged = true
        }
        if (videoPatch.tagActivityId != mActivityLabelEntity?.id ?: "") {
            isContentChanged = true
        }

        if (!isContentChanged) {
            val gameCategoryView = mBinding.gameCategory
            for (index in 0 until gameCategoryView.childCount) {
                val cell = gameCategoryView.getChildAt(index)
                if (cell is CheckedTextView && cell.isChecked) {
                    isContentChanged = videoPatch.categoryId != cell.tag
                    break
                }
            }
        }

        if (!isContentChanged) {
            val gameTags = arrayListOf<String>()
            val gameTagsView = mBinding.gameTag
            if (gameTagsView.childCount > 0) {
                for (index in 0 until gameTagsView.childCount) {
                    val cell = gameTagsView.getChildAt(index)
                    if (cell is CheckedTextView && cell.isChecked) {
                        gameTags.add(cell.tag.toString())
                    }
                }
            }
            isContentChanged = !videoPatch.tagsId.checkSameFromStringArray(gameTags)
        }

        mBinding.postButton.isEnabled = isContentChanged
        if (isContentChanged) {
            mBinding.postButton.setBackgroundResource(com.gh.gamecenter.feature.R.drawable.game_item_btn_download_style)
        } else {
            mBinding.postButton.setBackgroundResource(R.drawable.border_round_eee_999)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        val path = mVideoFileEntity?.path
        if (path != null && UploadManager.isUploading(path)) {
            UploadManager.cancelTask(path)
        }
    }


    private fun getConfirmUpdateProtocolKey(): String {
        return "ConfirmUpdateProtocolKey" + PackageUtils.getGhVersionName()
    }

    companion object {

        private const val REQUEST_GAME_CODE = 116
        const val RESULT_CODE_VIDEO = 117
        const val RESULT_CODE_DRAFT = 118
        const val REQUEST_CODE_IMAGE_CROP = 120
        const val REQUEST_CODE_CHOOSE_LABEL = 121

        /**
         * 普通入口(视频投稿)
         */
        fun getIntent(
            context: Context,
            videoPath: String,
            entrance: String,
            path: String,
            poster: String? = null
        ): Intent {
            val intent = Intent(context, UploadVideoActivity::class.java)
            intent.putExtra(EntranceConsts.KEY_PATH, path)
            intent.putExtra(EntranceConsts.KEY_ENTRANCE, mergeEntranceAndPath(entrance, path))
            intent.putExtra(EntranceConsts.KEY_PATH_VIDEO, videoPath)
            intent.putExtra(EntranceConsts.KEY_POSTER_PATH, poster)
            return intent
        }

        /**
         * WEB端入口
         *
         * @param link 只用于数据统计
         */
        fun getIntent(
            context: Context,
            videoPath: String,
            linkEntity: VideoLinkEntity,
            simpleGameEntity: SimpleGameEntity? = null,
            entrance: String,
            path: String,
            poster: String? = null
        ): Intent {
            val intent = Intent(context, UploadVideoActivity::class.java)
            intent.putExtra(EntranceConsts.KEY_ENTRANCE, mergeEntranceAndPath(entrance, path))
            intent.putExtra(EntranceConsts.KEY_PATH, path)
            intent.putExtra(VideoLinkEntity::class.java.simpleName, linkEntity)
            intent.putExtra(SimpleGameEntity::class.java.simpleName, simpleGameEntity)
            intent.putExtra(EntranceConsts.KEY_PATH_VIDEO, videoPath)
            intent.putExtra(EntranceConsts.KEY_POSTER_PATH, poster)
            return intent
        }

        /**
         * 通过草稿进入
         */
        fun getIntent(context: Context, videoDraft: VideoDraftEntity, entrance: String, path: String): Intent {
            val intent = Intent(context, UploadVideoActivity::class.java)
            intent.putExtra(EntranceConsts.KEY_ENTRANCE, mergeEntranceAndPath(entrance, path))
            intent.putExtra(EntranceConsts.KEY_PATH, path)
            intent.putExtra(VideoDraftEntity::class.java.simpleName, videoDraft)
            return intent
        }

        /**
         * 修改视频
         */
        fun getIntent(context: Context, video: VideoEntity, entrance: String, path: String): Intent {
            val intent = Intent(context, UploadVideoActivity::class.java)
            intent.putExtra(EntranceConsts.KEY_ENTRANCE, mergeEntranceAndPath(entrance, path))
            intent.putExtra(EntranceConsts.KEY_PATH, path)
            intent.putExtra(VideoEntity::class.java.simpleName, video)
            return intent
        }
    }
}