package com.yidianling.ydlcommon.custom.base

import android.app.Activity
import android.content.Context
import android.content.res.Configuration
import android.content.res.Resources
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.support.annotation.LayoutRes
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.LinearLayout
import com.tbruyelle.rxpermissions2.RxPermissions
import com.umeng.analytics.MobclickAgent
import com.yidianling.ydlcommon.R
import com.yidianling.ydlcommon.custom.ActivityManager
import com.yidianling.ydlcommon.custom.YdlBuryPointUtil
import com.yidianling.ydlcommon.custom.tool.AndroidSystemHelper
import com.yidianling.ydlcommon.custom.tool.StatusBarUtils
import com.yidianling.ydlcommon.custom.ui.LoadingDialogFragment
import com.yidianling.ydlcommon.custom.utils.PlayerFloatHelper
import java.lang.reflect.Field
import kotlin.properties.Delegates

/**
 * 基础 Activity，所有的 Activity 都继承此类
 * author : Zhangwenchao
 * e-mail : zhangwch@yidianling.com
 * time   : 2018/01/27
 */
abstract class BaseActivity : SimplyBaseActivity() {

    var mContext: Activity by Delegates.notNull()

    private var loadingDialogFragment: LoadingDialogFragment? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        //修复Android 8.0 崩溃
        AndroidSystemHelper.fixAndroidOrientationBug(this)
        super.onCreate(savedInstanceState)

        Log.d("TAG", javaClass.name)
        mContext = this

        val layoutResId = layoutResId()
        if (layoutResId != 0) setContentView(layoutResId())
        ActivityManager.getInstance().addStack(this)
        initDataAndEvent()
    }

    override fun setRequestedOrientation(requestedOrientation: Int) {
        if (AndroidSystemHelper.isAllowSetOrientation(this)) {
            super.setRequestedOrientation(requestedOrientation)
        }
    }

    override fun setContentView(@LayoutRes layoutResID: Int) {
        if (isAddStatusView()) {
            val containerView = View.inflate(this, R.layout.layout_root, null) as ViewGroup
            val rootView = containerView.findViewById<LinearLayout>(R.id.ll_root);
            initStatus(rootView);
            val params = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
            val child = View.inflate(this, layoutResID, null)
            rootView.addView(child, params)
            super.setContentView(containerView)
        } else {
            super.setContentView(layoutResID)
        }
    }

    var statusView: View? = null
    /**
     * 初始化状态栏
     */
    private fun initStatus(rootView: View) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            statusView = rootView.findViewById<View>(R.id.view_status_place_holder)
            statusView?.setBackgroundColor(Color.parseColor(getStatusColor()))
            val statusBarHeight = StatusBarUtils.getStatusBarHeight(this)
            val layoutParams = statusView?.getLayoutParams() as LinearLayout.LayoutParams
            layoutParams.height = statusBarHeight
            statusView?.layoutParams = layoutParams
            StatusBarUtils.setTransparentForImageView(this, null)
        }
        if (statusBarDarkMode()) {
            StatusBarUtils.statusBarLightMode(this)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        ActivityManager.getInstance().removeStack(this)
        fixInputMethodManagerLeak()
        PlayerFloatHelper.removeView(this)
    }

    override fun onResume() {
        super.onResume()
        try {
            if (this !is com.yidianling.ydlcommon.custom.h5.NewH5Activity && this::class.java.simpleName != "MainActivity") {
                YdlBuryPointUtil.sendPv(this::class.java.simpleName)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

        MobclickAgent.onResume(this)
        PlayerFloatHelper.showIfPlaying(this)
    }

    override fun onPause() {
        super.onPause()
        MobclickAgent.onPause(this)

    }

    @LayoutRes
    protected abstract fun layoutResId(): Int

    // 初始化数据和事件
    protected abstract fun initDataAndEvent()

    /**
     *  请求运行时权限
     *  @param permissions 权限
     *  @param callback 回调接口
     */
    protected fun requestPermissions(callback: PermissionCallback, vararg permissions: String) {
        RxPermissions(this).request(*permissions)
                .subscribe {
                    if (it) callback.onGranted()
                    else callback.onDenied()
                }
    }

    fun showProgressDialog() {
        showProgressDialog("")
    }


    //显示dialog
    open fun showProgressDialog(str: String?) {
        if (loadingDialogFragment == null) {
            loadingDialogFragment = LoadingDialogFragment.newInstance(str)
        }
        if (loadingDialogFragment?.isAdded!!) {
            return
        }
        loadingDialogFragment?.show(supportFragmentManager, BaseActivity::class.java.simpleName)
    }

    //移除dialog
    open fun dismissProgressDialog() {
        try {
            if (loadingDialogFragment != null && loadingDialogFragment?.isAdded!!) {
                loadingDialogFragment?.hide()
                loadingDialogFragment = null
            }
        } catch (e: Exception) {
            //防止以下错误
            //java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
        }

    }

    var resourcesConfig :Configuration ?=null

    override fun getResources(): Resources {
        //解决 修改系统字体大小后 H5页面大小比例不正常现象
        val res = super.getResources()
        if (resourcesConfig == null){
            //避免重复创建
            resourcesConfig = Configuration()
            resourcesConfig!!.setToDefaults()
        }
        res.updateConfiguration(resourcesConfig, res.displayMetrics)
        return res
    }

    /**
     * 解决 InputMethodManager 导致的内存泄漏问题
     */
    public fun fixInputMethodManagerLeak() {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
            return
        }

        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager

        val arr = arrayOf("mCurRootView", "mServedView", "mNextServedView")
        var f: Field?
        var obj_get: Any?
        for (i in arr.indices) {
            val param = arr[i]
            try {
                f = imm.javaClass.getDeclaredField(param)
                if (f!!.isAccessible === false) {
                    f!!.isAccessible = true
                } // author: sodino mail:sodino@qq.com
                obj_get = f!!.get(imm)
                if (obj_get != null && obj_get is View) {
                    val v_get = obj_get as View?
                    if (v_get!!.context === this) { // 被InputMethodManager持有引用的context是想要目标销毁的
                        f.set(imm, null) // 置空，破坏掉path to gc节点
                    } else {
                        // 不是想要目标销毁的，即为又进了另一层界面了，不要处理，避免影响原逻辑,也就不用继续for循环了
                        break
                    }
                }
            } catch (t: Throwable) {
                t.printStackTrace()
            }
        }
    }
}