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

import android.annotation.SuppressLint
import android.app.Service
import android.graphics.Rect
import android.os.Bundle
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.jakewharton.rxbinding4.widget.textChanges
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers
import kr.co.vividnext.sodalive.audio_content.playlist.create.add_content.PlaylistAddContentDialogFragment
import kr.co.vividnext.sodalive.audio_content.playlist.detail.AudioContentPlaylistContent
import kr.co.vividnext.sodalive.base.BaseActivity
import kr.co.vividnext.sodalive.common.LoadingDialog
import kr.co.vividnext.sodalive.databinding.ActivityAudioContentPlaylistCreateBinding
import kr.co.vividnext.sodalive.extensions.dpToPx
import org.koin.android.ext.android.inject

class AudioContentPlaylistCreateActivity : BaseActivity<ActivityAudioContentPlaylistCreateBinding>(
    ActivityAudioContentPlaylistCreateBinding::inflate
) {

    private val viewModel: AudioContentPlaylistCreateViewModel by inject()

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

    private val addContentDialogFragment: PlaylistAddContentDialogFragment by lazy {
        PlaylistAddContentDialogFragment(screenWidth, viewModel.contentList) { item, isChecked ->
            when {
                isChecked -> {
                    viewModel.addContentId(
                        AudioContentPlaylistContent(
                            id = item.contentId,
                            title = item.title,
                            category = item.themeStr,
                            coverUrl = item.coverImageUrl,
                            duration = item.duration ?: "00:00:00",
                            creatorNickname = item.creatorNickname
                        )
                    )
                    return@PlaylistAddContentDialogFragment true
                }

                !isChecked -> {
                    viewModel.removeContentId(
                        AudioContentPlaylistContent(
                            id = item.contentId,
                            title = item.title,
                            category = item.themeStr,
                            coverUrl = item.coverImageUrl,
                            duration = item.duration ?: "00:00:00",
                            creatorNickname = item.creatorNickname
                        )
                    )
                    return@PlaylistAddContentDialogFragment true
                }

                else -> {
                    return@PlaylistAddContentDialogFragment false
                }
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        imm = getSystemService(
            Service.INPUT_METHOD_SERVICE
        ) as InputMethodManager

        bindData()
    }

    override fun setupView() {
        binding.tvBack.text = "새 재생목록 만들기"
        binding.tvBack.setOnClickListener { finish() }

        loadingDialog = LoadingDialog(this, layoutInflater)

        binding.tvAddContent.setOnClickListener {
            if (addContentDialogFragment.isAdded) return@setOnClickListener
            addContentDialogFragment.show(supportFragmentManager, addContentDialogFragment.tag)
        }

        binding.tvSave.setOnClickListener {
            viewModel.savePlaylist {
                setResult(RESULT_OK)
                finish()
            }
        }

        adapter = AudioContentPlaylistCreateContentAdapter()

        val recyclerView = binding.rvPlaylistContent
        recyclerView.layoutManager = LinearLayoutManager(
            this,
            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.adapter = adapter
    }

    private fun bindData() {
        viewModel.toastLiveData.observe(this) {
            it?.let { showToast(it) }
        }

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

        viewModel.contentListLiveData.observe(this) {
            adapter.updateItems(it)
        }

        compositeDisposable.add(
            binding.etTitle.textChanges()
                .map { it.toString() }
                .distinctUntilChanged()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe {
                    if (it.length > 30) {
                        val truncated = it.take(30)
                        binding.etTitle.setText(truncated)
                        binding.etTitle.setSelection(truncated.length)
                        setTitle(truncated)
                    } else {
                        setTitle(it)
                    }
                }
        )

        compositeDisposable.add(
            binding.etDesc.textChanges()
                .map { it.toString() }
                .distinctUntilChanged()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe {
                    if (it.length > 40) {
                        val truncated = it.take(40)
                        binding.etDesc.setText(truncated)
                        binding.etDesc.setSelection(truncated.length)
                        setDesc(truncated)
                    } else {
                        setDesc(it)
                    }
                }
        )
    }

    @SuppressLint("SetTextI18n")
    private fun setTitle(title: String) {
        binding.tvTitleLength.text = "${title.length}/30"
        viewModel.title = title
    }

    @SuppressLint("SetTextI18n")
    private fun setDesc(desc: String) {
        binding.tvDescLength.text = "${desc.length}/40"
        viewModel.desc = desc
    }
}
