package com.narutohuo.xindazhou.common.networkrx

import android.content.Context
import com.narutohuo.xindazhou.common.networkrx.cookie.CookieJarImpl
import com.narutohuo.xindazhou.common.networkrx.cookie.CookieStore
import com.narutohuo.xindazhou.common.networkrx.cookie.MemoryCookieStore
import com.narutohuo.xindazhou.common.networkrx.cookie.SPCookieStore
import com.narutohuo.xindazhou.common.networkrx.interceptor.HeaderInterceptor
import com.narutohuo.xindazhou.common.networkrx.interceptor.TokenRefreshInterceptor
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit

/**
 * 网络管理器（基于RxJava）
 * 
 * 参考MVVMHabit框架设计，提供网络请求的核心配置
 * 
 * 功能：
 * - OkHttpClient配置
 * - Retrofit实例创建
 * - 超时设置
 * - 拦截器管理
 * - Cookie管理
 * - 网络状态检测
 * 
 * 使用方式：
 * ```kotlin
 * val apiService = NetworkManager.createApi(ApiService::class.java)
 * apiService.login(request)
 *     .subscribeOn(Schedulers.io())
 *     .observeOn(AndroidSchedulers.mainThread())
 *     .subscribe({
 *         // 处理成功
 *     }, {
 *         // 处理错误
 *     })
 * ```
 */
object NetworkManager {
    
    private const val DEFAULT_TIMEOUT = 30L
    private const val BASE_URL = "https://api.example.com/"
    
    private val cookieStore: CookieStore = MemoryCookieStore()
    
    /**
     * 获取Cookie存储
     * 
     * @return CookieStore
     */
    fun getCookieStore(): CookieStore {
        return cookieStore
    }
    
    /**
     * 创建OkHttpClient实例
     * 
     * @param interceptors 拦截器列表
     * @param useCookie 是否使用Cookie管理
     * @return OkHttpClient
     */
    fun createOkHttpClient(
        vararg interceptors: okhttp3.Interceptor,
        useCookie: Boolean = true
    ): OkHttpClient {
        val builder = OkHttpClient.Builder()
            .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
            .readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
            .writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
            .retryOnConnectionFailure(true)
        
        // 添加Cookie管理
        if (useCookie) {
            builder.cookieJar(CookieJarImpl(getCookieStore()))
        }
        
        // 添加拦截器
        interceptors.forEach {
            builder.addInterceptor(it)
        }
        
        return builder.build()
    }
    
    /**
     * 创建Retrofit实例
     * 
     * @param baseUrl 基础URL
     * @param client OkHttpClient
     * @return Retrofit
     */
    fun createRetrofit(baseUrl: String = BASE_URL, client: OkHttpClient): Retrofit {
        return Retrofit.Builder()
            .baseUrl(baseUrl)
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()
    }
    
    /**
     * 创建API服务
     * 
     * @param clazz API接口类
     * @param baseUrl 基础URL
     * @param client OkHttpClient
     * @return API服务实例
     */
    fun <T> createApi(
        clazz: Class<T>,
        baseUrl: String = BASE_URL,
        client: OkHttpClient = createOkHttpClient()
    ): T {
        val retrofit = createRetrofit(baseUrl, client)
        return retrofit.create(clazz)
    }
    
    /**
     * 创建默认的OkHttpClient
     * 
     * @param useCookie 是否使用Cookie管理
     * @return OkHttpClient
     */
    fun getDefaultOkHttpClient(useCookie: Boolean = true): OkHttpClient {
        return createOkHttpClient(
            HeaderInterceptor(),
            TokenRefreshInterceptor(),
            useCookie = useCookie
        )
    }
    
    /**
     * 获取默认的Retrofit实例
     * 
     * @param useCookie 是否使用Cookie管理
     * @return Retrofit
     */
    fun getDefaultRetrofit(useCookie: Boolean = true): Retrofit {
        return createRetrofit(client = getDefaultOkHttpClient(useCookie))
    }
    
    /**
     * 清除Cookie
     */
    fun clearCookie() {
        cookieStore?.clearCookie()
    }
    
    /**
     * 检查网络是否连接
     * 
     * @param context 上下文
     * @return 是否连接网络
     */
    fun isNetworkConnected(context: Context): Boolean {
        return NetworkUtil.isNetworkConnected(context)
    }
    
    /**
     * 获取网络类型
     * 
     * @param context 上下文
     * @return 网络类型
     */
    fun getNetworkType(context: Context): NetworkUtil.NetworkType {
        return NetworkUtil.getNetworkType(context)
    }
}