package com.narutohuo.xindazhou.core.network

import com.narutohuo.xindazhou.core.log.ILog
import okhttp3.OkHttpClient
import retrofit2.converter.gson.GsonConverterFactory
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicReference

/**
 * 网络管理器（单例模式 + 建造者模式）
 * 
 * 统一管理 Retrofit 和 OkHttpClient 实例，避免重复创建
 * 
 * 设计模式：
 * - 单例模式：全局唯一实例
 * - 建造者模式：通过 NetworkConfig 灵活配置
 * 
 * 使用方式：
 * ```kotlin
 * // 使用默认配置
 * val retrofit = NetworkManager.getRetrofit()
 * 
 * // 使用自定义配置
 * val retrofit = NetworkManager.getRetrofit(
 *     NetworkConfig.Builder()
 *         .baseUrl("https://api.example.com")
 *         .connectTimeout(60, TimeUnit.SECONDS)
 *         .build()
 * )
 * ```
 */
object NetworkManager {
    
    private const val TAG = "NetworkManager"
    
    // 使用 AtomicReference 确保线程安全
    private val retrofitRef = AtomicReference<Retrofit?>()
    private val okHttpClientRef = AtomicReference<OkHttpClient?>()
    
    // 默认配置
    private var defaultConfig: NetworkConfig? = null
    
    /**
     * Token 提供器（可选，用于自动添加 Token 到请求头）
     */
    var tokenProvider: (() -> String?)? = null
    
    /**
     * 初始化网络管理器（可选）
     * 
     * @param config 网络配置，如果为 null 则使用默认配置
     */
    fun init(config: NetworkConfig? = null) {
        defaultConfig = config ?: NetworkConfig.default()
        ILog.d(TAG, "NetworkManager 初始化完成")
    }
    
    /**
     * 获取 Retrofit 实例（单例）
     * 
     * @param config 网络配置，如果为 null 则使用默认配置或已缓存的实例
     * @return Retrofit 实例
     */
    fun getRetrofit(config: NetworkConfig? = null): Retrofit {
        val finalConfig = config ?: defaultConfig ?: NetworkConfig.default()
        
        return retrofitRef.get() ?: synchronized(this) {
            retrofitRef.get() ?: buildRetrofit(finalConfig).also {
                retrofitRef.set(it)
            }
        }
    }
    
    /**
     * 获取 OkHttpClient 实例（单例）
     * 
     * @param config 网络配置，如果为 null 则使用默认配置或已缓存的实例
     * @return OkHttpClient 实例
     */
    fun getOkHttpClient(config: NetworkConfig? = null): OkHttpClient {
        val finalConfig = config ?: defaultConfig ?: NetworkConfig.default()
        
        return okHttpClientRef.get() ?: synchronized(this) {
            okHttpClientRef.get() ?: buildOkHttpClient(finalConfig).also {
                okHttpClientRef.set(it)
            }
        }
    }
    
    /**
     * 构建 Retrofit 实例（建造者模式）
     */
    private fun buildRetrofit(config: NetworkConfig): Retrofit {
        return Retrofit.Builder()
            .baseUrl(config.baseUrl)
            .client(getOkHttpClient(config))
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }
    
    /**
     * 构建 OkHttpClient 实例（建造者模式）
     */
    private fun buildOkHttpClient(config: NetworkConfig): OkHttpClient {
        val builder = OkHttpClient.Builder()
            .connectTimeout(config.connectTimeoutSeconds, TimeUnit.SECONDS)
            .readTimeout(config.readTimeoutSeconds, TimeUnit.SECONDS)
            .writeTimeout(config.writeTimeoutSeconds, TimeUnit.SECONDS)
        
        // 添加日志拦截器
        if (config.enableLogging) {
            val loggingInterceptor = HttpLoggingInterceptor { message ->
                ILog.d("OkHttp", message)
            }
            loggingInterceptor.level = if (config.isDebug) {
                HttpLoggingInterceptor.Level.BODY
            } else {
                HttpLoggingInterceptor.Level.BASIC
            }
            builder.addInterceptor(loggingInterceptor)
        }
        
        // 添加 Token 拦截器
        tokenProvider?.let { provider ->
            builder.addInterceptor { chain ->
                val originalRequest = chain.request()
                val token = provider()
                
                val requestBuilder = originalRequest.newBuilder()
                    .header("Content-Type", "application/json")
                    .header("Accept", "application/json")
                
                if (!token.isNullOrEmpty()) {
                    requestBuilder.header("Authorization", "Bearer $token")
                }
                
                chain.proceed(requestBuilder.build())
            }
        }
        
        return builder.build()
    }
    
    /**
     * 重置网络管理器（用于切换服务器地址时）
     */
    fun reset() {
        synchronized(this) {
            retrofitRef.set(null)
            okHttpClientRef.set(null)
            defaultConfig = null
        }
        ILog.d(TAG, "NetworkManager 已重置")
    }
}

/**
 * 网络配置（建造者模式）
 * 
 * 用于灵活配置 Retrofit 和 OkHttpClient
 */
data class NetworkConfig(
    val baseUrl: String,
    val connectTimeoutSeconds: Long,
    val readTimeoutSeconds: Long,
    val writeTimeoutSeconds: Long,
    val enableLogging: Boolean,
    val isDebug: Boolean
) {
    class Builder {
        private var baseUrl: String = "http://localhost/"
        private var connectTimeoutSeconds: Long = 30
        private var readTimeoutSeconds: Long = 30
        private var writeTimeoutSeconds: Long = 30
        private var enableLogging: Boolean = true
        private var isDebug: Boolean = false
        
        fun baseUrl(url: String) = apply { this.baseUrl = url }
        fun connectTimeout(seconds: Long, unit: TimeUnit) = apply {
            this.connectTimeoutSeconds = unit.toSeconds(seconds)
        }
        fun readTimeout(seconds: Long, unit: TimeUnit) = apply {
            this.readTimeoutSeconds = unit.toSeconds(seconds)
        }
        fun writeTimeout(seconds: Long, unit: TimeUnit) = apply {
            this.writeTimeoutSeconds = unit.toSeconds(seconds)
        }
        fun enableLogging(enable: Boolean) = apply { this.enableLogging = enable }
        fun isDebug(debug: Boolean) = apply { this.isDebug = debug }
        
        fun build(): NetworkConfig {
            return NetworkConfig(
                baseUrl = baseUrl,
                connectTimeoutSeconds = connectTimeoutSeconds,
                readTimeoutSeconds = readTimeoutSeconds,
                writeTimeoutSeconds = writeTimeoutSeconds,
                enableLogging = enableLogging,
                isDebug = isDebug
            )
        }
    }
    
    companion object {
        /**
         * 创建默认配置
         */
        fun default(): NetworkConfig {
            return Builder().build()
        }
    }
}

