package kr.co.vividnext.sodalive.audio_content.main

import android.app.Service
import android.content.Intent
import android.graphics.Rect
import android.net.Uri
import android.os.Bundle
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.LinearLayout
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.zhpan.bannerview.BaseBannerAdapter
import com.zhpan.indicator.enums.IndicatorSlideMode
import com.zhpan.indicator.enums.IndicatorStyle
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
import kr.co.vividnext.sodalive.audio_content.order.AudioContentOrderListActivity
import kr.co.vividnext.sodalive.audio_content.upload.AudioContentUploadActivity
import kr.co.vividnext.sodalive.base.BaseFragment
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.FragmentAudioContentMainBinding
import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity
import kr.co.vividnext.sodalive.extensions.dpToPx
import kr.co.vividnext.sodalive.settings.event.EventDetailActivity
import kr.co.vividnext.sodalive.settings.notification.MemberRole
import org.koin.android.ext.android.inject
import kotlin.math.roundToInt

class AudioContentMainFragment : BaseFragment<FragmentAudioContentMainBinding>(
    FragmentAudioContentMainBinding::inflate
) {
    private val viewModel: AudioContentMainViewModel by inject()

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

    private lateinit var newContentCreatorAdapter: AudioContentMainNewContentCreatorAdapter
    private lateinit var bannerAdapter: AudioContentMainBannerAdapter
    private lateinit var orderListAdapter: AudioContentMainContentAdapter
    private lateinit var newContentThemeAdapter: AudioContentMainNewContentThemeAdapter
    private lateinit var newContentAdapter: AudioContentMainContentAdapter
    private lateinit var curationAdapter: AudioContentMainCurationAdapter

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

        loadingDialog = LoadingDialog(requireActivity(), layoutInflater)
        imm = requireContext().getSystemService(
            Service.INPUT_METHOD_SERVICE
        ) as InputMethodManager

        setupView()
        bindData()

        viewModel.getMain()
    }

    private fun setupView() {
        if (SharedPreferenceManager.role == MemberRole.CREATOR.name) {
            binding.llUploadContent.visibility = View.VISIBLE
            binding.llUploadContent.setOnClickListener {
                startActivity(
                    Intent(
                        requireActivity(),
                        AudioContentUploadActivity::class.java
                    )
                )
            }
        } else {
            binding.llUploadContent.visibility = View.GONE
        }

        setupNewContentCreator()
        setupBanner()
        setupOrderList()
        setupNewContentTheme()
        setupNewContent()
        setupCuration()

        binding.swipeRefreshLayout.setOnRefreshListener {
            binding.swipeRefreshLayout.isRefreshing = false
            viewModel.getMain()
        }
    }

    private fun setupNewContentCreator() {
        newContentCreatorAdapter = AudioContentMainNewContentCreatorAdapter {
            val intent = Intent(requireContext(), UserProfileActivity::class.java)
            intent.putExtra(Constants.EXTRA_USER_ID, it)
            startActivity(intent)
        }

        binding.rvNewContentCreator.layoutManager = LinearLayoutManager(
            context,
            LinearLayoutManager.HORIZONTAL,
            false
        )

        binding.rvNewContentCreator.addItemDecoration(object : RecyclerView.ItemDecoration() {
            override fun getItemOffsets(
                outRect: Rect,
                view: View,
                parent: RecyclerView,
                state: RecyclerView.State
            ) {
                super.getItemOffsets(outRect, view, parent, state)

                when (parent.getChildAdapterPosition(view)) {
                    0 -> {
                        outRect.left = 0
                        outRect.right = 10.7f.dpToPx().toInt()
                    }

                    orderListAdapter.itemCount - 1 -> {
                        outRect.left = 10.7f.dpToPx().toInt()
                        outRect.right = 0
                    }

                    else -> {
                        outRect.left = 10.7f.dpToPx().toInt()
                        outRect.right = 10.7f.dpToPx().toInt()
                    }
                }
            }
        })

        binding.rvNewContentCreator.adapter = newContentCreatorAdapter
    }

    private fun setupBanner() {
        val layoutParams = binding
            .rvBanner
            .layoutParams as LinearLayout.LayoutParams

        val pagerWidth = screenWidth.toDouble() - 26.7f.dpToPx()
        val pagerHeight = (pagerWidth * 0.53).roundToInt()
        layoutParams.width = pagerWidth.roundToInt()
        layoutParams.height = pagerHeight

        bannerAdapter = AudioContentMainBannerAdapter(
            requireContext(),
            pagerWidth.roundToInt(),
            pagerHeight
        ) {
            when (it.type) {
                AudioContentBannerType.EVENT -> {
                    startActivity(
                        Intent(requireContext(), EventDetailActivity::class.java).apply {
                            putExtra(Constants.EXTRA_EVENT, it.eventItem!!)
                        }
                    )
                }

                AudioContentBannerType.CREATOR -> {
                    startActivity(
                        Intent(requireContext(), UserProfileActivity::class.java).apply {
                            putExtra(Constants.EXTRA_USER_ID, it.creatorId!!)
                        }
                    )
                }

                AudioContentBannerType.LINK -> {
                    startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(it.link!!)))
                }
            }
        }

        binding
            .rvBanner
            .layoutParams = layoutParams

        binding.rvBanner.apply {
            adapter = bannerAdapter as BaseBannerAdapter<Any>

            setLifecycleRegistry(lifecycle)
            setScrollDuration(1000)
            setInterval(4 * 1000)
        }.create()

        binding
            .rvBanner
            .setIndicatorView(binding.indicatorBanner)
            .setIndicatorStyle(IndicatorStyle.ROUND_RECT)
            .setIndicatorSlideMode(IndicatorSlideMode.SMOOTH)
            .setIndicatorVisibility(View.GONE)
            .setIndicatorSliderColor(
                ContextCompat.getColor(requireContext(), R.color.color_909090),
                ContextCompat.getColor(requireContext(), R.color.color_9970ff)
            )
            .setIndicatorSliderWidth(4f.dpToPx().toInt(), 10f.dpToPx().toInt())
            .setIndicatorHeight(4f.dpToPx().toInt())
    }

    private fun setupOrderList() {
        orderListAdapter = AudioContentMainContentAdapter(
            onClickItem = {
                startActivity(
                    Intent(requireContext(), AudioContentDetailActivity::class.java).apply {
                        putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, it)
                    }
                )
            },
            onClickCreator = {
                startActivity(
                    Intent(requireContext(), UserProfileActivity::class.java).apply {
                        putExtra(Constants.EXTRA_USER_ID, it)
                    }
                )
            }
        )

        binding.rvMyStash.layoutManager = LinearLayoutManager(
            context,
            LinearLayoutManager.HORIZONTAL,
            false
        )

        binding.rvMyStash.addItemDecoration(object : RecyclerView.ItemDecoration() {
            override fun getItemOffsets(
                outRect: Rect,
                view: View,
                parent: RecyclerView,
                state: RecyclerView.State
            ) {
                super.getItemOffsets(outRect, view, parent, state)

                when (parent.getChildAdapterPosition(view)) {
                    0 -> {
                        outRect.left = 0
                        outRect.right = 6.7f.dpToPx().toInt()
                    }

                    orderListAdapter.itemCount - 1 -> {
                        outRect.left = 6.7f.dpToPx().toInt()
                        outRect.right = 0
                    }

                    else -> {
                        outRect.left = 6.7f.dpToPx().toInt()
                        outRect.right = 6.7f.dpToPx().toInt()
                    }
                }
            }
        })

        binding.rvMyStash.adapter = orderListAdapter
        binding.tvMyStashViewAll.setOnClickListener {
            startActivity(Intent(requireContext(), AudioContentOrderListActivity::class.java))
        }
    }

    private fun setupNewContentTheme() {
        newContentThemeAdapter = AudioContentMainNewContentThemeAdapter {
            viewModel.getNewContentOfTheme(theme = it)
        }

        binding.rvNewContentTheme.layoutManager = LinearLayoutManager(
            context,
            LinearLayoutManager.HORIZONTAL,
            false
        )

        binding.rvNewContentTheme.addItemDecoration(object : RecyclerView.ItemDecoration() {
            override fun getItemOffsets(
                outRect: Rect,
                view: View,
                parent: RecyclerView,
                state: RecyclerView.State
            ) {
                super.getItemOffsets(outRect, view, parent, state)

                when (parent.getChildAdapterPosition(view)) {
                    0 -> {
                        outRect.left = 0
                        outRect.right = 4f.dpToPx().toInt()
                    }

                    orderListAdapter.itemCount - 1 -> {
                        outRect.left = 4f.dpToPx().toInt()
                        outRect.right = 0
                    }

                    else -> {
                        outRect.left = 4f.dpToPx().toInt()
                        outRect.right = 4f.dpToPx().toInt()
                    }
                }
            }
        })

        binding.rvNewContentTheme.adapter = newContentThemeAdapter
    }

    private fun setupNewContent() {
        newContentAdapter = AudioContentMainContentAdapter(
            onClickItem = {
                startActivity(
                    Intent(requireContext(), AudioContentDetailActivity::class.java).apply {
                        putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, it)
                    }
                )
            },
            onClickCreator = {
                startActivity(
                    Intent(requireContext(), UserProfileActivity::class.java).apply {
                        putExtra(Constants.EXTRA_USER_ID, it)
                    }
                )
            }
        )

        binding.rvNewContent.layoutManager = LinearLayoutManager(
            context,
            LinearLayoutManager.HORIZONTAL,
            false
        )

        binding.rvNewContent.addItemDecoration(object : RecyclerView.ItemDecoration() {
            override fun getItemOffsets(
                outRect: Rect,
                view: View,
                parent: RecyclerView,
                state: RecyclerView.State
            ) {
                super.getItemOffsets(outRect, view, parent, state)

                when (parent.getChildAdapterPosition(view)) {
                    0 -> {
                        outRect.left = 0
                        outRect.right = 6.7f.dpToPx().toInt()
                    }

                    orderListAdapter.itemCount - 1 -> {
                        outRect.left = 6.7f.dpToPx().toInt()
                        outRect.right = 0
                    }

                    else -> {
                        outRect.left = 6.7f.dpToPx().toInt()
                        outRect.right = 6.7f.dpToPx().toInt()
                    }
                }
            }
        })

        binding.rvNewContent.adapter = newContentAdapter
    }

    private fun setupCuration() {
        curationAdapter = AudioContentMainCurationAdapter(
            onClickItem = {
                startActivity(
                    Intent(requireContext(), AudioContentDetailActivity::class.java).apply {
                        putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, it)
                    }
                )
            },
            onClickCreator = {
                startActivity(
                    Intent(requireContext(), UserProfileActivity::class.java).apply {
                        putExtra(Constants.EXTRA_USER_ID, it)
                    }
                )
            }
        )

        binding.rvCuration.layoutManager = LinearLayoutManager(
            context,
            LinearLayoutManager.VERTICAL,
            false
        )

        binding.rvCuration.addItemDecoration(object : RecyclerView.ItemDecoration() {
            override fun getItemOffsets(
                outRect: Rect,
                view: View,
                parent: RecyclerView,
                state: RecyclerView.State
            ) {
                super.getItemOffsets(outRect, view, parent, state)

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

                    curationAdapter.itemCount - 1 -> {
                        outRect.top = 20f.dpToPx().toInt()
                        outRect.bottom = 40f.dpToPx().toInt()
                    }

                    else -> {
                        outRect.top = 20f.dpToPx().toInt()
                        outRect.bottom = 20f.dpToPx().toInt()
                    }
                }
            }
        })
        binding.rvCuration.adapter = curationAdapter
    }

    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.newContentUploadCreatorListLiveData.observe(viewLifecycleOwner) {
            newContentCreatorAdapter.addItems(it)
            binding.rvNewContentCreator.visibility = if (
                newContentCreatorAdapter.itemCount <= 0 && it.isEmpty()
            ) {
                View.GONE
            } else {
                View.VISIBLE
            }
        }

        viewModel.bannerLiveData.observe(viewLifecycleOwner) {
            if (bannerAdapter.itemCount <= 0 && it.isEmpty()) {
                binding.rvBanner.visibility = View.GONE
                binding.indicatorBanner.visibility = View.GONE
            } else {
                binding.rvBanner.visibility = View.VISIBLE
                binding.indicatorBanner.visibility = View.VISIBLE
                binding.rvBanner.refreshData(it)
            }
        }

        viewModel.orderListLiveData.observe(viewLifecycleOwner) {
            orderListAdapter.addItems(it)
            binding.llMyStash.visibility = if (
                orderListAdapter.itemCount <= 0 && it.isEmpty()
            ) {
                View.GONE
            } else {
                View.VISIBLE
            }
        }

        viewModel.newContentListLiveData.observe(viewLifecycleOwner) {
            newContentAdapter.addItems(it)
        }

        viewModel.themeListLiveData.observe(viewLifecycleOwner) {
            binding.llNewContent.visibility = View.VISIBLE
            newContentThemeAdapter.addItems(it)
        }

        viewModel.curationListLiveData.observe(viewLifecycleOwner) {
            curationAdapter.addItems(it)
            binding.rvCuration.visibility = if (
                curationAdapter.itemCount <= 0 && it.isEmpty()
            ) {
                View.GONE
            } else {
                View.VISIBLE
            }
        }
    }
}
