package kr.co.vividnext.sodalive.live.room.update

import android.annotation.SuppressLint
import android.app.DatePickerDialog
import android.app.TimePickerDialog
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.MotionEvent
import android.widget.Toast
import androidx.core.content.IntentCompat
import com.jakewharton.rxbinding4.widget.textChanges
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers
import kr.co.vividnext.sodalive.R
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.databinding.ActivityLiveRoomEditBinding
import kr.co.vividnext.sodalive.extensions.convertDateFormat
import kr.co.vividnext.sodalive.live.room.detail.GetRoomDetailResponse
import org.koin.android.ext.android.inject
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

class LiveRoomEditActivity : BaseActivity<ActivityLiveRoomEditBinding>(
    ActivityLiveRoomEditBinding::inflate
) {

    private val viewModel: LiveRoomEditViewModel by inject()

    private lateinit var loadingDialog: LoadingDialog

    private val handler = Handler(Looper.getMainLooper())

    private val datePickerDialogListener =
        DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
            viewModel.beginDate = String.format("%d-%02d-%02d", year, monthOfYear + 1, dayOfMonth)
            viewModel.setReservationDate(
                String.format(
                    "%d.%02d.%02d",
                    year,
                    monthOfYear + 1,
                    dayOfMonth
                )
            )
        }

    private val timePickerDialogListener =
        TimePickerDialog.OnTimeSetListener { _, hourOfDay, minute ->
            val timeString = String.format("%02d:%02d", hourOfDay, minute)
            viewModel.beginTime = timeString
            viewModel.setReservationTime(timeString.convertDateFormat("HH:mm", "a hh:mm"))
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        val roomDetail = IntentCompat.getParcelableExtra(
            intent,
            Constants.EXTRA_ROOM_DETAIL,
            GetRoomDetailResponse::class.java
        )

        super.onCreate(savedInstanceState)

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

        bindData()
        binding.etTitle.setText(roomDetail!!.title)
        binding.etContent.setText(roomDetail.notice)
        binding.etNumberOfPeople.setText(roomDetail.numberOfParticipantsTotal.toString())
        viewModel.setRoomDetail(roomDetail = roomDetail)
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun setupView() {
        loadingDialog = LoadingDialog(this, layoutInflater)

        binding.toolbar.tvBack.text = "라이브 수정"
        binding.toolbar.tvBack.setOnClickListener { finish() }

        binding.tvReservationDate.setOnClickListener {
            val reservationDate = viewModel.beginDate.split("-")
            val datePicker: DatePickerDialog

            if (reservationDate.isNotEmpty() && reservationDate.size == 3) {
                datePicker = DatePickerDialog(
                    this,
                    R.style.DatePickerStyle,
                    datePickerDialogListener,
                    reservationDate[0].toInt(),
                    reservationDate[1].toInt() - 1,
                    reservationDate[2].toInt()
                )
            } else {
                val dateString = SimpleDateFormat(
                    "yyyy.MM.dd",
                    Locale.getDefault()
                ).format(Date()).split(".")

                datePicker = DatePickerDialog(
                    this,
                    R.style.DatePickerStyle,
                    datePickerDialogListener,
                    dateString[0].toInt(),
                    dateString[1].toInt() - 1,
                    dateString[2].toInt()
                )
            }

            datePicker.show()
        }
        binding.tvReservationTime.setOnClickListener {
            val reservationTime = viewModel.beginTime.split(":")
            val timePicker: TimePickerDialog

            if (reservationTime.isNotEmpty() && reservationTime.size == 2) {
                timePicker = TimePickerDialog(
                    this,
                    R.style.TimePickerStyle,
                    timePickerDialogListener,
                    reservationTime[0].toInt(),
                    reservationTime[1].toInt(),
                    false
                )
            } else {
                val timeString = SimpleDateFormat(
                    "HH:mm",
                    Locale.getDefault()
                ).format(Date()).split(":")

                timePicker = TimePickerDialog(
                    this,
                    R.style.TimePickerStyle,
                    timePickerDialogListener,
                    timeString[0].toInt(),
                    timeString[1].toInt(),
                    false
                )
            }

            timePicker.show()
        }
        binding.tvUpdate.setOnClickListener {
            binding.tvUpdate.isEnabled = false

            viewModel.updateLiveRoom { finish() }

            handler.postDelayed(
                { binding.tvUpdate.isEnabled = true },
                3000
            )
        }

        binding.etContent.setOnTouchListener { view, motionEvent ->
            view.parent.parent.requestDisallowInterceptTouchEvent(true)
            if ((motionEvent.action and MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP) {
                view.parent.parent.requestDisallowInterceptTouchEvent(false)
            }
            false
        }
    }

    @SuppressLint("SetTextI18n")
    private fun bindData() {
        compositeDisposable.add(
            binding.etTitle.textChanges().skip(1)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe {
                    viewModel.title = it.toString()
                }
        )

        compositeDisposable.add(
            binding.etContent.textChanges().skip(1)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe {
                    binding.tvNumberOfCharacters.text = "${it.length}자"
                    viewModel.content = it.toString()
                }
        )

        compositeDisposable.add(
            binding.etNumberOfPeople.textChanges().skip(1)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe {
                    if (it.isEmpty()) {
                        viewModel.numberOfPeople = 0
                    } else {
                        viewModel.numberOfPeople = it.toString().toInt()
                    }
                }
        )

        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.reservationDateLiveData.observe(this) {
            binding.tvReservationDate.text = it
        }

        viewModel.reservationTimeLiveData.observe(this) {
            binding.tvReservationTime.text = it
        }
    }
}
