package kr.co.vividnext.sodalive.audio_content.playlist.create.add_content

import android.annotation.SuppressLint
import android.app.Dialog
import android.content.DialogInterface
import android.graphics.Rect
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kr.co.vividnext.sodalive.audio_content.order.AudioContentOrderListViewModel
import kr.co.vividnext.sodalive.audio_content.order.GetAudioContentOrderListItem
import kr.co.vividnext.sodalive.audio_content.order.OrderType
import kr.co.vividnext.sodalive.audio_content.playlist.detail.AudioContentPlaylistContent
import kr.co.vividnext.sodalive.common.LoadingDialog
import kr.co.vividnext.sodalive.databinding.FragmentPlaylistAddContentBinding
import kr.co.vividnext.sodalive.extensions.dpToPx
import org.koin.android.ext.android.inject

class PlaylistAddContentDialogFragment(
    private val screenWidth: Int,
    private val selectedContentList: List<AudioContentPlaylistContent>,
    private val onItemClick: (GetAudioContentOrderListItem, Boolean) -> Boolean
) : BottomSheetDialogFragment() {

    private lateinit var binding: FragmentPlaylistAddContentBinding
    private lateinit var adapter: PlaylistAddContentAdapter
    private lateinit var loadingDialog: LoadingDialog

    private val viewModel: AudioContentOrderListViewModel by inject()

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = super.onCreateDialog(savedInstanceState)

        dialog.setOnShowListener { dialogInterface ->
            val d = dialogInterface as BottomSheetDialog
            val bottomSheet = d.findViewById<FrameLayout>(
                com.google.android.material.R.id.design_bottom_sheet
            )
            if (bottomSheet != null) {
                BottomSheetBehavior.from(bottomSheet).state = BottomSheetBehavior.STATE_EXPANDED
            }
            bottomSheet?.let {
                val behavior = BottomSheetBehavior.from(bottomSheet)
                behavior.state = BottomSheetBehavior.STATE_EXPANDED
                behavior.skipCollapsed = true

                it.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
                it.requestLayout()
            }
        }

        return dialog
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentPlaylistAddContentBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        setupView()
        bindData()
        viewModel.getAudioContentOrderList(orderType = OrderType.KEEP) { dismiss() }
    }

    override fun onDismiss(dialog: DialogInterface) {
        viewModel.page = 1
        super.onDismiss(dialog)
    }

    private fun setupView() {
        binding.tvClose.setOnClickListener { dismiss() }

        loadingDialog = LoadingDialog(requireActivity(), layoutInflater)
        adapter = PlaylistAddContentAdapter(
            selectedContentList.map { it.id }.toSet(),
            onItemClick
        )

        val recyclerView = binding.rvContent
        recyclerView.layoutManager = LinearLayoutManager(
            requireContext(),
            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.getAudioContentOrderList(orderType = OrderType.KEEP) {}
                }
            }
        })

        recyclerView.adapter = adapter
    }

    @SuppressLint("SetTextI18n", "NotifyDataSetChanged")
    private fun bindData() {
        viewModel.toastLiveData.observe(viewLifecycleOwner) {
            Toast.makeText(requireActivity(), it, Toast.LENGTH_LONG).show()
        }

        viewModel.isLoading.observe(viewLifecycleOwner) {
            if (it) {
                loadingDialog.show(
                    screenWidth,
                    ""
                )
            } else {
                loadingDialog.dismiss()
            }
        }

        viewModel.orderList.observe(viewLifecycleOwner) {
            if (viewModel.page == 2) {
                adapter.items.clear()
            }

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

        viewModel.totalCount.observe(viewLifecycleOwner) {
            binding.tvContentCount.text = "${it}개"
        }
    }
}
