package com.develop.base.app

import android.app.Application
import android.content.Context
import androidx.multidex.MultiDex
import com.alibaba.android.arouter.launcher.ARouter
import com.drake.net.NetConfig
import com.drake.net.cookie.PersistentCookieJar
import com.drake.net.interceptor.LogRecordInterceptor
import com.drake.net.okhttp.setConverter
import com.drake.net.okhttp.setDebug
import com.drake.net.okhttp.setRequestInterceptor
import com.github.moduth.blockcanary.BlockCanary
import com.github.moduth.blockcanary.BlockCanaryContext
import com.scwang.smart.refresh.footer.ClassicsFooter
import com.scwang.smart.refresh.header.MaterialHeader
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import com.tencent.bugly.crashreport.CrashReport
import com.develop.base.BuildConfig
import com.develop.base.util.MMkvUtils
import com.develop.base.util.TopResumedAtyHolder
import com.drake.net.convert.NetConverter
import com.drake.net.interceptor.RequestInterceptor
import com.drake.net.interfaces.NetErrorHandler
import com.drake.net.okhttp.setErrorHandler
import okhttp3.Cache
import java.util.concurrent.TimeUnit

abstract class BaseApp : Application() {

    companion object {
        lateinit var application: Application
    }

    abstract fun createHostUrl(): String

    abstract fun createRequestInterceptor(): RequestInterceptor

    abstract fun createConverter(): NetConverter

    abstract fun createErrorHandle(): NetErrorHandler


    override fun onCreate() {
        super.onCreate()
        initNet()
        initThirdPart()
    }

    override fun attachBaseContext(base: Context?) {
        super.attachBaseContext(base)
        application = this
        MultiDex.install(this)
        registerActivityLifecycleCallbacks(TopResumedAtyHolder)
    }


    /** 初始化Net库 */
    private fun initNet() {
        //host - 请求url的主机名, 该参数会在每次请求时自动和请求路径进行拼接(如果路径包含https/http则不会拼接)
        NetConfig.initialize(createHostUrl(), this) {
            //超时设置
            connectTimeout(30, TimeUnit.SECONDS)
            readTimeout(30, TimeUnit.SECONDS)
            writeTimeout(30, TimeUnit.SECONDS)

            // 本框架支持Http缓存协议和强制缓存模式
            // 缓存设置, 当超过maxSize最大值会根据最近最少使用算法清除缓存来限制缓存大小
            cache(Cache(cacheDir, 1024 * 1024 * 128))

            // LogCat是否输出异常日志, 异常日志可以快速定位网络请求错误
            setDebug(BuildConfig.DEBUG)

            // AndroidStudio OkHttp Profiler 插件输出网络日志
            addInterceptor(LogRecordInterceptor(BuildConfig.DEBUG))

            // 添加持久化Cookie管理
            cookieJar(PersistentCookieJar(this@BaseApp))

            // 添加请求拦截器, 可配置全局/动态参数（MyRequestInterceptor自定义）
            setRequestInterceptor(createRequestInterceptor())

            // 数据转换器
            setConverter(createConverter())

            //全局错误处理
            setErrorHandler(createErrorHandle())

            // 自定义全局加载对话框
            // setDialogFactory()
        }
    }

    /** 初始化第三方依赖库 */
    private fun initThirdPart() {
        // 初始化SmartRefreshLayout, 这是自动下拉刷新和上拉加载采用的第三方库
        SmartRefreshLayout.setDefaultRefreshHeaderCreator { context, layout ->
            MaterialHeader(context)
        }
        SmartRefreshLayout.setDefaultRefreshFooterCreator { context, _ ->
            ClassicsFooter(context)
        }

        //阿里路由
        if (BuildConfig.DEBUG) {
            // 开启调试模式(如果在InstantRun模式下运行，必须开启调试模式！线上版本需要关闭,否则有安全风险)
            ARouter.openDebug()
        }
        ARouter.init(application) // 尽可能早，推荐在Application中初始化
        ARouter.getInstance().inject(this)
        ARouter.openLog()

        //优化策略
        CrashReport.initCrashReport(this, "0c1b27f35b", BuildConfig.DEBUG)
        BlockCanary.install(this, BlockCanaryContext()).start()

        //键值对保存
        MMkvUtils.initialize(this)
    }
}