package com.gh.gamecenter.gamedetail.fuli.kaifu

import android.app.Dialog
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import com.bigkoo.pickerview.adapter.ArrayWheelAdapter
import com.contrarywind.adapter.WheelAdapter
import com.contrarywind.view.WheelView
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.databinding.DialogServersCalendarTimeSettingBinding
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import java.text.SimpleDateFormat
import java.util.*

/**
 * 设置开服时间弹窗
 */
class ServersCalendarTimeSettingDialog private constructor() : BottomSheetDialogFragment() {

    private lateinit var viewBinding: DialogServersCalendarTimeSettingBinding

    private lateinit var kaifuCalendar: Calendar

    private lateinit var selectKaifuCalendar: Calendar

    private val currentCalendar = Calendar.getInstance()

    private val dateFormat = SimpleDateFormat("yyyy-MM-dd hh时 mm分", Locale.getDefault())

    private var selectCallback: ((Long) -> Unit)? = null

    fun setSelectCallback(callback: ((Long) -> Unit)?) {
        this.selectCallback = callback
    }

    private fun dispatchSelectCallback() {
        val date = viewBinding.date.adapter.getItem(viewBinding.date.currentItem)
        val hour = viewBinding.hour.adapter.getItem(viewBinding.hour.currentItem)
        val minute = viewBinding.minute.adapter.getItem(viewBinding.minute.currentItem)
        dateFormat.parse("$date $hour $minute")?.let {
            selectCallback?.invoke(it.time)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setStyle(STYLE_NORMAL, com.gh.gamecenter.common.R.style.DialogWindowTransparent)
        selectKaifuCalendar = Calendar.getInstance().apply {
            timeInMillis = arguments?.getLong(EntranceConsts.KEY_KAIFU_SELECT_TIME) ?: 0L
        }
        kaifuCalendar = Calendar.getInstance().apply {
            timeInMillis = arguments?.getLong(EntranceConsts.KEY_KAIFU_TIME) ?: 0L
        }
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return super.onCreateDialog(savedInstanceState).apply {
            window?.setWindowAnimations(com.gh.gamecenter.common.R.style.community_publication_animation)
            window?.setGravity(Gravity.BOTTOM)
            if (this is BottomSheetDialog) {
                behavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
                    override fun onStateChanged(bottomSheet: View, newState: Int) {
                        if (newState == BottomSheetBehavior.STATE_DRAGGING) {
                            behavior.state = BottomSheetBehavior.STATE_EXPANDED
                        }
                    }

                    override fun onSlide(bottomSheet: View, slideOffset: Float) {
                    }
                })
            }
        }
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        return DialogServersCalendarTimeSettingBinding.inflate(inflater, container, false).also {
            viewBinding = it
        }.root
    }

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

        viewBinding.cancel.setOnClickListener {
            dismissAllowingStateLoss()
        }

        viewBinding.confirm.setOnClickListener {
            dispatchSelectCallback()
            dismissAllowingStateLoss()
        }


        val dateList = buildDates(currentCalendar, kaifuCalendar)

        initWheelView(
            viewBinding.date,
            ArrayWheelAdapter(dateList),
            calculateCurrentDateItem(currentCalendar, selectKaifuCalendar),
            false
        )

        initWheelView(
            viewBinding.hour,
            ArrayWheelAdapter(buildHours()),
            selectKaifuCalendar.get(Calendar.HOUR_OF_DAY)
        )

        initWheelView(
            viewBinding.minute,
            ArrayWheelAdapter(buildMinutes()),
            selectKaifuCalendar.get(Calendar.MINUTE)
        )
    }

    companion object {

        fun create(
            kaifuSelectTime: Long,
            kaifuTime: Long,
            selectCallback: (Long) -> Unit
        ): ServersCalendarTimeSettingDialog =
            ServersCalendarTimeSettingDialog().apply {
                arguments = Bundle().apply {
                    putLong(EntranceConsts.KEY_KAIFU_SELECT_TIME, kaifuSelectTime)
                    putLong(EntranceConsts.KEY_KAIFU_TIME, kaifuTime)
                }
                setSelectCallback(selectCallback)
            }

        private fun initWheelView(
            wheelView: WheelView,
            adapter: WheelAdapter<*>,
            currentIndex: Int,
            isLoop: Boolean = true
        ) {
            wheelView.javaClass.getDeclaredField("itemsVisible").apply {
                isAccessible = true
                set(wheelView, 7)
            }
            wheelView.setLabel("")
            wheelView.setCyclic(isLoop)
            wheelView.setGravity(Gravity.CENTER)
            wheelView.adapter = adapter
            wheelView.currentItem = currentIndex
            wheelView.setTextSize(14F)
            wheelView.setLineSpacingMultiplier(3F)
            wheelView.setTextXOffset(0)
            wheelView.setDividerColor(ContextCompat.getColor(wheelView.context, com.gh.gamecenter.common.R.color.transparent))
            wheelView.setTextColorCenter(ContextCompat.getColor(wheelView.context, com.gh.gamecenter.common.R.color.text_primary))
            wheelView.setTextColorCenter(ContextCompat.getColor(wheelView.context, com.gh.gamecenter.common.R.color.text_primary))
        }

        private fun calculateCurrentDateItem(
            currentCalendar: Calendar,
            selectKaifuCalendar: Calendar
        ): Int {
            val selectKaifuTime = Calendar.getInstance().apply {
                timeInMillis = selectKaifuCalendar.timeInMillis
                set(Calendar.HOUR_OF_DAY, 0)
                set(Calendar.MINUTE, 0)
                set(Calendar.SECOND, 0)
                set(Calendar.MILLISECOND, 0)
            }.timeInMillis
            val currentTime = Calendar.getInstance().apply {
                timeInMillis = currentCalendar.timeInMillis
                set(Calendar.HOUR_OF_DAY, 0)
                set(Calendar.MINUTE, 0)
                set(Calendar.SECOND, 0)
                set(Calendar.MILLISECOND, 0)
            }.timeInMillis
            return ((selectKaifuTime - currentTime) / (24 * 60 * 60 * 1000)).toInt()

        }

        private fun buildDates(currentCalendar: Calendar, kaifuCalendar: Calendar): List<String> {
            val dateList = mutableListOf<String>()
            val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
            val calendar = Calendar.getInstance().apply {
                timeInMillis = currentCalendar.timeInMillis
                set(Calendar.HOUR_OF_DAY, 0)
                set(Calendar.MINUTE, 0)
                set(Calendar.SECOND, 0)
                set(Calendar.MILLISECOND, 0)
            }

            val kaifuTime = Calendar.getInstance().apply {
                timeInMillis = kaifuCalendar.timeInMillis
                set(Calendar.HOUR_OF_DAY, 0)
                set(Calendar.MINUTE, 0)
                set(Calendar.SECOND, 0)
                set(Calendar.MILLISECOND, 0)
            }.timeInMillis
            var dateTime = calendar.timeInMillis
            var dateOffset = (kaifuTime - dateTime) / (24 * 60 * 60 * 1000)
            while (dateOffset >= 0) {
                dateList.add(dateFormat.format(dateTime))
                dateTime = calendar.apply {
                    add(Calendar.DAY_OF_YEAR, 1)
                }.timeInMillis
                dateOffset = (kaifuTime - dateTime) / (24 * 60 * 60 * 1000)
            }
            return dateList
        }

        private fun buildHours(): List<String> {
            val hourList = mutableListOf<String>()
            for (hour in 0..23) {
                hourList.add("${hour}时")
            }
            return hourList
        }

        private fun buildMinutes(): List<String> {
            val minuteList = mutableListOf<String>()
            for (minute in 0..59) {
                minuteList.add("${minute}分")
            }
            return minuteList
        }
    }
}