package com.gh.common.view

import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.LinearLayout
import androidx.core.content.ContextCompat
import com.facebook.drawee.drawable.ScalingUtils
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.common.util.*
import com.gh.gamecenter.ImageViewerActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.debounceActionWithInterval
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.toResString
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.core.utils.TopCutProcess
import com.gh.gamecenter.databinding.ItemCommunityImageBinding
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.qa.entity.CommunityVideoEntity
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel

class ImageContainerView : LinearLayout {
    private var mAnswerEntity: AnswerEntity? = null

    //三图默认宽度
    private var mDefaultWidth = 0f

    //单图固定宽度
    private var mFixdWidth = 0f

    //最小比例
    private var mMinRatio = 3 / 4f

    //最大比例
    private var mMaxRatio = 3 / 2f

    //长图比例
    private var mLongPictureRatio = 9 / 18f

    private var mEntrance = ""
    private var mPath = ""

    //图片之间的间距
    private val mItemSpace = 4f.dip2px()
    private var mOffset = 0
    private var index = 0

    private val imageViewList = arrayListOf<SimpleDraweeView>()

    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        initView(attrs)
    }

    private fun initView(attrs: AttributeSet?) {
        orientation = HORIZONTAL
        val ta = context.obtainStyledAttributes(attrs, R.styleable.ImageContainerView)
        mOffset = ta.getDimensionPixelSize(R.styleable.ImageContainerView_offset, 0)
        calculateWidth()
        ta.recycle()
    }

    private fun calculateWidth() {
        mDefaultWidth = (DisplayUtils.getScreenWidth() - mOffset.toFloat() - mItemSpace * 2) / 3
        mFixdWidth = (DisplayUtils.getScreenWidth() - mOffset.toFloat() - mItemSpace * 2) * 2 / 3
    }

    fun setOffset(offset: Float) {
        mOffset = offset.dip2px()
        calculateWidth()
    }

    fun bindData(entity: AnswerEntity, entrance: String = "", path: String = "") {
        imageViewList.clear()
        if (entity.id != mAnswerEntity?.id) {
            removeAllViews()
        }
        mAnswerEntity = entity
        mEntrance = entrance
        mPath = path
        index = 0
        if ((entity.user.id == UserManager.getInstance().userId && entity.videos.isNotEmpty()) ||
            (entity.user.id != UserManager.getInstance().userId && entity.getPassVideos().isNotEmpty()) ||
            entity.images.isNullOrEmpty()
        ) {
            visibility = View.GONE
            return
        }
        visibility = View.VISIBLE
        if (mAnswerEntity?.type == "community_article") {
            //若文章内容含有图片及视频，则信息流卡片，仅展示图片，且标题后带有‘有视频’标签
            //若文章内容仅含有图片，则信息流卡片，仅展示图片，无标签
            //若文章内容仅含有视频，则信息流卡片，仅展示视频，无标签
            when {
                entity.images.isNotEmpty() -> {
                    val imagesInfo = entity.imagesInfo
                    val images = entity.images.take(3)
                    images.forEachIndexed { index, url ->
                        val width = if (index <= entity.imagesInfo.size - 1) imagesInfo[index].width else 0
                        val height = if (index <= entity.imagesInfo.size - 1) imagesInfo[index].height else 0
                        bindImage(url, width, height, images.size == 1)
                    }
                }
                entity.getPassVideos().isNotEmpty() -> {
                    val video = entity.getPassVideos()[0]
                    bindVideo(video, video.width, video.height, true)
                }
                else -> {
                    // do noting
                }
            }
        } else {
            //若问答内容含有图片及视频，则信息流卡片，同时展示图片及视频，且参考以往排序逻辑（视频优先放置第一位），无标签
            //若问答内容仅含有图片，则信息流卡片，仅展示图片，无标签
            //若问答内容仅含有视频，则信息流卡片，仅展示视频，无标签
            if (entity.getPassVideos().isNotEmpty()) {
                val video = entity.getPassVideos()[0]
                bindVideo(video, video.width, video.height, mAnswerEntity?.images.isNullOrEmpty())
                entity.images.take(2).forEachIndexed { index, url ->
                    val imagesInfo = entity.imagesInfo
                    val width = if (index <= entity.imagesInfo.size - 1) imagesInfo[index].width else 0
                    val height = if (index <= entity.imagesInfo.size - 1) imagesInfo[index].height else 0
                    bindImage(url, width, height, false)
                }
            } else {
                val images = entity.images.take(3)
                images.forEachIndexed { index, url ->
                    val imagesInfo = entity.imagesInfo
                    val width = if (index <= entity.imagesInfo.size - 1) imagesInfo[index].width else 0
                    val height = if (index <= entity.imagesInfo.size - 1) imagesInfo[index].height else 0
                    bindImage(url, width, height, images.size == 1)
                }
            }
        }
    }

    private fun bindVideo(video: CommunityVideoEntity, width: Int, height: Int, isChangeRatio: Boolean) {
        val oldView = if (childCount == 0 || index >= childCount) null else getChildAt(index)
        val binding = if (oldView != null) {
            ItemCommunityImageBinding.bind(oldView)
        } else {
            ItemCommunityImageBinding.inflate(LayoutInflater.from(context), null, false)
        }
        if (oldView == null) {
            addView(binding.root)
        }
        binding.durationOrNumTv.visibility = View.VISIBLE
        binding.videoPlay.visibility = View.VISIBLE
        binding.labelIcon.visibility = View.GONE
        binding.durationOrNumTv.text = video.duration
        displayImage(binding, video.poster, width.toFloat(), height.toFloat(), isChangeRatio, true)
        binding.root.setOnClickListener {
            debounceActionWithInterval(it.id, 1000) {
                if (mAnswerEntity == null) return@debounceActionWithInterval
                val videoEntity = mAnswerEntity!!.getPassVideos()[0]
                DirectUtils.directToVideoDetail(
                    context,
                    videoEntity.id,
                    VideoDetailContainerViewModel.Location.VIDEO_HOT.value,
                    showComment = false,
                    entrance = mEntrance,
                    path = mPath
                )
            }
        }
        index++
    }

    private fun bindImage(url: String, width: Int, height: Int, isChangeRatio: Boolean) {
        val oldView = if (childCount == 0 || index >= childCount) null else getChildAt(index)
        val binding = if (oldView != null) {
            ItemCommunityImageBinding.bind(oldView)
        } else {
            ItemCommunityImageBinding.inflate(LayoutInflater.from(context), null, false)
        }
        binding.root.tag = index
        if (oldView == null) {
            addView(binding.root)
        }
        imageViewList.add(binding.image)
        binding.durationOrNumTv.visibility = View.GONE
        binding.videoPlay.visibility = View.GONE
        displayImage(binding, url, width.toFloat(), height.toFloat(), isChangeRatio)
        binding.root.setOnClickListener {
            if (mAnswerEntity?.status == "pending" || mAnswerEntity?.status == "fail") return@setOnClickListener

            debounceActionWithInterval(it.id, 1000) {
                if (mAnswerEntity == null) return@debounceActionWithInterval
                val position = if (mAnswerEntity?.type == "community_article") {
                    binding.root.tag as Int
                } else {
                    if (mAnswerEntity!!.getPassVideos()
                            .isNullOrEmpty()
                    ) binding.root.tag as Int else (binding.root.tag as Int) - 1
                }
                if (mAnswerEntity?.communityId.isNullOrEmpty()) {
                    mAnswerEntity?.communityId = mAnswerEntity?.bbs?.id
                }
                val intent = ImageViewerActivity.getIntent(
                    context, mAnswerEntity!!.images as ArrayList<String>, position, imageViewList,
                    if (mAnswerEntity?.type == "community_article") mAnswerEntity else null, mEntrance, true
                )
                context.startActivity(intent)
            }
        }
        index++
    }

    private fun displayImage(
        binding: ItemCommunityImageBinding,
        url: String,
        width: Float,
        height: Float,
        isChangeRatio: Boolean,
        isVideo: Boolean = false
    ) {
        val params = binding.root.layoutParams as LayoutParams
        val hierarchy = binding.image.hierarchy
        binding.labelIcon.visibility = View.GONE
        if (width != 0f && height != 0f) {
            val picRatio = width / height
            if (isChangeRatio) {
                when {
                    picRatio <= mMinRatio -> {
                        params.height = (mFixdWidth / mMinRatio).toInt()
                        if (binding.image.tag != url) {
                            ImageUtils.display(binding.image, url, false, TopCutProcess(mMinRatio))
                        }
                    }
                    picRatio >= mMaxRatio -> {
                        params.height = (mFixdWidth / mMaxRatio).toInt()
                        ImageUtils.display(binding.image, url, false)
                    }
                    else -> {
                        params.height = (mFixdWidth / picRatio).toInt()
                        ImageUtils.display(binding.image, url, false)
                    }
                }
                params.width = mFixdWidth.toInt()
            } else {
                params.width = mDefaultWidth.toInt()
                params.height = mDefaultWidth.toInt()
                if (width > height) {
                    val loadImageWidth = width * (mDefaultWidth.toInt() / height)
                    binding.image.setTag(ImageUtils.TAG_TARGET_WIDTH, loadImageWidth.toInt())
                }
                ImageUtils.display(binding.image, url, false)
            }
            //长图
            if (!isVideo && picRatio <= mLongPictureRatio) {
                binding.labelIcon.visibility = View.VISIBLE
                binding.labelIcon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_long_pic_label))
            }
        } else {
            params.width = mDefaultWidth.toInt()
            params.height = mDefaultWidth.toInt()
            ImageUtils.display(binding.image, url, false)
        }

        if (url.endsWith(".gif")) {
            binding.gifBorder.visibility = View.VISIBLE
            binding.labelIcon.visibility = View.VISIBLE
            binding.labelIcon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_gif_label))
        }

        binding.pendingView.run {
            when (mAnswerEntity?.status) {
                "pending" -> {
                    visibility = View.VISIBLE
                    text = R.string.pending_status.toResString()
                }

                "fail" -> {
                    visibility = View.VISIBLE
                    text = R.string.fail_status.toResString()
                }

                else -> {
                    visibility = View.GONE
                }
            }
        }


        val imageCount = mAnswerEntity?.images?.size ?: 0
        if (!isVideo && index == 2 && imageCount > 3) {
            binding.labelIcon.visibility = View.GONE
            binding.durationOrNumTv.visibility = View.VISIBLE
            binding.durationOrNumTv.text = "+${imageCount - 3}"
        }

        hierarchy.actualImageScaleType = ScalingUtils.ScaleType.CENTER_CROP
        if (index != 0) params.leftMargin = mItemSpace
        binding.root.layoutParams = params
    }
}