package kr.co.vividnext.sodalive.explorer.profile.creator_community.all

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.text.Spannable
import android.text.SpannableString
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.widget.PopupMenu
import androidx.recyclerview.widget.RecyclerView
import coil.load
import coil.transform.CircleCropTransformation
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
import kr.co.vividnext.sodalive.databinding.ItemCreatorCommunityAllBinding
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostCommentListItem
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostListResponse
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.player.CreatorCommunityContentItem
import kr.co.vividnext.sodalive.extensions.dpToPx
import kr.co.vividnext.sodalive.extensions.loadUrl
import java.util.regex.Pattern

class CreatorCommunityAllAdapter(
    private val screenWidth: Int,
    private val onClickLike: (Long) -> Unit,
    private val writeComment: (Long, Long?, String) -> Unit,
    private val showCommentBottomSheetDialog: (Long) -> Unit,
    private val onClickModify: (Long) -> Unit,
    private val onClickDelete: (Long) -> Unit,
    private val onClickReport: (Long) -> Unit,
    private val onClickAudioContentPlayOrPause: (CreatorCommunityContentItem) -> Unit,
    private val isAudioContentPlaying: (Long) -> Boolean,
    private val onClickPurchaseContent:
        (Long, Int, onSuccess: (GetCommunityPostListResponse) -> Unit) -> Unit
) : RecyclerView.Adapter<CreatorCommunityAllAdapter.ViewHolder>() {

    val items = mutableListOf<GetCommunityPostListResponse>()

    inner class ViewHolder(
        private val context: Context,
        private val binding: ItemCreatorCommunityAllBinding
    ) : RecyclerView.ViewHolder(binding.root) {
        @SuppressLint("NotifyDataSetChanged", "SetTextI18n")
        fun bind(item: GetCommunityPostListResponse, index: Int) {
            binding.tvDate.text = item.date
            binding.tvNickname.text = item.creatorNickname
            binding.ivCreatorProfile.loadUrl(item.creatorProfileUrl) {
                crossfade(true)
                placeholder(R.drawable.bg_placeholder)
                transformations(CircleCropTransformation())
            }

            if (item.price > 0) {
                if (item.existOrdered) {
                    setContent(item, index)
                } else {
                    binding.llLike.visibility = View.GONE
                    binding.ivContent.visibility = View.GONE
                    binding.llComment.visibility = View.GONE
                    binding.ivSeeMore.visibility = View.GONE
                    binding.ivPlayOrPause.visibility = View.GONE
                    binding.llLockPost.visibility = View.VISIBLE

                    val lockPostWidth = (screenWidth - 42f.dpToPx()).toInt()
                    val lp = binding.llLockPost.layoutParams as LinearLayout.LayoutParams
                    lp.width = lockPostWidth
                    lp.height = lockPostWidth
                    binding.llLockPost.layoutParams = lp

                    binding.tvPurchase.text = "${item.price}캔으로 게시글 보기"
                    binding.tvPurchase.setOnClickListener {
                        onClickPurchaseContent(item.postId, item.price) { post ->
                            items[index] = post
                            setContent(post, index)
                        }
                    }

                    setNoticeAndClickableUrl(binding.tvContent, item.content, item.isExpand, index)
                }
            } else {
                setContent(item, index)
            }
        }

        private fun setContent(item: GetCommunityPostListResponse, index: Int) {
            binding.llLockPost.visibility = View.GONE
            binding.llLike.visibility = View.VISIBLE
            binding.llComment.visibility = View.VISIBLE
            binding.ivSeeMore.visibility = View.VISIBLE
            binding.ivSeeMore.setOnClickListener {
                showOptionMenu(
                    context = context,
                    v = binding.ivSeeMore,
                    postId = item.postId,
                    creatorId = item.creatorId
                )
            }

            if (item.audioUrl != null && item.imageUrl != null) {
                binding.ivPlayOrPause.visibility = View.VISIBLE
                binding.ivPlayOrPause.setImageResource(
                    if (isAudioContentPlaying(item.postId)) {
                        R.drawable.btn_audio_content_pause
                    } else {
                        R.drawable.btn_audio_content_play
                    }
                )
                binding.ivPlayOrPause.setOnClickListener {
                    onClickAudioContentPlayOrPause(
                        CreatorCommunityContentItem(
                            item.postId,
                            item.audioUrl
                        )
                    )
                }
            } else {
                binding.ivPlayOrPause.visibility = View.GONE
                binding.ivPlayOrPause.setOnClickListener {}
            }

            setImageContent(binding.ivContent, item.imageUrl)
            setContentLike(item.isLike, item.likeCount, item.postId, index)
            setNoticeAndClickableUrl(binding.tvContent, item.content, item.isExpand, index)
            setContentComment(
                item.postId,
                item.commentCount,
                item.isCommentAvailable,
                comment = item.firstComment
            )
        }

        private fun setImageContent(ivContent: ImageView, imageUrl: String?) {
            ivContent.visibility = View.VISIBLE
            if (imageUrl != null) {
                ivContent.visibility = View.VISIBLE
                ivContent.loadUrl(imageUrl) {
                    crossfade(true)
                    placeholder(R.drawable.bg_placeholder)
                }
            } else {
                ivContent.visibility = View.GONE
            }
        }

        private fun setContentComment(
            postId: Long,
            commentCount: Int,
            isCommentAvailable: Boolean,
            comment: GetCommunityPostCommentListItem?
        ) {
            if (isCommentAvailable) {
                binding.llComment.visibility = View.VISIBLE
                binding.tvCommentCount.text = "$commentCount"
            } else {
                binding.llComment.visibility = View.GONE
            }

            if (commentCount > 0 && comment != null) {
                binding.ivCommentProfile.load(comment.profileUrl) {
                    crossfade(true)
                    placeholder(R.drawable.bg_placeholder)
                    transformations(CircleCropTransformation())
                }
                binding.tvCommentText.text = comment.comment
                binding.tvCommentText.visibility = View.VISIBLE
                binding.rlInputComment.visibility = View.GONE

                binding.llComment.setOnClickListener { showCommentBottomSheetDialog(postId) }
            } else {
                binding.tvCommentText.visibility = View.GONE
                binding.rlInputComment.visibility = View.VISIBLE
                binding.ivCommentProfile.load(SharedPreferenceManager.profileImage) {
                    crossfade(true)
                    placeholder(R.drawable.bg_placeholder)
                    transformations(CircleCropTransformation())
                }

                binding.ivCommentSend.setOnClickListener {
                    val inputComment = binding.etComment.text.toString()
                    binding.etComment.setText("")
                    writeComment(postId, null, inputComment)
                }

                binding.llComment.setOnClickListener {}
            }
        }

        @SuppressLint("NotifyDataSetChanged")
        private fun setContentLike(isLike: Boolean, likeCount: Int, postId: Long, index: Int) {
            binding.ivLike.setImageResource(
                if (isLike) {
                    R.drawable.ic_audio_content_heart_pressed
                } else {
                    R.drawable.ic_audio_content_heart_normal
                }
            )

            binding.tvLike.text = "$likeCount"
            binding.llLike.setOnClickListener {
                items[index] = items[index].copy(
                    isLike = !isLike,
                    likeCount = if (!isLike) likeCount + 1 else likeCount - 1
                )
                notifyDataSetChanged()

                onClickLike(postId)
            }
        }

        @SuppressLint("NotifyDataSetChanged")
        private fun setNoticeAndClickableUrl(
            textView: TextView,
            text: String,
            isExpand: Boolean,
            index: Int
        ) {
            textView.visibility = View.VISIBLE
            textView.text = text

            val spannable = SpannableString(text)
            val pattern = Pattern.compile("https?://\\S+")
            val matcher = pattern.matcher(spannable)

            while (matcher.find()) {
                val start = matcher.start()
                val end = matcher.end()
                val clickableSpan = object : ClickableSpan() {
                    override fun onClick(widget: View) {
                        val url = spannable.subSequence(start, end).toString()
                        context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
                    }
                }
                spannable.setSpan(clickableSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
            }

            textView.text = spannable
            textView.movementMethod = LinkMovementMethod.getInstance()

            textView.setOnClickListener {
                items[index] = items[index].copy(
                    isExpand = !isExpand,
                )
                notifyDataSetChanged()
            }

            textView.maxLines = if (isExpand) {
                Int.MAX_VALUE
            } else {
                3
            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
        parent.context,
        ItemCreatorCommunityAllBinding.inflate(
            LayoutInflater.from(parent.context),
            parent,
            false
        )
    )

    override fun getItemCount() = items.size

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(items[position], position)
    }

    private fun showOptionMenu(
        context: Context,
        v: View,
        postId: Long,
        creatorId: Long
    ) {
        val popup = PopupMenu(context, v)
        val inflater = popup.menuInflater

        if (creatorId == SharedPreferenceManager.userId) {
            inflater.inflate(R.menu.community_post_creator_option_menu, popup.menu)
        } else {
            inflater.inflate(R.menu.community_post_option_menu, popup.menu)
        }

        popup.setOnMenuItemClickListener {
            when (it.itemId) {
                R.id.menu_modify -> {
                    onClickModify(postId)
                }

                R.id.menu_delete -> {
                    onClickDelete(postId)
                }

                R.id.menu_report -> {
                    onClickReport(postId)
                }
            }

            true
        }

        popup.show()
    }

    @SuppressLint("NotifyDataSetChanged")
    fun updateUI() {
        notifyDataSetChanged()
    }
}
