package kr.co.vividnext.sodalive.audio_content.comment

import android.annotation.SuppressLint
import android.app.Service
import android.graphics.Rect
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import coil.load
import coil.transform.CircleCropTransformation
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.base.BaseFragment
import kr.co.vividnext.sodalive.base.SodaDialog
import kr.co.vividnext.sodalive.common.Constants
import kr.co.vividnext.sodalive.common.LoadingDialog
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentCommentListBinding
import kr.co.vividnext.sodalive.dialog.MemberProfileDialog
import kr.co.vividnext.sodalive.extensions.dpToPx
import org.koin.android.ext.android.inject

class AudioContentCommentListFragment : BaseFragment<FragmentAudioContentCommentListBinding>(
    FragmentAudioContentCommentListBinding::inflate
) {

    private val viewModel: AudioContentCommentListViewModel by inject()

    private lateinit var imm: InputMethodManager
    private lateinit var loadingDialog: LoadingDialog
    private lateinit var adapter: AudioContentCommentAdapter

    private var creatorId: Long = 0
    private var audioContentId: Long = 0
    private var isShowSecret: Boolean = false

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        creatorId = arguments?.getLong(Constants.EXTRA_AUDIO_CONTENT_CREATOR_ID) ?: 0
        audioContentId = arguments?.getLong(Constants.EXTRA_AUDIO_CONTENT_ID) ?: 0
        isShowSecret = arguments?.getBoolean(Constants.EXTRA_IS_SHOW_SECRET) ?: false
        return super.onCreateView(inflater, container, savedInstanceState)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        loadingDialog = LoadingDialog(requireActivity(), layoutInflater)
        imm = requireContext().getSystemService(
            Service.INPUT_METHOD_SERVICE
        ) as InputMethodManager

        setupView()
        bindData()
        viewModel.getCommentList(audioContentId = audioContentId) { hideDialog() }
    }

    private fun hideDialog() {
        (parentFragment as AudioContentCommentFragment).hideCommentDialog()
    }

    private fun setupView() {
        binding.ivClose.setOnClickListener { hideDialog() }

        binding.ivCommentProfile.load(SharedPreferenceManager.profileImage) {
            crossfade(true)
            placeholder(R.drawable.ic_place_holder)
            transformations(CircleCropTransformation())
        }

        binding.ivCommentSend.setOnClickListener {
            hideKeyboard()
            val comment = binding.etComment.text.toString()
            val isSecret = binding.tvSecret.isSelected
            viewModel.registerComment(audioContentId, comment, isSecret)

            binding.etComment.setText("")
            binding.tvSecret.isSelected = false
        }

        if (isShowSecret) {
            binding.tvSecret.visibility = View.VISIBLE
            binding.tvSecret.setOnClickListener {
                binding.tvSecret.isSelected = !binding.tvSecret.isSelected
            }
        } else {
            binding.tvSecret.visibility = View.GONE
        }

        adapter = AudioContentCommentAdapter(
            creatorId = creatorId,
            modifyComment = { commentId, comment ->
                hideKeyboard()
                viewModel.modifyComment(
                    commentId = commentId,
                    audioContentId = audioContentId,
                    comment = comment
                )
            },
            onClickDelete = {
                SodaDialog(
                    activity = requireActivity(),
                    layoutInflater = layoutInflater,
                    title = "댓글 삭제",
                    desc = "삭제하시겠습니까?",
                    confirmButtonTitle = "삭제",
                    confirmButtonClick = {
                        viewModel.modifyComment(
                            commentId = it,
                            audioContentId = audioContentId,
                            isActive = false
                        )
                    },
                    cancelButtonTitle = "취소",
                    cancelButtonClick = {}
                ).show(screenWidth)
            },
            onItemClick = {
                (parentFragment as AudioContentCommentFragment).onClickComment(it)
            },
            onClickProfile = {
                MemberProfileDialog(
                    activity = requireActivity(),
                    layoutInflater = layoutInflater,
                    memberId = it,
                    screenWidth = screenWidth
                ).show()
            }
        )

        val recyclerView = binding.rvComment
        recyclerView.setHasFixedSize(true)
        recyclerView.layoutManager = LinearLayoutManager(
            activity,
            LinearLayoutManager.VERTICAL,
            false
        )
        recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
            override fun getItemOffsets(
                outRect: Rect,
                view: View,
                parent: RecyclerView,
                state: RecyclerView.State
            ) {
                super.getItemOffsets(outRect, view, parent, state)

                outRect.left = 13.3f.dpToPx().toInt()
                outRect.right = 13.3f.dpToPx().toInt()

                when (parent.getChildAdapterPosition(view)) {
                    0 -> {
                        outRect.top = 13.3f.dpToPx().toInt()
                        outRect.bottom = 6.7f.dpToPx().toInt()
                    }

                    adapter.itemCount - 1 -> {
                        outRect.top = 6.7f.dpToPx().toInt()
                        outRect.bottom = 13.3f.dpToPx().toInt()
                    }

                    else -> {
                        outRect.top = 6.7f.dpToPx().toInt()
                        outRect.bottom = 6.7f.dpToPx().toInt()
                    }
                }
            }
        })

        recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)

                val lastVisibleItemPosition = (recyclerView.layoutManager as LinearLayoutManager?)!!
                    .findLastCompletelyVisibleItemPosition()
                val itemTotalCount = recyclerView.adapter!!.itemCount - 1

                // 스크롤이 끝에 도달했는지 확인
                if (!recyclerView.canScrollVertically(1) &&
                    lastVisibleItemPosition == itemTotalCount
                ) {
                    viewModel.getCommentList(audioContentId = audioContentId)
                }
            }
        })

        recyclerView.adapter = adapter
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun bindData() {
        viewModel.isLoading.observe(viewLifecycleOwner) {
            if (it) {
                loadingDialog.show(screenWidth)
            } else {
                loadingDialog.dismiss()
            }
        }

        viewModel.toastLiveData.observe(viewLifecycleOwner) {
            it?.let { Toast.makeText(requireContext(), it, Toast.LENGTH_LONG).show() }
        }

        viewModel.totalCommentCount.observe(viewLifecycleOwner) {
            binding.tvCommentCount.text = "$it"
        }

        viewModel.commentList.observe(viewLifecycleOwner) {
            if (viewModel.page - 1 == 1) {
                adapter.items.clear()
                binding.rvComment.scrollToPosition(0)
            }

            adapter.items.addAll(it)
            adapter.notifyDataSetChanged()
        }
    }

    private fun hideKeyboard() {
        imm.hideSoftInputFromWindow(view?.windowToken, 0)
    }

    companion object {
        fun newInstance(
            creatorId: Long,
            audioContentId: Long,
            isShowSecret: Boolean
        ): AudioContentCommentListFragment {
            val args = Bundle()
            args.putLong(Constants.EXTRA_AUDIO_CONTENT_CREATOR_ID, creatorId)
            args.putLong(Constants.EXTRA_AUDIO_CONTENT_ID, audioContentId)
            args.putBoolean(Constants.EXTRA_IS_SHOW_SECRET, isShowSecret)

            val fragment = AudioContentCommentListFragment()
            fragment.arguments = args
            return fragment
        }
    }
}
