package com.gh.common.util;

import android.annotation.SuppressLint;
import android.app.Application;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log;

import com.therouter.TheRouter;
import com.gh.ad.AdDelegateHelper;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
import com.gh.gamecenter.common.retrofit.BiResponse;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.core.provider.ISentryProvider;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.feature.utils.SentryHelper;
import com.gh.gamecenter.login.entity.IdCardEntity;
import com.gh.gamecenter.login.entity.UserInfoEntity;
import com.gh.gamecenter.provider.GhContentProvider;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.gid.GidCallback;
import com.gh.gid.GidHelper;
import com.halo.assistant.HaloApp;
import com.lightgame.config.CommonDebug;
import com.lightgame.utils.Utils;

import io.reactivex.schedulers.Schedulers;

/**
 * Created by LGT on 2016/6/15.
 * 数据收集工具类
 */
public class DataUtils {

    // 神策 OAID 是否已绑定
    private static boolean isSensorOAIDBounded = false;
    // 原始的 OAID 是否已成功获取
    private static boolean originalOAIDIsReceived = false;

    private DataUtils() {
        throw new IllegalStateException("Utility class");
    }

    /**
     * 初始化各种统计工具，仅在release build（非debug）模式启用统计
     */
    public static void init(final Application context, String channel) {
        if (CommonDebug.IS_DEBUG) {
            return;
        }

        initSentry(context, channel);
    }

    private static void initSentry(Context context, String channel) {
        ISentryProvider sentryProvider = TheRouter.get(ISentryProvider.class);
        if (sentryProvider != null) {
            sentryProvider.init(context, channel, BuildConfig.FLAVOR, BuildConfig.VERSION_NAME);
        }
    }

    public static void getGid() {
        // 默认用 APP 级已存储的 GID 来使用，不使用外部 GID
        String savedGid = SPUtils.getString(Constants.GID);
        if (!TextUtils.isEmpty(savedGid)) {
            onGidReceived(savedGid);
        } else {
            GidHelper.getInstance().registerDevice(HaloApp.getInstance().getApplication(), new GidCallback() {
                @Override
                public void onSuccess(String gid) {
                    Utils.log("Gid", gid);
                    PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication()).edit().putString(Constants.DEVICE_KEY, gid).apply();

                    SPUtils.setString(Constants.GID, gid);

                    onGidReceived(gid);
                }

                @Override
                public void onFailure(String s) {
                    // 更新广告配置
                    AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
                }
            });
        }
    }

    private static void onGidReceived(String gid) {
        bindValidOaidToSensor(false);

        HaloApp.getInstance().setGid(gid);
        // 更新广告配置
        AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);

        getDeviceCertification(gid);

        // 避免初始化顺序问题导致 MetaUtil 一直持有空的 gid
        MetaUtil.INSTANCE.refreshMeta();

        AppExecutor.getIoExecutor().execute(() -> {
            ContentValues values = new ContentValues();
            values.put(GhContentProvider.KEY_GID, gid);
            values.put(GhContentProvider.KEY_ANDROID_ID, MetaUtil.getBase64EncodedAndroidId());
            try {
                HaloApp.getInstance().getContentResolver().insert(Uri.parse("content://com.gh.gamecenter.provider/device"), values);
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        });
    }

    /**
     * 为神策绑定有效的 OAID
     */
    public static void bindValidOaidToSensor(boolean fromOaidResult) {
        if (isSensorOAIDBounded) return;

        String oaid = HaloApp.getInstance().getOAID();

        // 来自于 oaid 获取回调，或者说原始 oaid 已经获取成功
        if (fromOaidResult || originalOAIDIsReceived) {
            originalOAIDIsReceived = true;
            // 遇到异常的 OAID
            if (Constants.INVALID_OAID_1.equals(oaid)
                    || Constants.INVALID_OAID_2.equals(oaid)
                    || Constants.INVALID_OAID_3.equals(oaid)
                    || TextUtils.isEmpty(oaid)) {
                // 若 gid 不为空，那么整合 gid 作为 oaid https://jira.shanqu.cc/browse/GHZSCY-7004
                if (HaloApp.getInstance().getGid() != null) {
                    oaid = "GID" + HaloApp.getInstance().getGid();
                    SensorsBridge.INSTANCE.setOAID(oaid);
                    isSensorOAIDBounded = true;
                }
            } else {
                SensorsBridge.INSTANCE.setOAID(oaid);
                isSensorOAIDBounded = true;
            }
        }
    }

    /**
     * 获取应用 gid 绑定的实名信息
     */
    // TODO 这个方法启动时会被调用多次，后面考虑优化优化
    @SuppressLint("CheckResult")
    public static void getDeviceCertification(String gid) {
        RetrofitManager.getInstance()
                .getApi()
                .getCertification()
                .subscribeOn(Schedulers.io())
                .subscribe(new BiResponse<UserInfoEntity>() {
                    @Override
                    public void onSuccess(UserInfoEntity data) {
                        SPUtils.setString(Constants.SP_DEVICE_CERTIFICATION_PREFIX + gid, GsonUtils.toJson(data));

                        ContentValues values = new ContentValues();
                        IdCardEntity idCardEntity = data.getIdCard();

                        if (idCardEntity != null) {
                            boolean isCertificated = !TextUtils.isEmpty(data.getIdCard().getId());
                            boolean isAdult = data.getIdCard().getMinor() == null || !data.getIdCard().getMinor();
                            boolean isCertificating = data.getIdCard().getStatus() == 1;

                            values.put(GhContentProvider.KEY_IS_CERTIFICATED, isCertificated); // 是否认证
                            values.put(GhContentProvider.KEY_IS_ADULT, isAdult); // 是否成年
                            values.put(GhContentProvider.KEY_IS_CERTIFICATING, isCertificating); // 是否认证中

                            if (!isCertificated) {
                                RealNameHelper.updateCertificationStatus(0);
                            } else {
                                if (isAdult) {
                                    RealNameHelper.updateCertificationStatus(2);
                                } else {
                                    RealNameHelper.updateCertificationStatus(1);
                                }
                            }
                        } else {
                            values.put(GhContentProvider.KEY_IS_CERTIFICATED, false);
                            values.put(GhContentProvider.KEY_IS_ADULT, false);
                            values.put(GhContentProvider.KEY_IS_CERTIFICATING, false);
                            RealNameHelper.updateCertificationStatus(0);
                        }

                        RealNameHelper.INSTANCE.onRealNameInfoUpdated();

                        try {
                            // Unknown URL content://com.gh.gamecenter.provider/certification
                            // TODO 将 com.gh.gamecenter 改成 BuildConfig.ApplicationID
                            HaloApp.getInstance().getContentResolver().insert(Uri.parse("content://com.gh.gamecenter.provider/certification"), values);
                        } catch (Exception exception) {
                            exception.printStackTrace();
                        }
                    }
                });
    }

    /**
     * 下次应用启动再上报
     *
     * @param context
     * @param throwable
     */
    public static void reportException(Context context, Throwable throwable) {

        CommonDebug.logMethodWithParams(context, "ERRMSG", throwable);

        // 上传错误数据
        try {
            DataCollectionUtils.uploadError(context, Log.getStackTraceString(throwable));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}
