package com.gamedog.vididin.manager


import com.ama.core.architecture.util.FileUtil
import com.ama.core.architecture.util.eventbus.NotifyMan
import com.gamedog.vididin.VidiConst
import com.gamedog.vididin.VididinEvents
import com.gamedog.vididin.beans.RECORD_GOLD_PLUS_WATCH_REWARD_AD
import com.gamedog.vididin.beans.RECORD_GOLD_PLUS_WATCH_VIDEO_BY_TIME_DURATION
import com.gamedog.vididin.beans.RecordGold
import com.gamedog.vididin.core.login.login.AccountManager
import com.gamedog.vididin.main.fragments.task.BoxTaskRoot
import com.gamedog.vididin.main.fragments.task.Task
import com.gamedog.vididin.main.fragments.task.TaskBean
import com.gamedog.vididin.manager.helpers.BoxTaskHelper
import com.gamedog.vididin.manager.helpers.DailySignTaskHelper
import com.gamedog.vididin.manager.helpers.DailyWatchAdTaskHelper
import com.gamedog.vididin.manager.helpers.DailyWatchVideoTaskHelper
import com.gamedog.vididin.manager.helpers.NewbieEnableNotifyHelper
import com.gamedog.vididin.manager.helpers.NewbieFirstWithdrawHelper
import com.gamedog.vididin.manager.helpers.NewbieJoinDiscordHelper
import com.gamedog.vididin.youtubestatistic.RewardConst
import com.google.gson.GsonBuilder
import com.remax.notification.newUtil.NotificationDatas
import com.remax.notification.newUtil.NotificationDatas.IResidentDataCallback
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.*

class TaskManager private constructor() {
    companion object {
        // 新手任务分类及其子类
        private const val TAG_CATEGORY_NEWBIE_TASK = "newbie_task"
        private const val TAG_TASK_NEWBIE_FIRST_WITHDRAW = "newbie_first_withdraw"
        private const val TAG_TASK_NEWBIE_PUSH_NOTIFY = "newbie_push_notify"
        private const val TAG_TASK_NEWBIE_JOIN_DISCORD = "newbie_join_discord"
        private const val TAG_TASK_NEWBIE_7DAY_CHECKIN = "newbie_7day_checkin"

        // 日常任务分类及其子类
        private const val TAG_CATEGORY_DAILY_TASK = "daily_task"
        private const val TAG_TASK_DAILY_CHECKIN = "daily_checkin"
        private const val TAG_TASK_DAILY_VIDEO = "daily_video_ladder"
        private const val TAG_TASK_DAILY_AD = "daily_ad_ladder"






        // 宝箱子任务类型对应
        const val BOX_SUB_TASK_TYPE_AD = 1
        const val BOX_SUB_TASK_TYPE_VIDEO = 2
        const val BOX_SUB_TASK_TYPE_SIGN = 3
        const val BOX_SUB_TASK_TYPE_ZERO_BUY = 4











        @Volatile
        private var instance: TaskManager? = null

        fun instance(): TaskManager {
            return instance ?: synchronized(this) {
                instance ?: TaskManager().also {
                    instance = it
                }
            }
        }
    }




    @Volatile
    private var initialized = false
    private val mutex = Mutex()
    private val mGson = GsonBuilder().create()
    private var mTaskConfig: TaskBean? = null


    private val mDailySignTaskHelper by lazy { DailySignTaskHelper() }
    private val mDailyWatchVideoTaskHelper by lazy { DailyWatchVideoTaskHelper() }
    private val mDailyWatchAdTaskHelper by lazy { DailyWatchAdTaskHelper() }
    private val mBoxHelper by lazy { BoxTaskHelper() }
    private val mNewbieJoinDiscordHelper by lazy { NewbieJoinDiscordHelper() }
    private val mNewbieEnableNotifyHelper by lazy { NewbieEnableNotifyHelper() }
    private val mNewbieFirstWithdrawHelper by lazy { NewbieFirstWithdrawHelper() }




    init {
        loadTaskConfigAsync()
        registerEvents()

        // TODO - remove test code
        if (false) {
            mDailySignTaskHelper.generateTestDailySignTestBean()
        }
    }

    private fun registerEvents() {
        NotifyMan.instance().register(object : NotifyMan.ICallback(true) {
            override fun onEvent(data: NotifyMan.NotifyData<*>?) {
                when (data?.mEventType) {
                    VididinEvents.EVENT_AD_WATCHED_FOR_CONVERT_GOLD_2_CASH -> {
                        AccountManager.convertGold2Cash()
                    }

                    VididinEvents.EVENT_AD_WATCHED_FOR_EARN_GOLD -> {
                        val goldNum = VidiConst.WATCH_AD_REWARD_GOLD.toLong()
                        AccountManager.adjustGold(goldNum, RecordGold(RECORD_GOLD_PLUS_WATCH_REWARD_AD, goldNum))
                    }
                }
            }
        }, VididinEvents.EVENT_AD_WATCHED_FOR_CONVERT_GOLD_2_CASH, VididinEvents.EVENT_AD_WATCHED_FOR_EARN_GOLD)
    }


    suspend fun getTaskConfig(): TaskBean? = mutex.withLock {
        if (!initialized) {
            loadTaskConfigFromAsset()
        }
        return mTaskConfig
    }

    private fun loadTaskConfigAsync() {
        CoroutineScope(Dispatchers.IO).launch {
            mutex.withLock {
                if (!initialized) {
                    loadTaskConfigFromAsset()
                    initHelpers()
                }
            }
        }
    }

    private suspend fun loadTaskConfigFromAsset() {
        return withContext(Dispatchers.IO) {
            val configStr = FileUtil.readAssetsFile("taskConfig.json")
            mTaskConfig = mGson.fromJson(configStr, TaskBean::class.java)
            initialized = true
        }
    }

    private suspend fun initHelpers() {
        mDailySignTaskHelper.setConfigDatas(getDailyCheckInTask()!!)
        mDailyWatchVideoTaskHelper.setConfigDatas(getDailyVideoTask()!!)
        mDailyWatchAdTaskHelper.setConfigDatas(getDailyAdTask()!!)
        mNewbieJoinDiscordHelper.setConfigDatas(getNewbieJoinDiscordTask()!!)
        mNewbieEnableNotifyHelper.setConfigDatas(getNewbieEnableNotifyTask()!!)
        mNewbieFirstWithdrawHelper.setConfigDatas(getNewbieFirstWithdrawTask()!!)
        mBoxHelper.setConfigDatas(getBoxTaskConfig()!!)
    }

    fun onDateChanged() {
        mDailySignTaskHelper.onDateChanged()
        mDailyWatchVideoTaskHelper.onDateChanged()
        mDailyWatchAdTaskHelper.onDateChanged()
        mBoxHelper.onDateChanged()
        mNewbieJoinDiscordHelper.onDateChanged()
        mNewbieEnableNotifyHelper.onDateChanged()
        mNewbieFirstWithdrawHelper.onDateChanged()
    }


    //------------------------- Tasks Getter ------------------------------
    fun dailySignStatus(): DailySignTaskHelper {
        return mDailySignTaskHelper
    }

    fun dailyWatchVideoStatus(): DailyWatchVideoTaskHelper {
        return mDailyWatchVideoTaskHelper
    }

    fun dailyWatchAdStatus(): DailyWatchAdTaskHelper {
        return mDailyWatchAdTaskHelper
    }

    fun boxTaskStatus(): BoxTaskHelper {
        return mBoxHelper
    }

    fun newbieJoinDiscordStatus(): NewbieJoinDiscordHelper {
        return mNewbieJoinDiscordHelper
    }

    fun newbieEnableNotifyStatus(): NewbieEnableNotifyHelper {
        return mNewbieEnableNotifyHelper
    }

    fun newbieFirstWithdrawStatus(): NewbieFirstWithdrawHelper {
        return mNewbieFirstWithdrawHelper
    }




    //-------------------------  Get tasks  -------------------------------
    // 日常任务
    fun getDailyCheckInTask(): Task? {
        return mTaskConfig?.task_module_config?.getTaskCategoryById(TAG_CATEGORY_DAILY_TASK)?.getTaskById(TAG_TASK_DAILY_CHECKIN)
    }

    fun getDailyVideoTask(): Task? {
        return mTaskConfig?.task_module_config?.getTaskCategoryById(TAG_CATEGORY_DAILY_TASK)?.getTaskById(TAG_TASK_DAILY_VIDEO)
    }

    fun getDailyAdTask(): Task? {
        return mTaskConfig?.task_module_config?.getTaskCategoryById(TAG_CATEGORY_DAILY_TASK)?.getTaskById(TAG_TASK_DAILY_AD)
    }

    // 新手任务
    fun getNewbieFirstWithdrawTask(): Task? {
        return mTaskConfig?.task_module_config?.getTaskCategoryById(TAG_CATEGORY_NEWBIE_TASK)?.getTaskById(TAG_TASK_NEWBIE_FIRST_WITHDRAW)
    }

    fun getNewbieEnableNotifyTask(): Task? {
        return mTaskConfig?.task_module_config?.getTaskCategoryById(TAG_CATEGORY_NEWBIE_TASK)?.getTaskById(TAG_TASK_NEWBIE_PUSH_NOTIFY)
    }

    fun getNewbieJoinDiscordTask(): Task? {
        return mTaskConfig?.task_module_config?.getTaskCategoryById(TAG_CATEGORY_NEWBIE_TASK)?.getTaskById(TAG_TASK_NEWBIE_JOIN_DISCORD)
    }

    fun getNewbieCheckInTask(): Task? {
        return mTaskConfig?.task_module_config?.getTaskCategoryById(TAG_CATEGORY_NEWBIE_TASK)?.getTaskById(TAG_TASK_NEWBIE_7DAY_CHECKIN)
    }


    // 宝箱任务
    fun getBoxTaskConfig(): BoxTaskRoot? {
        return mTaskConfig?.task_module_config?.box_task
    }

    fun initNotificationData() {
        NotificationDatas.setResidentCallback(object : IResidentDataCallback {
            override fun getGoldNumber(): Long {
                return AccountManager.getGold()
            }

            override fun getCashNumber(): Double {
                return AccountManager.getCash()
            }

            override fun getBoxRestTimeStr(): String {
                return mBoxHelper.getLeftValidBoxTotalDurationStr()
            }

            override fun hasWithdrawed01(): Boolean {
                return newbieFirstWithdrawStatus().getStatusBean().hasClaimReward
            }
        })
    }


}



