package com.gh.common.util

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Parcelable
import androidx.fragment.app.Fragment
import com.gh.gamecenter.common.annotation.Synchronize
import com.gh.common.util.SyncDataBetweenPageHelper.resultHandle
import com.gh.common.util.SyncDataBetweenPageHelper.startActivityForResult
import com.gh.gamecenter.entity.RatingComment
import com.gh.gamecenter.gamedetail.rating.RatingAdapter
import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity

/**
 * 页面之间实现数据同步（前提：页面之前拥有同一个数据实体）
 * 需要同步的数据,在相应的字段加上[Synchronize]注解,关键方法[resultHandle]
 * 如无特殊情况,尽量使用下面方法进行页面联动
 * 注意: [startActivityForResult] intent的数据实体key必须是Class的SimpleName
 * ----------------------------------------------------------------
 * 具体参考(游戏详情:评论列表<-->评论详情):
 * 数据实体=>[RatingComment]
 * 回调数据=>[RatingReplyActivity.handleBackPressed]
 * 回调处理=>[RatingAdapter.handleSyncData]
 */


object SyncDataBetweenPageHelper {

    private const val REQUEST_CODE_TAG = "REQUEST_CODE_TAG"
    private const val DATA_POSITION_TAG = "DATA_POSITION_TAG"
    private const val DEFAULT_NUMBER = -1111

    fun startActivityForResult(context: Context, intent: Intent, requestCode: Int, dataPosition: Int) {
        if (context is Activity) {
            intent.putExtra(DATA_POSITION_TAG, dataPosition)
            intent.putExtra(REQUEST_CODE_TAG, requestCode)
            context.startActivityForResult(intent, requestCode)
        }
    }

    fun startActivityForResult(fragment: Fragment, intent: Intent, requestCode: Int, dataPosition: Int) {
        intent.putExtra(DATA_POSITION_TAG, dataPosition)
        intent.putExtra(REQUEST_CODE_TAG, requestCode)
        fragment.startActivityForResult(intent, requestCode)
    }

    fun <T : Parcelable> setResultAndFinish(
        context: Context,
        syncData: T?,
        resultCode: Int = Activity.RESULT_OK
    ): Boolean {
        if (context is Activity) {
            val requestCode = context.intent.getIntExtra(REQUEST_CODE_TAG, DEFAULT_NUMBER)
            val dataPosition = context.intent.getIntExtra(DATA_POSITION_TAG, DEFAULT_NUMBER)
            if (syncData != null && requestCode != DEFAULT_NUMBER) {
                val intent = Intent()
                intent.putExtra(DATA_POSITION_TAG, dataPosition)
                intent.putExtra(syncData::class.java.simpleName, syncData)
                context.setResult(resultCode, intent)
                context.finish()
                return true
            }
        }
        return false
    }

    fun <T : Parcelable> resultHandle(intent: Intent?, callback: OnSyncCallBack<T>) {
        if (intent == null) return

        val dataPosition = intent.getIntExtra(DATA_POSITION_TAG, DEFAULT_NUMBER)
        val syncData = callback.onData(dataPosition) ?: return

        val resultData = intent.getParcelableExtra<T>(syncData::class.java.simpleName)
        val fields = syncData::class.java.declaredFields
        var isNeedNotify = false
        for (field in fields) {
            if (field.getAnnotation(Synchronize::class.java) != null && resultData != null) {
                // 同步数据
                val resultField = resultData::class.java.getDeclaredField(field.name)
                resultField.isAccessible = true
                field.isAccessible = true

                val resultFieldDate = resultField.get(resultData)
                if (field.get(syncData) != resultFieldDate) {
                    field.set(syncData, resultFieldDate)
                    if (!isNeedNotify) isNeedNotify = true
                }
            }
        }

        if (isNeedNotify) callback.onNotify(dataPosition)
    }
}

/**
 * dataPosition: 数据位置,和[SyncDataBetweenPageHelper.startActivityForResult] 的dataPosition对应
 * [onData]: 返回需要同步的原数据
 * [onNotify]: 同步完成后刷新页面,如果数据没有更改的话就不会触发(如果标记的不是基本数据类型有可能会触发)
 */
interface OnSyncCallBack<T> {
    fun onData(dataPosition: Int): T?

    fun onNotify(dataPosition: Int)
}