package kr.co.vividnext.sodalive.audio_content

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.graphics.Rect
import android.os.Bundle
import android.view.View
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.audio_content.category.AudioContentCategoryAdapter
import kr.co.vividnext.sodalive.audio_content.category.GetCategoryListResponse
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
import kr.co.vividnext.sodalive.audio_content.upload.AudioContentUploadActivity
import kr.co.vividnext.sodalive.base.BaseActivity
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.ActivityAudioContentBinding
import kr.co.vividnext.sodalive.extensions.dpToPx
import org.koin.android.ext.android.inject

class AudioContentActivity : BaseActivity<ActivityAudioContentBinding>(
    ActivityAudioContentBinding::inflate
) {

    private val viewModel: AudioContentViewModel by inject()

    private lateinit var loadingDialog: LoadingDialog
    private lateinit var audioContentAdapter: AudioContentAdapter
    private lateinit var categoryAdapter: AudioContentCategoryAdapter

    private var userId: Long = 0
    private lateinit var activityResultLauncher: ActivityResultLauncher<Intent>

    override fun onCreate(savedInstanceState: Bundle?) {
        userId = intent.getLongExtra(Constants.EXTRA_USER_ID, 0)
        activityResultLauncher = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()
        ) {
            if (it.resultCode == Activity.RESULT_OK) {
                viewModel.page = 1
                viewModel.isLast = false
                viewModel.getAudioContentList(userId = userId) { finish() }
            }
        }
        super.onCreate(savedInstanceState)

        if (userId <= 0) {
            Toast.makeText(applicationContext, "잘못된 요청입니다.", Toast.LENGTH_LONG).show()
            finish()
        }

        bindData()
        viewModel.getCategoryList(userId = userId)
        viewModel.getAudioContentList(userId = userId) { finish() }
    }

    override fun setupView() {
        loadingDialog = LoadingDialog(this, layoutInflater)
        binding.toolbar.tvBack.text = "콘텐츠 전체보기"
        binding.toolbar.tvBack.setOnClickListener { finish() }

        audioContentAdapter = AudioContentAdapter {
            val intent = Intent(applicationContext, AudioContentDetailActivity::class.java)
                .apply {
                    putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, it)
                }
            activityResultLauncher.launch(intent)
        }

        categoryAdapter = AudioContentCategoryAdapter {
            viewModel.selectCategory(it, userId = userId)
        }

        binding.rvCategory.layoutManager = LinearLayoutManager(
            applicationContext,
            LinearLayoutManager.HORIZONTAL,
            false
        )

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

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

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

        binding.rvCategory.adapter = categoryAdapter

        binding.rvAudioContent.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)) {
                    audioContentAdapter.itemCount - 1 -> {
                        outRect.bottom = 0
                    }

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

        binding.rvAudioContent.layoutManager = LinearLayoutManager(
            applicationContext,
            LinearLayoutManager.VERTICAL,
            false
        )

        binding.rvAudioContent.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)) {
                    audioContentAdapter.itemCount - 1 -> {
                        outRect.bottom = 0
                    }

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

        binding.rvAudioContent.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.getAudioContentList(userId = userId) { }
                }
            }
        })

        binding.rvAudioContent.adapter = audioContentAdapter

        binding.tvSortNewest.setOnClickListener {
            viewModel.changeSort(AudioContentViewModel.Sort.NEWEST)
        }

        binding.tvSortPriceLow.setOnClickListener {
            viewModel.changeSort(AudioContentViewModel.Sort.PRICE_LOW)
        }

        binding.tvSortPriceHigh.setOnClickListener {
            viewModel.changeSort(AudioContentViewModel.Sort.PRICE_HIGH)
        }

        if (userId == SharedPreferenceManager.userId) {
            binding.tvNewContent.visibility = View.VISIBLE
            binding.tvNewContent.setOnClickListener {
                startActivity(
                    Intent(
                        applicationContext,
                        AudioContentUploadActivity::class.java
                    )
                )
            }
        } else {
            binding.tvNewContent.visibility = View.GONE
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun bindData() {
        viewModel.toastLiveData.observe(this) {
            it?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show() }
        }

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

        viewModel.audioContentListLiveData.observe(this) {
            if (viewModel.page - 1 == 1) {
                audioContentAdapter.items.clear()
                binding.rvAudioContent.scrollToPosition(0)
            }

            binding.tvTotalCount.text = "${it.totalCount}"

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

        viewModel.sort.observe(this) {
            deselectSort()
            selectSort(
                when (it) {
                    AudioContentViewModel.Sort.PRICE_HIGH -> {
                        binding.tvSortPriceHigh
                    }

                    AudioContentViewModel.Sort.PRICE_LOW -> {
                        binding.tvSortPriceLow
                    }

                    else -> {
                        binding.tvSortNewest
                    }
                }
            )
            viewModel.getAudioContentList(userId = userId) { finish() }
        }

        viewModel.categoryListLiveData.observe(this) {
            if (it.isNotEmpty()) {
                binding.rvCategory.visibility = View.VISIBLE
                val items = it as MutableList<GetCategoryListResponse>
                items.add(0, GetCategoryListResponse(0, "전체"))
                categoryAdapter.addItems(items = items)
            } else {
                binding.rvCategory.visibility = View.GONE
            }
        }
    }

    private fun deselectSort() {
        val color = ContextCompat.getColor(
            applicationContext,
            R.color.color_88e2e2e2
        )

        binding.tvSortNewest.setTextColor(color)
        binding.tvSortPriceLow.setTextColor(color)
        binding.tvSortPriceHigh.setTextColor(color)
    }

    private fun selectSort(view: TextView) {
        view.setTextColor(
            ContextCompat.getColor(
                applicationContext,
                R.color.color_e2e2e2
            )
        )
    }
}
