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

import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.GridLayoutManager
import com.gh.common.util.CheckLoginUtils
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.databinding.ActivityServersCalendarBinding
import com.gh.gamecenter.entity.CalendarEntity
import com.gh.gamecenter.feature.entity.GameDetailServer
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.MeEntity
import com.gh.gamecenter.feature.entity.ServerCalendarEntity
import com.halo.assistant.HaloApp
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.text.SimpleDateFormat
import java.util.*

/**
 * 开服日历表
 */
class ServersCalendarActivity : ToolBarActivity() {
    private lateinit var mBinding: ActivityServersCalendarBinding
    private lateinit var mViewModel: ServersCalendarViewModel

    private val mDelayLogRunnable = Runnable {
        NewLogUtils.logGameDetailOpenCalendarView(mViewModel.game.name ?: "", mViewModel.game.id)
    }

    private val mMoreDialog by lazy { ServersCalendarMoreDialog() }

    private val mWeChatSubscriptionSuccessDialog by lazy { ServersCalendarWeChatSubscriptionSuccessDialog() }

    private val mSubscriptionSuccessDialog by lazy { ServersCalendarSubscriptionSuccessDialog() }


    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        val serverCalendars = mViewModel.serverCalendarLiveData.value ?: return
        if (requestCode == GAME_DETAIL_ADD_KAIFU_REQUEST && resultCode == Activity.RESULT_OK) { // 新增开服
            val dataList = data!!.getParcelableArrayListExtra<ServerCalendarEntity>(GAME_DETAIL_ADD_KAIFU_KEY)
            if (dataList != null) {
                serverCalendars.addAll(dataList)
                mViewModel.serverCalendarLiveData.postValue(serverCalendars)
            }
        } else if (requestCode == GAME_DETAIL_PATCH_KAIFU_REQUEST && resultCode == Activity.RESULT_OK) { // 修改开服
            val dataEntity = data!!.getParcelableExtra<ServerCalendarEntity>(GAME_DETAIL_PATCH_KAIFU_KEY)
            if (dataEntity != null) {
                if (TextUtils.isEmpty(dataEntity.getNote())) { // 删除
                    for (entity in serverCalendars) {
                        if (dataEntity.id == entity.id) {
                            serverCalendars.remove(entity)
                            mViewModel.serverCalendarLiveData.postValue(serverCalendars)
                            break
                        }
                    }
                } else { // 更改
                    for (entity in serverCalendars) {
                        if (dataEntity.id == entity.id) {
                            entity.setNote(dataEntity.getNote())
                            entity.remark = dataEntity.remark
                            mViewModel.serverCalendarLiveData.postValue(serverCalendars)
                            break
                        }
                    }
                }
            }
        }
    }

    override fun getLayoutId(): Int {
        return R.layout.activity_servers_calendar
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        val game = intent?.getParcelableExtra<GameEntity>(GameEntity::class.java.simpleName)
        val serverList = intent?.getParcelableExtra<GameDetailServer>(GameDetailServer::class.java.simpleName)
        val meEntity = intent?.getParcelableExtra<MeEntity>(MeEntity::class.java.simpleName)
        if (game == null || serverList == null) {
            throwExceptionInDebug()
            return
        }

        // 必须放在super.onCreate前面，因为子Fragment的onCreate方法也是在super.onCreate回调的时候调用
        // 如果放在super.onCreate之后，那么在页面重构时，子Fragment在onCreate方法引用通过viewModels方法获取parentViewModel将触发崩溃
        val factory = ServersCalendarViewModel.Factory(HaloApp.getInstance().application, game, serverList, meEntity)
        mViewModel = ViewModelProviders.of(this, factory).get(ServersCalendarViewModel::class.java)
        mViewModel.setKaifuTime(intent.getLongExtra(EntranceConsts.KEY_KAIFU_TIME, 0))

        super.onCreate(savedInstanceState)
        updateStatusBarColor(com.gh.gamecenter.common.R.color.ui_surface, com.gh.gamecenter.common.R.color.ui_surface)
        setNavigationTitle("开服日历表")

        mBinding = ActivityServersCalendarBinding.bind(mContentView)
        mBinding.includeNoConnection.root.setOnClickListener {
            mBinding.includeLoading.root.visibility = View.VISIBLE
            mBinding.includeNoConnection.root.visibility = View.GONE
            mViewModel.loadServerData()
        }

        mViewModel.calendarLiveData.observeNonNull(this, callback = {
            val adapter = ServersCalendarAdapter(this, mViewModel, it)
            mBinding.recyclerView.isNestedScrollingEnabled = false
            mBinding.recyclerView.layoutManager = GridLayoutManager(this, 7)
            mBinding.recyclerView.adapter = adapter
        })
        mViewModel.serversDetailLiveData.observeNonNull(this, callback = {
            showServersCalendarDetailDialog(it)
            NewLogUtils.logGameDetailOpenCalendarClick(mViewModel.game.name ?: "", mViewModel.game.id)
        })
        mViewModel.serverCalendarLiveData.observe(this) {
            if (it != null) {
                mViewModel.initDate()
                initView()
            } else {
                mBinding.includeLoading.root.visibility = View.GONE
                mBinding.includeNoConnection.root.visibility = View.VISIBLE
            }
        }
        mViewModel.serverSubscriptionLiveData.observe(this) {
            // 用户订阅状态
           if (it?.byApp == true) {// 用户已登录并处于已订阅状态
                clearMenu()
                setToolbarMenu(R.menu.menu_server_calendar_more)
                mBinding.subscribe.visibility = View.GONE
                mBinding.subscribeHint1.visibility = View.GONE
                mBinding.subscribe.setOnClickListener(null)
            } else {// 用户已登录并处于未订阅状态
                clearMenu()
                mBinding.subscribe.visibility = View.VISIBLE
                mBinding.subscribeHint1.visibility = View.VISIBLE
                mBinding.subscribe.setOnClickListener {
                    CheckLoginUtils.checkLogin(this, "游戏详情-开服日历表-开启订阅") {
                        mViewModel.subscribeServer()
                        NewLogUtils.logLaunchServerSubscribeAdd(
                            gameId = mViewModel.game.id,
                            gameName = mViewModel.game.name ?: ""
                        )
                        SensorsBridge.trackLaunchServerSubscribeClick(
                            gameId = mViewModel.game.id,
                            gameName = mViewModel.game.name ?: "",
                            gameType = mViewModel.game.categoryChinese
                        )
                    }
                }
            }
        }
        mViewModel.subscribeServerSuccessEvent.observe(this) {
            val serverSubscription = mViewModel.serverSubscriptionLiveData.value
            if (serverSubscription?.byWeChat != true && !mWeChatSubscriptionSuccessDialog.isAdded) {// 开启微信提醒弹窗
                mWeChatSubscriptionSuccessDialog.showNow(
                    supportFragmentManager,
                    SERVERS_CALENDAR_WECHAT_SUBSCRIPTION_DIALOG_TAG
                )
            } else if (!mSubscriptionSuccessDialog.isAdded) {// 开启订阅成功提醒弹窗
                mSubscriptionSuccessDialog.showNow(
                    supportFragmentManager,
                    SERVERS_CALENDAR_SUBSCRIPTION_DIALOG_TAG
                )
            }
        }
        mViewModel.error.observe(this) {
            ToastUtils.showToast(getString(R.string.network_error_hint))
        }
        mBaseHandler.postDelayed(mDelayLogRunnable, 3000)
    }

    override fun onPause() {
        super.onPause()
        mBaseHandler.removeCallbacks(mDelayLogRunnable)
    }

    override fun onMenuItemClick(item: MenuItem?): Boolean {
        if (item?.itemId == R.id.menu_more) {
            if (!mMoreDialog.isAdded) {
                mMoreDialog.showNow(supportFragmentManager, SERVERS_CALENDAR_MORE_DIALOG_TAG)
            }
        }
        return super.onMenuItemClick(item)
    }

    fun initView() {
        mBinding.contentContainer.visibility = View.VISIBLE
        mBinding.includeLoading.root.visibility = View.GONE

        val serversDes = mViewModel.gameServer.des
        if (serversDes.isNotEmpty()) {
            mBinding.des.text = serversDes.fromHtml()
        }

        val curTime = System.currentTimeMillis()

        val formatMonth = SimpleDateFormat("MM", Locale.CHINA)
        val formatMonthText = SimpleDateFormat("M月", Locale.CHINA)
        val formatYearText = SimpleDateFormat("yyyy年", Locale.CHINA)
        val curMonth = formatMonth.format(curTime).toInt()

        var previousTime: Long = -1
        var previousMonth = -1

        var nextTime: Long = -1
        var nextMonth = -1

        for (serverEntity in mViewModel.serverCalendarLiveData.value ?: arrayListOf()) {
            previousTime = serverEntity.getTime() * 1000
            previousMonth = formatMonth.format(previousTime).toInt()
            if (previousMonth != curMonth && previousTime < curTime) break
        }

        for (serverEntity in mViewModel.serverCalendarLiveData.value ?: arrayListOf()) {
            nextTime = serverEntity.getTime() * 1000
            nextMonth = formatMonth.format(nextTime).toInt()
            if (nextMonth != curMonth && nextTime > curTime) break
        }

        // 是否存在下一个月开服表
        if (nextMonth != curMonth && nextTime > curTime) {
            mBinding.nextMonth.text = formatMonthText.format(nextTime)
            mBinding.nextMonth.visibility = View.VISIBLE
        } else {
            mBinding.nextMonth.visibility = View.GONE
        }

        // 是否存在上一个月开服表
        if (previousMonth != curMonth && previousTime < curTime) {
            mBinding.previousMonth.text = formatMonthText.format(previousTime)
            mBinding.previousMonth.visibility = View.VISIBLE
        } else {
            mBinding.previousMonth.visibility = View.GONE
        }


        if (!mViewModel.isExistCurServer) {// 这里已经不执行了，估计是遗留下的旧代码...
            mViewModel.selectedMonth = MonthType.NEXT_MONTH

            mBinding.curMonth.visibility = View.GONE

            mBinding.nextMonth.setBackgroundResource(com.gh.gamecenter.common.R.drawable.download_oval_hint_up)
            mBinding.nextMonth.setTextColor(Color.WHITE)
            mBinding.year.text = formatYearText.format(previousTime)
        } else {
            mBinding.curMonth.visibility = View.VISIBLE

            mBinding.curMonth.text = formatMonthText.format(curTime)
            mBinding.year.text = formatYearText.format(curTime)

            when (mViewModel.selectedMonth) {
                MonthType.CUR_MONTH -> {
                    mBinding.curMonth.setBackgroundResource(com.gh.gamecenter.common.R.drawable.download_oval_hint_up)
                    mBinding.curMonth.setTextColor(Color.WHITE)

                    mBinding.previousMonth.setBackgroundColor(0)
                    mBinding.previousMonth.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(this))
                    mBinding.nextMonth.setBackgroundColor(0)
                    mBinding.nextMonth.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(this))
                }
                MonthType.NEXT_MONTH -> {
                    mBinding.nextMonth.setBackgroundResource(com.gh.gamecenter.common.R.drawable.download_oval_hint_up)
                    mBinding.nextMonth.setTextColor(Color.WHITE)

                    mBinding.curMonth.setBackgroundColor(0)
                    mBinding.curMonth.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(this))
                    mBinding.previousMonth.setBackgroundColor(0)
                    mBinding.previousMonth.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(this))
                }
                else -> {
                    mBinding.previousMonth.setBackgroundResource(com.gh.gamecenter.common.R.drawable.download_oval_hint_up)
                    mBinding.previousMonth.setTextColor(Color.WHITE)

                    mBinding.nextMonth.setBackgroundColor(0)
                    mBinding.nextMonth.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(this))
                    mBinding.curMonth.setBackgroundColor(0)
                    mBinding.curMonth.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(this))
                }
            }

        }

        mBinding.nextMonth.setOnClickListener { v ->
            if (mViewModel.selectedMonth == MonthType.NEXT_MONTH) {
                return@setOnClickListener
            }

            mViewModel.selectedMonth = MonthType.NEXT_MONTH
            mViewModel.initDate()

            mBinding.nextMonth.setBackgroundResource(com.gh.gamecenter.common.R.drawable.download_oval_hint_up)
            mBinding.nextMonth.setTextColor(Color.WHITE)

            mBinding.curMonth.setBackgroundColor(0)
            mBinding.curMonth.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(this))
            mBinding.previousMonth.setBackgroundColor(0)
            mBinding.previousMonth.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(this))
            mBinding.year.text = formatYearText.format(previousTime)
        }

        mBinding.curMonth.setOnClickListener { v ->
            if (mViewModel.selectedMonth == MonthType.CUR_MONTH) {
                return@setOnClickListener
            }

            mViewModel.selectedMonth = MonthType.CUR_MONTH
            mViewModel.initDate()

            mBinding.curMonth.setBackgroundResource(com.gh.gamecenter.common.R.drawable.download_oval_hint_up)
            mBinding.curMonth.setTextColor(Color.WHITE)

            mBinding.nextMonth.setBackgroundColor(0)
            mBinding.nextMonth.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(this))
            mBinding.previousMonth.setBackgroundColor(0)
            mBinding.previousMonth.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(this))
            mBinding.year.text = formatYearText.format(curTime)
        }

        mBinding.previousMonth.setOnClickListener { v ->
            if (mViewModel.selectedMonth == MonthType.PREVIOUS_MONTH) {
                return@setOnClickListener
            }

            mViewModel.selectedMonth = MonthType.PREVIOUS_MONTH
            mViewModel.initDate()

            mBinding.previousMonth.setBackgroundResource(com.gh.gamecenter.common.R.drawable.download_oval_hint_up)
            mBinding.previousMonth.setTextColor(Color.WHITE)

            mBinding.nextMonth.setBackgroundColor(0)
            mBinding.nextMonth.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(this))
            mBinding.curMonth.setBackgroundColor(0)
            mBinding.curMonth.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(this))
            mBinding.year.text = formatYearText.format(curTime)
        }

        if (SPUtils.getBoolean("showServersDetailHint", true)) {
            showHintDialog()
        }
    }

    private fun showHintDialog() {
        val contentView = LayoutInflater.from(this).inflate(R.layout.dialog_servers_calendear_detail_hint, null)
        val params = ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, resources.displayMetrics.heightPixels)
        val dialog = Dialog(this, com.gh.gamecenter.common.R.style.DialogWindowTransparent)
        dialog.setContentView(contentView, params)
        dialog.setCancelable(false)
        dialog.show()

        contentView.findViewById<View>(R.id.confirm).setOnClickListener {
            dialog.dismiss()
            SPUtils.setBoolean("showServersDetailHint", false)
        }
    }


    private fun showServersCalendarDetailDialog(calendarEntity: CalendarEntity) {
        val currentCalendar = Calendar.getInstance().apply {
            set(Calendar.HOUR_OF_DAY, 0)
            set(Calendar.MINUTE, 0)
            set(Calendar.SECOND, 0)
            set(Calendar.MILLISECOND, 0)
        }
        val serverCalendar = Calendar.getInstance().apply {
            set(calendarEntity.year, calendarEntity.month - 1, calendarEntity.day, 0, 0, 0)
        }

        // 开服表详情是否显示提醒按钮，条件如下:
        // 2. 当前开服表日期大于当天日期
        val isRemindFeatureSupported = serverCalendar >= currentCalendar

        if (!isRemindFeatureSupported && calendarEntity.server.isEmpty()) {
            // 小于当前时间的未知服不显示弹窗
            return
        }

        val dialog = if (calendarEntity.server.isEmpty()) {
            ServersCalendarDetailNoDataDialog().apply {
                arguments = Bundle().apply {
                    putInt(EntranceConsts.KEY_CALENDAR_YEAR, calendarEntity.year)
                    putInt(EntranceConsts.KEY_CALENDAR_MONTH, calendarEntity.month)
                    putInt(EntranceConsts.KEY_CALENDAR_DAY, calendarEntity.day)
                }
            }
        } else {
            ServersCalendarDetailDialog().apply {
                arguments = Bundle().apply {
                    putInt(EntranceConsts.KEY_CALENDAR_YEAR, calendarEntity.year)
                    putInt(EntranceConsts.KEY_CALENDAR_MONTH, calendarEntity.month)
                    putInt(EntranceConsts.KEY_CALENDAR_DAY, calendarEntity.day)
                    putBoolean(EntranceConsts.KEY_SHOW_REMIND, isRemindFeatureSupported)
                }
            }
        }
        dialog.showNow(supportFragmentManager, null)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(reuse: EBReuse) {
        if (reuse.type == Constants.LOGIN_TAG || reuse.type == Constants.LOGOUT_TAG) {
            mViewModel.loadServerData()
        }
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        updateStatusBarColor(com.gh.gamecenter.common.R.color.ui_surface, com.gh.gamecenter.common.R.color.ui_surface)
        mBinding.root.setRootBackgroundColor(com.gh.gamecenter.common.R.color.ui_background)
        mBinding.hint.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_background.toColor(this))
        mBinding.hint.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(this))
        mBinding.contentContainer.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(this))
        mBinding.divider.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_background.toColor(this))
        mBinding.dividerLine1.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_background.toColor(this))
        mBinding.dividerLine2.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_background.toColor(this))
        mBinding.year.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(this))
        mBinding.recyclerView.recycledViewPool.clear()
        mBinding.recyclerView.adapter?.notifyItemRangeChanged(0, mBinding.recyclerView.adapter?.itemCount ?: 0)
    }

    companion object {
        const val GAME_DETAIL_PATCH_KAIFU_REQUEST = 51
        const val GAME_DETAIL_ADD_KAIFU_REQUEST = 50
        const val GAME_DETAIL_ADD_KAIFU_KEY = "GAME_DETAIL_ADD_KAIFU_KEY"
        const val GAME_DETAIL_PATCH_KAIFU_KEY = "GAME_DETAIL_PATCH_KAIFU_KEY"

        const val SERVERS_CALENDAR_MORE_DIALOG_TAG = "ServersCalendarMoreDialog"
        const val SERVERS_CALENDAR_WECHAT_SUBSCRIPTION_DIALOG_TAG = "ServersCalendarWeChatSubscriptionDialog"
        const val SERVERS_CALENDAR_SUBSCRIPTION_DIALOG_TAG = "ServersCalendarSubscriptionDialog"

        fun getIntent(context: Context, game: GameEntity, gameServer: GameDetailServer, me: MeEntity?): Intent {
            val intent = Intent(context, ServersCalendarActivity::class.java)
            intent.putExtra(GameEntity::class.java.simpleName, game)
            intent.putExtra(GameDetailServer::class.java.simpleName, gameServer)
            intent.putExtra(MeEntity::class.java.simpleName, me)
            return intent
        }
    }
}