package kr.co.vividnext.sodalive.explorer

import android.annotation.SuppressLint
import android.app.Service
import android.content.Intent
import android.graphics.Rect
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
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.base.BaseFragment
import kr.co.vividnext.sodalive.common.Constants
import kr.co.vividnext.sodalive.common.LoadingDialog
import kr.co.vividnext.sodalive.databinding.FragmentExplorerBinding
import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity
import kr.co.vividnext.sodalive.extensions.dpToPx
import kr.co.vividnext.sodalive.message.SelectMessageRecipientAdapter
import org.koin.android.ext.android.inject
import java.util.concurrent.TimeUnit

class ExplorerFragment : BaseFragment<FragmentExplorerBinding>(
    FragmentExplorerBinding::inflate
) {

    private val viewModel: ExplorerViewModel by inject()

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

    private val handler = Handler(Looper.getMainLooper())
    private lateinit var searchChannelAdapter: SelectMessageRecipientAdapter

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

    private fun hideKeyboard() {
        handler.postDelayed({
            imm.hideSoftInputFromWindow(
                requireActivity().window.decorView.applicationWindowToken,
                InputMethodManager.HIDE_NOT_ALWAYS
            )
        }, 100)
    }

    private fun setupView() {
        adapter = ExplorerAdapter {
            val intent = Intent(requireContext(), UserProfileActivity::class.java)
            intent.putExtra(Constants.EXTRA_USER_ID, it)
            startActivity(intent)
        }

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

        binding.rvExplorer.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 = 0
                        outRect.bottom = 15f.dpToPx().toInt()
                    }

                    adapter.itemCount - 1 -> {
                        outRect.top = 15f.dpToPx().toInt()
                        outRect.bottom = 0
                    }

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

        binding.rvExplorer.adapter = adapter
        setupSearchChannelView()
    }

    private fun setupSearchChannelView() {
        searchChannelAdapter = SelectMessageRecipientAdapter {
            hideKeyboard()
            val intent = Intent(requireContext(), UserProfileActivity::class.java)
            intent.putExtra(Constants.EXTRA_USER_ID, it.id)
            startActivity(intent)
        }

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

        binding.rvSearchChannel.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()
                outRect.top = 13.3f.dpToPx().toInt()
                outRect.bottom = 13.3f.dpToPx().toInt()
            }
        })

        binding.rvSearchChannel.adapter = searchChannelAdapter

        compositeDisposable.add(
            binding.etSearchChannel.textChanges().skip(1)
                .debounce(500, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe {
                    binding.ivX.visibility = if (it.length > 1) {
                        View.VISIBLE
                    } else {
                        View.GONE
                    }

                    if (it.length >= 2) {
                        viewModel.searchChannel(it.toString())
                        binding.rvSearchChannel.visibility = View.VISIBLE
                        binding.rvExplorer.visibility = View.GONE
                    } else {
                        binding.rvSearchChannel.visibility = View.GONE
                        binding.rvExplorer.visibility = View.VISIBLE
                    }

                    binding.tvResultX.visibility = View.GONE
                }
        )

        binding.ivX.setOnClickListener {
            hideKeyboard()
            binding.etSearchChannel.setText("")
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    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.responseLiveData.observe(viewLifecycleOwner) {
            adapter.addItems(it.sections)
        }

        viewModel.searchChannelLiveData.observe(viewLifecycleOwner) {
            searchChannelAdapter.items.clear()
            if (it.isNotEmpty()) {
                searchChannelAdapter.items.addAll(it)
                binding.rvSearchChannel.visibility = View.VISIBLE
                binding.tvResultX.visibility = View.GONE
            } else {
                binding.rvSearchChannel.visibility = View.GONE
                binding.tvResultX.visibility = View.VISIBLE
            }
            searchChannelAdapter.notifyDataSetChanged()
        }
    }
}
