package com.gh.common.constant;

import android.annotation.SuppressLint;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Build;
import android.preference.PreferenceManager;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.gh.common.util.PackageHelper;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.constant.CommonConsts;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
import com.gh.gamecenter.common.retrofit.BiResponse;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.common.utils.DarkModeUtils;
import com.gh.gamecenter.common.utils.EnvHelper;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.core.utils.UrlFilterUtils;
import com.gh.gamecenter.entity.AppEntity;
import com.gh.gamecenter.entity.FloatWindowSettingEntity;
import com.gh.gamecenter.entity.GameGuidePopupEntity;
import com.gh.gamecenter.entity.NewApiSettingsEntity;
import com.gh.gamecenter.entity.NewSettingsEntity;
import com.gh.gamecenter.entity.VNewSetting;
import com.gh.gamecenter.entity.VSetting;
import com.gh.gamecenter.feature.entity.SettingsEntity;
import com.gh.gamecenter.feature.entity.SimulatorEntity;
import com.gh.gamecenter.feature.utils.ContentBlockedHelper;
import com.gh.gamecenter.receiver.PackageChangeBroadcastReceiver;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.gamecenter.retrofit.service.VApiService;
import com.gh.vspace.VHelper;
import com.halo.assistant.HaloApp;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.Locale;

import io.reactivex.Observable;
import io.reactivex.Single;
import io.reactivex.SingleSource;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.BehaviorSubject;
import okhttp3.ResponseBody;

public class Config {

    // 这个 API_HOST 在测试包里会随着选择的环境切换，正式包里会一直保持正式 host
    public static final String API_HOST = EnvHelper.getHost();
    public static final String NEW_API_HOST = EnvHelper.getNewHost();
    public static final String VAPI_HOST = EnvHelper.getVHost();

    public static final String WGAME_CPM_BUSIAPPID = BuildConfig.WGAME_CPM_BUSIAPPID;
    public static final String WGAME_CPM_API_HOST = EnvHelper.getWGameCPMHost();

    public static final String DSP_API_HOST = EnvHelper.getDspHost();

    // Third-Party confs
    public static final String WECHAT_APPID = BuildConfig.WECHAT_APPID;
    public static final String WECHAT_SECRET = BuildConfig.WECHAT_SECRET;
    public static final String TENCENT_APPID = BuildConfig.TENCENT_APPID;
    public static final String WEIBO_APPKEY = BuildConfig.WEIBO_APPKEY;
    public static final String QUICK_LOGIN_APPID = BuildConfig.QUICK_LOGIN_APPID;
    public static final String QUICK_LOGIN_APPKEY = BuildConfig.QUICK_LOGIN_APPKEY;
    public static final String URL_ARTICLE = "www.ghzs666.com/article/"; // ghzs/ghzs666 统一

    private static final String SETTINGS_KEY = "settingsKey";

    private static SettingsEntity mSettingsEntity;
    private static NewSettingsEntity mNewSettingsEntity;
    private static NewApiSettingsEntity mNewApiSettingsEntity;

    private static NewApiSettingsEntity.NightMode mNightModeSetting;
    private static SimulatorEntity mNewSimulatorEntity;
    private static VSetting mVSetting;
    private volatile static VNewSetting mVNewSetting;

    private static FloatWindowSettingEntity mFloatWindowSetting;

    private static AppEntity mNew32UpdateEntity;
    private static BehaviorSubject<VNewSetting> vNewSettingSubject = BehaviorSubject.create();
    private static GameGuidePopupEntity mGameGuidePopupEntity;
    private static SharedPreferences mDefaultSharedPreferences;

    public static final int VIDEO_PAGE_SIZE = 21; // 视频列表大多都是一行3个

    public static boolean isShow() {
        return !SPUtils.getBoolean(Constants.SP_TEENAGER_MODE);
    }

    public static void setSettings(SettingsEntity settingsEntity) {
        getPreferences().edit().putString(SETTINGS_KEY, GsonUtils.toJson(settingsEntity)).apply();
        mSettingsEntity = settingsEntity;

        PackageHelper.refreshPackageNameList();
    }

    @Nullable
    public static SettingsEntity getSettings() {
        if (mSettingsEntity == null) {
            try {
                String json = getPreferences().getString(SETTINGS_KEY, null);
                if (!TextUtils.isEmpty(json)) {
                    mSettingsEntity = GsonUtils.fromJson(json, SettingsEntity.class);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return mSettingsEntity;
    }

    //新模拟器
    @Nullable
    public static SimulatorEntity getNewSimulatorEntitySetting() {
        if (mNewSimulatorEntity != null) {
            return mNewSimulatorEntity;
        } else if (mNewApiSettingsEntity != null && mNewApiSettingsEntity.getSimulator() != null) {
            return mNewApiSettingsEntity.getSimulator();
        } else {
            return null;
        }
    }

    @Nullable
    public static NewApiSettingsEntity.NightMode getNightModeSetting() {
        if (mNightModeSetting != null) {
            return mNightModeSetting;
        } else if (mNewApiSettingsEntity != null && mNewApiSettingsEntity.getNightMode() != null) {
            return mNewApiSettingsEntity.getNightMode();
        } else {
            return null;
        }
    }

    public static boolean getUserInterestedGame() {
        if (mNewApiSettingsEntity != null) {
            return mNewApiSettingsEntity.getUserInterestedGame();
        } else {
            return false;
        }
    }

    @Nullable
    public static NewSettingsEntity getNewSettingsEntity() {
        if (mNewSettingsEntity == null) {
            try {
                String json = SPUtils.getString(Constants.SP_NEW_SETTINGS);
                if (!TextUtils.isEmpty(json)) {
                    mNewSettingsEntity = GsonUtils.fromJson(json, NewSettingsEntity.class);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return mNewSettingsEntity;
    }

    @Nullable
    public static NewApiSettingsEntity getNewApiSettingsEntity() {
        if (mNewApiSettingsEntity == null) {
            try {
                String json = SPUtils.getString(Constants.SP_NEW_API_SETTINGS);
                if (!TextUtils.isEmpty(json)) {
                    mNewApiSettingsEntity = GsonUtils.fromJson(json, NewApiSettingsEntity.class);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return mNewApiSettingsEntity;
    }

    public static void updateNewApiSettings(NewApiSettingsEntity settingsEntity) {
        mNewApiSettingsEntity = settingsEntity;
        SPUtils.setString(Constants.SP_NEW_API_SETTINGS, GsonUtils.toJson(settingsEntity));
    }

    @Nullable
    public static VSetting getVSettingEntity() {
        if (mVSetting == null) {
            try {
                String json = SPUtils.getString(Constants.SP_V_SETTINGS);
                if (!TextUtils.isEmpty(json)) {
                    mVSetting = GsonUtils.fromJson(json, VSetting.class);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return mVSetting;
    }

    @Nullable
    public static VNewSetting getVNewSettingEntity() {
        if (mVNewSetting == null) {
            try {
                String json = SPUtils.getString(Constants.SP_V_NEW_SETTINGS);
                if (!TextUtils.isEmpty(json)) {
                    mVNewSetting = GsonUtils.fromJson(json, VNewSetting.class);
                    vNewSettingSubject.onNext(mVNewSetting);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return mVNewSetting;
    }
    @Nullable
    public static FloatWindowSettingEntity getFloatWindowSettingEntity() {
        if (mFloatWindowSetting == null) {
            try {
                String json = SPUtils.getString(Constants.SP_FLOAT_WINDOW_SETTINGS);
                if (!TextUtils.isEmpty(json)) {
                    mFloatWindowSetting = GsonUtils.fromJson(json, FloatWindowSettingEntity.class);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return mFloatWindowSetting;
    }


    @NonNull
    public static Observable<VNewSetting> getVNewSettingObservable() {
        if (mVNewSetting != null) {
            return Observable.just(mVNewSetting);
        } else {
            return vNewSettingSubject.hide();
        }
    }


    @Nullable
    public static AppEntity getNew32UpdateEntity() {
        return mNew32UpdateEntity;
    }

    /**
     * 请求网络数据，尝试刷新畅玩相关配置
     */
    @SuppressLint("CheckResult")
    public static void refreshVSettingEntity() {
        RetrofitManager.getInstance()
                .getVApi().getSettings(BuildConfig.VERSION_NAME, Build.VERSION.SDK_INT)
                .subscribeOn(Schedulers.io())
                .subscribe(new BiResponse<VSetting>() {
                    @Override
                    public void onSuccess(VSetting data) {
                        mVSetting = data;
                        SPUtils.setString(Constants.SP_V_SETTINGS, GsonUtils.toJson(data));
                        VHelper.checkVspaceUpdate(HaloApp.getInstance());
                    }
                });
    }

    @SuppressLint("CheckResult")
    public static void getNewSetting() {
        VApiService vApi = RetrofitManager.getInstance().getVApi();
        vApi.getNewSettings(BuildConfig.VERSION_NAME, Build.VERSION.SDK_INT).flatMap(new Function<VNewSetting, SingleSource<AppEntity>>() {
                    @Override
                    public SingleSource<AppEntity> apply(VNewSetting data) throws Exception {
                        mVNewSetting = data;
                        vNewSettingSubject.onNext(mVNewSetting);
                        SPUtils.setString(Constants.SP_V_NEW_SETTINGS, GsonUtils.toJson(data));
                        if (data.getVa() != null && data.getVa().getArch32() != null) {
                            String versionNameByPackageName = PackageUtils.getVersionNameByPackageName(data.getVa().getArch32().getPackageName());
                            return vApi.getNewPackageUpdate(
                                    BuildConfig.VERSION_NAME,
                                    versionNameByPackageName != null ? versionNameByPackageName : "",
                                    HaloApp.getInstance().getChannel()
                            );
                        }
                        return Single.error(new IllegalStateException("VNewSetting entity is not expected"));
                    }
                })
                .subscribeOn(Schedulers.io())
                .subscribe(new BiResponse<AppEntity>() {
                    @Override
                    public void onSuccess(AppEntity data) {
                        mNew32UpdateEntity = data;
                    }
                });
    }

    @Nullable
    public static GameGuidePopupEntity getGameGuidePopupEntity() {
        return mGameGuidePopupEntity;
    }

    public static SharedPreferences getPreferences() {
        if (mDefaultSharedPreferences == null) {
            mDefaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication());
        }

        return mDefaultSharedPreferences;
    }

    @SuppressLint("CheckResult")
    public static void getGhzsSettings() {
        String channel = HaloApp.getInstance().getChannel();

        // 把请求提前，避免请求过多阻塞，首页显示广告时老是用到上一次的缓存
        getNewSettings(channel);

        RetrofitManager.getInstance()
                .getApi().getSettings(PackageUtils.getGhVersionName(), channel)
                .subscribeOn(Schedulers.io())
                .subscribe(new Response<SettingsEntity>() {
                    @Override
                    public void onResponse(SettingsEntity response) {
                        Config.setSettings(response);

                        // 意见反馈
                        SharedPreferences.Editor edit = getPreferences().edit();
                        edit.putString(CommonConsts.SUGGESTION_HINT_TYPE,
                                GsonUtils.toJson(response.getSuggestion()));
                        edit.apply();

                        if (!SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
                            AppExecutor.getUiExecutor().execute(() -> EventBus.getDefault().post(new EBReuse("Refresh")));
                        }
                    }
                });

        RetrofitManager.getInstance()
                .getApi().getNewSettings(Build.MANUFACTURER, Build.MODEL, channel, Build.VERSION.SDK_INT, BuildConfig.VERSION_NAME)
                .subscribeOn(Schedulers.io())
                .subscribe(new BiResponse<NewSettingsEntity>() {
                    @Override
                    public void onSuccess(NewSettingsEntity data) {
                        mNewSettingsEntity = data;
                        SPUtils.setString(Constants.SP_NEW_SETTINGS, GsonUtils.toJson(data));
                    }
                });

        refreshVSettingEntity();
        getNewSetting();
        getFloatWindowSetting();

        RetrofitManager.getInstance()
                .getApi().getGameGuidePopup(Build.MANUFACTURER, Build.VERSION.RELEASE, Build.MODEL, channel, BuildConfig.VERSION_NAME)
                .subscribeOn(Schedulers.io())
                .subscribe(new BiResponse<GameGuidePopupEntity>() {
                    @Override
                    public void onSuccess(GameGuidePopupEntity data) {
                        mGameGuidePopupEntity = data;
                    }
                });

        String manufacturer = Build.MANUFACTURER.toUpperCase(Locale.CHINA);
        if (manufacturer.equals("OPPO") || manufacturer.equals("VIVO")) {
            RetrofitManager.getInstance().getNewApi().getBrowserHintUrl(manufacturer)
                    .subscribeOn(Schedulers.io())
                    .subscribe(new BiResponse<ResponseBody>() {
                        @Override
                        public void onSuccess(ResponseBody data) {
                            try {
                                JSONObject jsonObject = new JSONObject(data.string());
                                if (!TextUtils.isEmpty(jsonObject.getJSONObject("data").getString("link"))) {
                                    SPUtils.setString(Constants.SP_BROWSER_HINT_URL, jsonObject.getJSONObject("data").getString("link"));
                                }
                            } catch (JSONException | IOException e) {
                                e.printStackTrace();
                            }
                        }
                    });
        }
    }

    @SuppressLint("CheckResult")
    private static void getNewSettings(String channel) {
        if (mNewApiSettingsEntity == null) {

            String filterString = UrlFilterUtils.getFilterQuery(
                    "manufacturer", Build.MANUFACTURER,
                    "model", Build.MODEL,
                    "android_sdk_version", String.valueOf(Build.VERSION.SDK_INT),
                    "rom", MetaUtil.INSTANCE.getRom().getRomName() + " " + MetaUtil.INSTANCE.getRom().getRomVersion()
            );

            RetrofitManager.getInstance()
                    .getNewApi().getNewSettings(PackageUtils.getGhVersionName(), channel, filterString)
                    .subscribeOn(Schedulers.io())
                    .subscribe(new BiResponse<NewApiSettingsEntity>() {
                        @Override
                        public void onSuccess(NewApiSettingsEntity data) {
                            mNewApiSettingsEntity = data;
                            mNightModeSetting = data.getNightMode();
                            mNewSimulatorEntity = data.getSimulator();
                            if (HaloApp.getInstance().isNewForThisVersion && mNightModeSetting != null && mNightModeSetting.getInstall()) {
                                DarkModeUtils.INSTANCE.updateFollowSystemDarkModeToSp(true);
                                AppExecutor.getUiExecutor().execute(DarkModeUtils.INSTANCE::initDarkMode);
                            }
                            SPUtils.setString(Constants.SP_NEW_API_SETTINGS, GsonUtils.toJson(data));

                            // 刷新屏蔽字段
                            if (mNewApiSettingsEntity.getGameShieldContents() != null) {
                                ContentBlockedHelper.INSTANCE.init(mNewApiSettingsEntity.getGameShieldContents());
                            }

                            // 更新安装列表是否开启的配置
                            if (mNewApiSettingsEntity.getInstalledComplianceSwitch() != null) {
                                PackageHelper.INSTANCE.updateIsGetInstalledPackagesApiAgreedRequired(mNewApiSettingsEntity.getInstalledComplianceSwitch());
                            } else {
                                PackageHelper.INSTANCE.updateIsGetInstalledPackagesApiAgreedRequired(false);
                            }

                            // 更新包名监听是否开启
                            if (mNewApiSettingsEntity.isPackageObserveEnable()) {
                                AppExecutor.getUiExecutor().execute(() -> observePackageChange(mNewApiSettingsEntity.getPackageObserveActions()));
                            }
                        }
                    });
        }
    }

    @SuppressLint("CheckResult")
    private static void getFloatWindowSetting() {
        RetrofitManager.getInstance().getNewApi()
                .getFloatWindowSettings()
                .subscribeOn(Schedulers.io())
                .subscribe(new BiResponse<FloatWindowSettingEntity>() {
                    @Override
                    public void onSuccess(FloatWindowSettingEntity data) {
                        mFloatWindowSetting = data;
                        SPUtils.setString(Constants.SP_FLOAT_WINDOW_SETTINGS, GsonUtils.toJson(data));
                    }
                });
    }

    public static void observePackageChange(NewApiSettingsEntity.PackageObserveActions packageObserveActions) {
        PackageChangeBroadcastReceiver receiver = new PackageChangeBroadcastReceiver(packageObserveActions);
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(packageObserveActions.getAdd());
        intentFilter.addAction(packageObserveActions.getRem());
        intentFilter.addAction(packageObserveActions.getRep());
        intentFilter.addDataScheme("package");
        HaloApp.getInstance().registerReceiver(receiver, intentFilter);
    }

}
