package com.narutohuo.xindazhou.launch

import android.app.Application
import com.alibaba.android.arouter.launcher.ARouter
import com.narutohuo.xindazhou.common.auth.AuthManager
import com.narutohuo.xindazhou.common.config.ServerConfigManager
import com.narutohuo.xindazhou.common.log.LogHelper
import com.narutohuo.xindazhou.common.network.ApiManager
import com.narutohuo.xindazhou.common.socketio.SocketIOManager
import com.narutohuo.xindazhou.common.version.VersionUpdateManager
import com.narutohuo.xindazhou.core.storage.StorageImpl
import com.narutohuo.xindazhou.share.factory.ShareServiceFactory

/**
 * 应用初始化管理器
 * 
 * 统一管理所有模块的初始化，简化 Application 代码
 * 
 * 位置：app 模块（应用层）
 * 职责：协调所有层的初始化（base-core、base-common、capability-*）
 * 
 * 使用方式：
 * ```kotlin
 * // 在 Application.onCreate() 中调用
 * AppInitializer.init(this)
 * ```
 */
object AppInitializer {
    
    private const val TAG = "AppInitializer"
    private var initialized = false
    
    /**
     * 初始化所有模块
     * 
     * 按顺序初始化各个模块，确保依赖关系正确
     * 
     * @param application Application 实例
     */
    fun init(application: Application) {
        if (initialized) {
            LogHelper.w(TAG, "AppInitializer 已初始化，跳过重复初始化")
            return
        }
        
        try {
            // 1. 初始化统一存储（必须在其他初始化之前，因为其他模块可能依赖存储）
            StorageImpl.init(application.applicationContext)
            LogHelper.d(TAG, "统一存储初始化完成")
            
            // 2. 初始化 ARouter（必须在其他初始化之前）
            initARouter(application)
            
            // 3. 初始化配置管理器（base-common）
            ServerConfigManager.init(application.applicationContext)
            
            // 4. 初始化网络管理器（base-common）
            // ApiManager.initialize() 会自动从 ServerConfigManager 读取服务器地址并初始化 NetworkHelper
            // Token Provider 稍后由 AuthManager 设置
            ApiManager.initialize(application)
            LogHelper.d(TAG, "✅ 网络管理器初始化完成")
            
            // 5. 初始化认证管理器（base-common，会自动初始化 TokenStore，TokenStore 使用 StorageImpl）
            // AuthManager.init() 会自动配置 NetworkHelper 的 Token Provider
            AuthManager.init(application.applicationContext)
            LogHelper.d(TAG, "✅ 认证管理器初始化完成")
            
            // 6. 初始化版本更新管理器（base-common）
            VersionUpdateManager.init(application.applicationContext)
            LogHelper.d(TAG, "✅ 版本更新管理器初始化完成")
            
            // 7. SocketIO 管理器（base-common）
            // SocketIOManager 会自动处理连接、Token 刷新、重连等
            // 业务层可以直接订阅消息，无需关心连接细节
            SocketIOManager.initialize(application)
            LogHelper.d(TAG, "✅ SocketIO 管理器初始化完成（自动处理连接和Token刷新）")
            
            // 8. 初始化分享服务（capability-share，可选）
            initShareService(application)
            
            initialized = true
            LogHelper.d(TAG, "所有模块初始化完成")
        } catch (e: Exception) {
            LogHelper.e(TAG, "初始化失败", e)
            throw e
        }
    }
    
    /**
     * 初始化 ARouter
     */
    private fun initARouter(application: Application) {
        val isDebug = isDebugMode(application)
        if (isDebug) {
            // 开启日志
            ARouter.openLog()
            // 开启调试模式（如果在InstantRun模式下运行，必须开启调试模式！线上版本需要关闭,否则有安全风险)
            ARouter.openDebug()
        }
        // 初始化 ARouter
        ARouter.init(application)
        LogHelper.d(TAG, "ARouter 初始化完成")
    }
    
    /**
     * 初始化分享服务
     * 
     * app 模块直接依赖 capability-share，可以直接导入使用，不需要反射
     */
    private fun initShareService(application: Application) {
        try {
            ShareServiceFactory.init(application)
            LogHelper.d(TAG, "分享服务初始化成功")
        } catch (e: Exception) {
            // 分享服务初始化失败不影响应用运行，但分享功能将不可用
            LogHelper.e(TAG, "分享服务初始化失败，分享功能将不可用", e)
        }
    }
    
    /**
     * 获取是否为调试模式
     * 
     * 安全地获取 BuildConfig.DEBUG，避免模块未引入时崩溃
     */
    private fun isDebugMode(application: Application): Boolean {
        return try {
            val buildConfigClass = Class.forName("${application.packageName}.BuildConfig")
            val debugField = buildConfigClass.getField("DEBUG")
            debugField.getBoolean(null)
        } catch (e: Exception) {
            LogHelper.e(TAG, "无法获取 BuildConfig.DEBUG，默认返回 false", e)
            false
        }
    }
}

