package com.uiuipad.appstore.network;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Environment;
import android.util.Log;

import com.tencent.mmkv.MMKV;
import com.uiuipad.appstore.bean.AdminAppInfo;
import com.uiuipad.appstore.bean.AppClassBean;
import com.uiuipad.appstore.bean.AppInfo;
import com.uiuipad.appstore.base.BaseResponse;
import com.uiuipad.appstore.common.CommonConfig;
import com.uiuipad.appstore.disklrucache.CacheHelper;
import com.uiuipad.appstore.network.api.AdminAppApi;
import com.uiuipad.appstore.network.api.AdminAppClassApi;
import com.uiuipad.appstore.network.api.AdminAppDetailsApi;
import com.uiuipad.appstore.network.api.AdminClassAppApi;
import com.uiuipad.appstore.network.api.ApplyForInstallApi;
import com.uiuipad.appstore.network.interceptor.RepeatRequestInterceptor;
import com.uiuipad.appstore.utils.ToastUtil;
import com.uiuipad.appstore.utils.Utils;

import java.io.File;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.schedulers.Schedulers;
import okhttp3.Cache;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class NetInterfaceManager {
    @SuppressLint("StaticFieldLeak")
    private static NetInterfaceManager sInstance;
    private Context mContext;
    private Retrofit mRetrofit;
    private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
    private OkHttpClient okHttpClient;
    private CacheHelper cacheHelper;

    //超时时间
    private static final int timeOut = 5;
    // 缓存文件最大限制大小20M
    private static final long cacheSize = 1024 * 1024 * 64;

    private NetInterfaceManager(Context context) {
        if (context == null) {
            throw new RuntimeException("Context is NULL");
        }
        this.mContext = context;
        this.cacheHelper = new CacheHelper(mContext);

        if (null == mRetrofit) {
            if (okHttpClient == null) {
                //如果无法生存缓存文件目录，检测权限使用已经加上，检测手机是否把文件读写权限禁止了
                OkHttpClient.Builder builder = new OkHttpClient.Builder();
                builder.connectTimeout(timeOut, TimeUnit.SECONDS); // 设置连接超时时间
                builder.writeTimeout(timeOut, TimeUnit.SECONDS);// 设置写入超时时间
                builder.readTimeout(timeOut, TimeUnit.SECONDS);// 设置读取数据超时时间
                builder.retryOnConnectionFailure(true);// 设置进行连接失败重试
                builder.addInterceptor(new RepeatRequestInterceptor());

                // 设置缓存文件路径
                String cacheDirectory = getCacheDir() + "/OkHttpCache";
                Cache cache = new Cache(new File(cacheDirectory), cacheSize);
                builder.cache(cache);// 设置缓存
                okHttpClient = builder.build();
            }

            mRetrofit = new Retrofit.Builder()
                    .client(okHttpClient)
                    .baseUrl(UrlAddress.ROOT_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                    .build();
        }
    }

    public static void init(Context context) {
        if (sInstance == null) {
            sInstance = new NetInterfaceManager(context);
        }
    }

    private String getCacheDir() {
        String cachePath;
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
                || !Environment.isExternalStorageRemovable()) {
            if (mContext.getExternalCacheDir() != null) {
                cachePath = mContext.getExternalCacheDir().getPath();
            } else if (mContext.getExternalFilesDir("cache") != null) {
                cachePath = mContext.getExternalFilesDir("cache").getPath();
            } else {
                cachePath = mContext.getCacheDir().getPath();
            }
        } else {
            cachePath = mContext.getCacheDir().getPath();
        }
        return cachePath;
    }

    public static NetInterfaceManager getInstance() {
        if (sInstance == null) {
            throw new IllegalStateException("You must be init NetworkManager first");
        }
        return sInstance;
    }


    public Observable<BaseResponse<List<AdminAppInfo>>> getAdminAppObservable() {
        return mRetrofit.create(AdminAppApi.class)
                .getAdminApp(Utils.getSerial())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<BaseResponse<List<AdminAppInfo>>> getAdminClassAppObservable(int id) {
        return mRetrofit.create(AdminClassAppApi.class)
                .getAdminApp(Utils.getSerial(), id)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }


    public Observable<BaseResponse<List<AppClassBean>>> getAdminAppClassObservable() {
        return mRetrofit.create(AdminAppClassApi.class)
                .getAdminAppClassApi(Utils.getSerial())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<BaseResponse> getApplyForInstallObservable(String pkg, String name) {
        return mRetrofit.create(ApplyForInstallApi.class)
                .applyForInstall(pkg, name, Utils.getSerial())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<BaseResponse<AdminAppInfo>> getAdminAppDetailsObservable(long id) {
        return mRetrofit.create(AdminAppDetailsApi.class)
                .getAdminAppDetails(id)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }


    public interface onCompleteCallback {
        void onComplete();
    }

    public void getApplyForInstall(String pkg, String name, onCompleteCallback callback) {
        getApplyForInstallObservable(pkg, name)
                .subscribe(new Observer<BaseResponse>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e("getApplyForInstall", "onSubscribe: ");
                    }

                    @Override
                    public void onNext(@NonNull BaseResponse baseResponse) {
                        Log.e("getApplyForInstall", "onNext: " + baseResponse);
                        ToastUtil.show(baseResponse.msg);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e("getApplyForInstall", "onError: " + e.getMessage());
                        ToastUtil.show("网络连接失败");
                        onComplete();
                    }

                    @Override
                    public void onComplete() {
                        Log.e("getApplyForInstall", "onComplete: ");
                        if (callback != null) {
                            callback.onComplete();
                        }
                    }
                });
    }

}