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

import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Rect
import android.net.Uri
import android.os.Bundle
import android.view.View
import android.widget.LinearLayout
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.GridLayoutManager
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.all.AudioContentNewAllActivity
import kr.co.vividnext.sodalive.audio_content.all.AudioContentRankingAllActivity
import kr.co.vividnext.sodalive.audio_content.all.by_theme.AudioContentAllByThemeActivity
import kr.co.vividnext.sodalive.audio_content.box.AudioContentBoxActivity
import kr.co.vividnext.sodalive.audio_content.curation.AudioContentCurationActivity
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
import kr.co.vividnext.sodalive.audio_content.main.banner.AudioContentMainBannerAdapter
import kr.co.vividnext.sodalive.audio_content.main.banner.AudioContentMainBannerViewModel
import kr.co.vividnext.sodalive.audio_content.main.curation.AudioContentMainCurationAdapter
import kr.co.vividnext.sodalive.audio_content.main.curation.AudioContentMainCurationViewModel
import kr.co.vividnext.sodalive.audio_content.main.new_content.AudioContentMainNewContentThemeAdapter
import kr.co.vividnext.sodalive.audio_content.main.new_content.AudioContentMainNewContentViewModel
import kr.co.vividnext.sodalive.audio_content.main.order.AudioContentMainOrderListViewModel
import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainRankingAdapter
import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainRankingViewModel
import kr.co.vividnext.sodalive.audio_content.main.recommend_series.AudioContentMainRecommendSeriesViewModel
import kr.co.vividnext.sodalive.audio_content.order.AudioContentOrderListActivity
import kr.co.vividnext.sodalive.audio_content.series.detail.SeriesDetailActivity
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.SharedPreferenceManager
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentMainBinding
import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity
import kr.co.vividnext.sodalive.explorer.profile.series.UserProfileSeriesListAdapter
import kr.co.vividnext.sodalive.extensions.dpToPx
import kr.co.vividnext.sodalive.mypage.alarm.AlarmListActivity
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 recommendSeriesViewModel: AudioContentMainRecommendSeriesViewModel by inject()
    private lateinit var seriesAdapter: UserProfileSeriesListAdapter

    private val bannerViewModel: AudioContentMainBannerViewModel by inject()
    private lateinit var bannerAdapter: AudioContentMainBannerAdapter

    private val orderListViewModel: AudioContentMainOrderListViewModel by inject()
    private lateinit var orderListAdapter: AudioContentMainContentAdapter

    private val newContentViewModel: AudioContentMainNewContentViewModel by inject()
    private lateinit var newContentThemeAdapter: AudioContentMainNewContentThemeAdapter
    private lateinit var newContentAdapter: AudioContentMainContentAdapter

    private val contentRankingViewModel: AudioContentMainRankingViewModel by inject()
    private lateinit var contentRankingSortAdapter: AudioContentMainNewContentThemeAdapter
    private lateinit var contentRankingAdapter: AudioContentMainRankingAdapter

    private val curationViewModel: AudioContentMainCurationViewModel by inject()
    private lateinit var curationAdapter: AudioContentMainCurationAdapter

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

        curationViewModel.getCurationList()
        bannerViewModel.getMainBannerList()
        newContentViewModel.getThemeList()
        newContentViewModel.getNewContentOfTheme("전체")
        contentRankingViewModel.getContentRanking()
        contentRankingViewModel.getContentRankingSortType()
        recommendSeriesViewModel.getRecommendSeriesList()
    }

    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
        }

        setupRecommendSeries()
        setupBanner()
        setupOrderList()
        setupNewContentTheme()
        setupNewContent()
        setupContentRankingSortType()
        setupContentRanking()
        setupCuration()

        binding.llShortPlay.setOnClickListener {
            startActivity(
                Intent(requireContext(), AudioContentAllByThemeActivity::class.java).apply {
                    putExtra(Constants.EXTRA_THEME_ID, 11L)
                }
            )
        }

        binding.llMorningCall.setOnClickListener {
            startActivity(
                Intent(requireContext(), AudioContentAllByThemeActivity::class.java).apply {
                    putExtra(Constants.EXTRA_THEME_ID, 12L)
                }
            )
        }

        binding.ivContentKeep.setOnClickListener {
            startActivity(
                Intent(
                    requireContext(),
                    AudioContentBoxActivity::class.java
                )
            )
        }

        binding.ivAlarm.setOnClickListener {
            startActivity(
                Intent(
                    requireActivity(),
                    AlarmListActivity::class.java
                )
            )
        }
    }

    private fun setupRecommendSeries() {
        seriesAdapter = UserProfileSeriesListAdapter(
            onClickItem = {
                startActivity(
                    Intent(requireContext(), SeriesDetailActivity::class.java).apply {
                        putExtra(Constants.EXTRA_SERIES_ID, it)
                    }
                )
            },
            onClickCreator = {
                startActivity(
                    Intent(requireContext(), UserProfileActivity::class.java).apply {
                        putExtra(Constants.EXTRA_USER_ID, it)
                    }
                )
            },
            isVisibleCreator = true
        )

        val recyclerView = binding.rvRecommendSeries
        recyclerView.layoutManager = LinearLayoutManager(
            requireContext(),
            LinearLayoutManager.HORIZONTAL,
            false
        )

        recyclerView.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()
                    }

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

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

        recyclerView.adapter = seriesAdapter

        recommendSeriesViewModel.seriesListLiveData.observe(viewLifecycleOwner) {
            seriesAdapter.addItems(it)
            binding.llRecommendSeries.visibility = if (
                seriesAdapter.itemCount <= 0 && it.isEmpty()
            ) {
                View.GONE
            } else {
                View.VISIBLE
            }
        }

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

        binding.llRecommendSeriesRefresh.setOnClickListener {
            seriesAdapter.clear()
            recommendSeriesViewModel.getRecommendSeriesList()
        }
    }

    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_3bb9f1)
            )
            .setIndicatorSliderWidth(4f.dpToPx().toInt(), 10f.dpToPx().toInt())
            .setIndicatorHeight(4f.dpToPx().toInt())

        bannerViewModel.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)
            }
        }

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

    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(), AudioContentBoxActivity::class.java))
        }

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

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

    private fun setupNewContentTheme() {
        newContentThemeAdapter = AudioContentMainNewContentThemeAdapter {
            newContentViewModel.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()
                    }

                    newContentThemeAdapter.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

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

    private fun setupNewContent() {
        binding.ivNewContentAll.setOnClickListener {
            startActivity(Intent(requireContext(), AudioContentNewAllActivity::class.java))
        }

        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()
                    }

                    newContentAdapter.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

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

        newContentViewModel.isLoading.observe(viewLifecycleOwner) {
            binding.pbNewContent.visibility = if (it) {
                View.VISIBLE
            } else {
                View.GONE
            }
        }

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

    private fun setupContentRankingSortType() {
        contentRankingSortAdapter = AudioContentMainNewContentThemeAdapter {
            contentRankingViewModel.getContentRanking(sort = it)
        }

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

        binding.rvContentRankingSort.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()
                    }

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

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

        binding.rvContentRankingSort.adapter = contentRankingSortAdapter

        contentRankingViewModel.contentRankingSortListLiveData.observe(viewLifecycleOwner) {
            binding.llContentRanking.visibility = View.VISIBLE
            contentRankingSortAdapter.addItems(it)
        }
    }

    @SuppressLint("SetTextI18n")
    private fun setupContentRanking() {
        binding.ivContentRankingAll.setOnClickListener {
            startActivity(Intent(requireContext(), AudioContentRankingAllActivity::class.java))
        }

        contentRankingAdapter = AudioContentMainRankingAdapter(
            width = (screenWidth * 0.66).toInt()
        ) {
            startActivity(
                Intent(requireContext(), AudioContentDetailActivity::class.java).apply {
                    putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, it)
                }
            )
        }

        binding.rvContentRanking.layoutManager = GridLayoutManager(
            context,
            3,
            GridLayoutManager.HORIZONTAL,
            false
        )

        binding.rvContentRanking.addItemDecoration(object : RecyclerView.ItemDecoration() {
            override fun getItemOffsets(
                outRect: Rect,
                view: View,
                parent: RecyclerView,
                state: RecyclerView.State
            ) {
                super.getItemOffsets(outRect, view, parent, state)
                outRect.top = 13.3f.dpToPx().toInt()
                outRect.bottom = 13.3f.dpToPx().toInt()
                outRect.left = 13.3f.dpToPx().toInt()
                outRect.right = 13.3f.dpToPx().toInt()
            }
        })

        binding.rvContentRanking.adapter = contentRankingAdapter

        contentRankingViewModel.contentRankingLiveData.observe(viewLifecycleOwner) {
            binding.llContentRanking.visibility = View.VISIBLE
            binding.tvDate.text = "${it.startDate}~${it.endDate}"
            contentRankingAdapter.addItems(it.items)
        }

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

    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)
                    }
                )
            },

            onClickCurationMore = { curationId, title ->
                startActivity(
                    Intent(requireContext(), AudioContentCurationActivity::class.java).apply {
                        putExtra(Constants.EXTRA_AUDIO_CONTENT_CURATION_ID, curationId)
                        putExtra(Constants.EXTRA_AUDIO_CONTENT_CURATION_TITLE, title)
                    }
                )
            }
        )

        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.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
                ) {
                    curationViewModel.getCurationList()
                }
            }
        })

        binding.rvCuration.adapter = curationAdapter

        curationViewModel.curationListLiveData.observe(viewLifecycleOwner) {
            if (curationViewModel.page == 2) {
                curationAdapter.clear()
            }

            curationAdapter.addItems(it)

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

        curationViewModel.isLoading.observe(viewLifecycleOwner) {
            binding.pbCuration.visibility = if (it) {
                View.VISIBLE
            } else {
                View.GONE
            }
        }

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