package com.gem.media.ad;


import static com.gem.media.ad.CpAdData.CP_ADMOB;

import android.app.KeyguardManager;
import android.content.Context;
import android.os.PowerManager;
import android.text.TextUtils;

import com.ads.cal.notes.manager.GoogleMobileAdsConsentManager;
import com.gem.media.StatsStaticHelper;
import com.gem.media.splash.base.protocol.AdCallback;
import com.gem.media.splash.base.protocol.Constants;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdLoader;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.LoadAdError;
import com.google.android.gms.ads.VideoOptions;
import com.google.android.gms.ads.nativead.NativeAd;
import com.google.android.gms.ads.nativead.NativeAdOptions;
import com.or.ange.dot.utils.LLog;

import java.util.Date;
import java.util.Locale;

public class AdmobNativeManager {
    private static final String TAG = "AdmobNativeManagerManager";
    private static final String AD_TYPE = "admob_native";
    public static final String P_1 = "1";
    public static final String P_2 = "2";
    public static final String P_3 = "3";



    private AdCallback adCallback;
    private static NativeAdStatusCallBack nativeAdStatusCallBack;
    private volatile boolean adIsLoading;
    public NativeAd mNativeAd;
    private long requestTime;
    private static String mAdUnitId;
    public int loadIndex = 0;
    private String adPosition;

    public void setAdCallback(AdCallback adCallback) {
        this.adCallback = adCallback;
    }
    public static void setNativeAdStatusCallBack(NativeAdStatusCallBack nativeAdStatusCallBack) {
        if (null == AdmobNativeManager.nativeAdStatusCallBack) {
            AdmobNativeManager.nativeAdStatusCallBack = nativeAdStatusCallBack;
        }
    }

    private void loadNativeAd(Context context, String adUnitId) {
        AdLoader.Builder builder = new AdLoader.Builder(context, adUnitId);
        requestTime = System.currentTimeMillis();
        adIsLoading = true;

        builder.forNativeAd(new NativeAd.OnNativeAdLoadedListener() {
            // OnLoadedListener implementation.
            @Override
            public void onNativeAdLoaded(NativeAd nativeAd) {
                adIsLoading = false;
                // If this callback occurs after the activity is destroyed, you must call
                // destroy and return or you may get a memory leak.
//                        boolean isDestroyed = false;
//                        isDestroyed = isDestroyed();
//                        if (isDestroyed || isFinishing() || isChangingConfigurations()) {
//                            nativeAd.destroy();
//                            return;
//                        }
                // You must call destroy on old ads when you are done with them,
                // otherwise you will have a memory leak.
                LLog.d(TAG, "onNativeAdLoaded.");
                if (mNativeAd != null) {
                    mNativeAd.destroy();
                }
                mNativeAd = nativeAd;

                adIsLoading = false;
                loadAdTime = (new Date()).getTime();
                requestTime = System.currentTimeMillis() - requestTime;
                if (null != adCallback) {
                    adCallback.onAdLoaded(Constants.NODE_REQUEST_SUCCESS_EID, AD_TYPE, "loaded", requestTime);
                }
                if (null != nativeAdStatusCallBack) {
                    nativeAdStatusCallBack.onAdLoaded(Constants.NODE_REQUEST_SUCCESS, AD_TYPE, "loaded", requestTime, mAdUnitId, Constants.SCENARIO_NATIVE_CLEAR, adPosition);
                }
                requestTime =  System.currentTimeMillis();
                loadIndex = 0;
            }
        });
        VideoOptions videoOptions = new VideoOptions.Builder().setStartMuted(true).build();
        NativeAdOptions adOptions = new NativeAdOptions.Builder().setVideoOptions(videoOptions).build();
        builder.withNativeAdOptions(adOptions);
        AdLoader adLoader = builder.withAdListener(new AdListener() {
            @Override
            public void onAdFailedToLoad(LoadAdError loadAdError) {
                adIsLoading = false;
                String error = String.format(
                        Locale.getDefault(),
                        "domain: %s, code: %d, message: %s",
                        loadAdError.getDomain(),
                        loadAdError.getCode(),
                        loadAdError.getMessage());
                LLog.d(TAG, "error.   "+error);
                requestTime = System.currentTimeMillis() - requestTime;
                if (null != adCallback) {
                    adCallback.onAdError(Constants.NODE_ERROR_EID, AD_TYPE, error, requestTime);
                }
                if (null != nativeAdStatusCallBack) {
                    nativeAdStatusCallBack.onNoAdError(Constants.NODE_ERROR, AD_TYPE, error, requestTime, mAdUnitId, Constants.SCENARIO_NATIVE_CLEAR);
                }
                loadAd(context, loadIndex);
            }

            @Override
            public void onAdImpression() {
                super.onAdImpression();
                LLog.d(TAG, "onAdImpression.");
                if (null != adCallback) {
                    adCallback.onAdShow(Constants.NODE_SHOW_EID, AD_TYPE, "", -1);
                    adCallback = null;
                }
                if (null != nativeAdStatusCallBack) {
                    nativeAdStatusCallBack.onAdShow(Constants.NODE_SHOW, AD_TYPE, "", -1, mAdUnitId, Constants.SCENARIO_NATIVE_CLEAR);
                }
            }

            @Override
            public void onAdClicked() {
                super.onAdClicked();
                LLog.d(TAG, "onAdClicked.");
                if (null != adCallback) {
                    adCallback.onAdClick(Constants.NODE_CLICK_EID, AD_TYPE, "click", -1);
                }
                if (null != nativeAdStatusCallBack) {
                    nativeAdStatusCallBack.onAdClick(Constants.NODE_CLICK, AD_TYPE, "click", -1, mAdUnitId, Constants.SCENARIO_NATIVE_CLEAR);
                }
            }

            @Override
            public void onAdOpened() {
                super.onAdOpened();
                if (null != adCallback) {
                    adCallback.onAdClick(Constants.NODE_OPEN_EID, AD_TYPE, "open", -1);
                }
                if (null != nativeAdStatusCallBack) {
                    nativeAdStatusCallBack.onAdClick(Constants.NODE_OPEN, AD_TYPE, "open", -1, mAdUnitId, Constants.SCENARIO_NATIVE_CLEAR);
                }
            }

            @Override
            public void onAdLoaded() {
                super.onAdLoaded();
                if (null != nativeAdStatusCallBack) {
                    nativeAdStatusCallBack.onAdLoaded(Constants.NODE_OPEN, AD_TYPE, "open", -1, mAdUnitId, Constants.SCENARIO_NATIVE_CLEAR, adPosition);
                }
                LLog.d(TAG, "onAdLoaded.   0000000");
            }

            @Override
            public void onAdClosed() {
                super.onAdClosed();
                LLog.d(TAG, "onAdClosed.");
                if (null != adCallback) {
                    adCallback.onAdClose(Constants.NODE_CLOSE_EID, AD_TYPE, "", -1);
                    adCallback = null;
                }
                if (null != nativeAdStatusCallBack) {
                    nativeAdStatusCallBack.onAdDismiss(Constants.NODE_CLOSE, AD_TYPE, "", -1, mAdUnitId, Constants.SCENARIO_NATIVE_CLEAR);
                }
            }

            @Override
            public void onAdSwipeGestureClicked() {
                super.onAdSwipeGestureClicked();
            }
        }).build();

        adLoader.loadAd(new AdRequest.Builder().build());
    }

    public boolean isAdAvailable() {
        return mNativeAd != null && wasLoadTimeLessThanNHoursAgo();
    }

    public void release() {
        if (null != mNativeAd) {
            mNativeAd.destroy();
        }
        mNativeAd = null;
    }

    private long loadAdTime;

    private boolean wasLoadTimeLessThanNHoursAgo() {
        //广告会在一小时后过期
        long dateDifference = (new Date()).getTime() - loadAdTime;
        long numMilliSecondsPerHour = 3600000;
        boolean expired = dateDifference < numMilliSecondsPerHour;
        if (!expired) {
            StatsStaticHelper.onEvent("to_n", String.valueOf(false));
        }
        return expired;
    }

    public void loadAd(Context context, int loadIndex) {
        if (null != nativeAdStatusCallBack) {
            nativeAdStatusCallBack.nextMediaAppAdReq(Constants.NODE_NEXT_MEDIA_AD_REQ, AD_TYPE, "loadAd admob native start", -2, "", Constants.SCENARIO_NATIVE_CLEAR);
        }
        LLog.d(TAG, "loadAd admob native start.");
        if (adIsLoading) {
            LLog.d(TAG, "loadAd admob isLoading. "+AdmobNativeManager.mAdUnitId);
            if (null != nativeAdStatusCallBack) {
                nativeAdStatusCallBack.nextMediaAppAdReq(Constants.NODE_NEXT_MEDIA_AD_REQ, AD_TYPE, "adIsLoading", -2, AdmobNativeManager.mAdUnitId, Constants.SCENARIO_NATIVE_CLEAR);
            }
            return;
        }
        try {
            AdData adData = CpAdData.getInstance().getAdData(CP_ADMOB);
            if (adData == null) {
                LLog.w(TAG, " adData = null");
                if (null != nativeAdStatusCallBack) {
                    nativeAdStatusCallBack.nextMediaAppAdReq(Constants.NODE_NEXT_MEDIA_AD_REQ, AD_TYPE, "adData = null", -1, "", Constants.SCENARIO_NATIVE_CLEAR);
                }
                return;
            }
            AdmobNativeManager.mAdUnitId = adData.getAdAdId(AdData.AD_TYPE_NATIVE, loadIndex);
            if (TextUtils.isEmpty(AdmobNativeManager.mAdUnitId)) {
                LLog.d(TAG, "loadAd admob native AdUnitId is empty  loadIndex = "+loadIndex);
                if (null != nativeAdStatusCallBack) {
                    nativeAdStatusCallBack.nextMediaAppAdReq(Constants.NODE_NEXT_MEDIA_AD_REQ, AD_TYPE, "AdUnitId is empty loadIndex = " + loadIndex, -1, "", Constants.SCENARIO_NATIVE_CLEAR);
                }
                this.loadIndex = 0;
                return;
            }
            if (isScreenLock(context)) {
                LLog.d(TAG, "loadAd admob native 1.");
                if (null != nativeAdStatusCallBack) {
                    nativeAdStatusCallBack.nextMediaAppAdReq(Constants.NODE_NEXT_MEDIA_AD_REQ, AD_TYPE, "isScreenLock", -2, AdmobNativeManager.mAdUnitId, Constants.SCENARIO_NATIVE_CLEAR);
                }
                return;
            }
            if (!isScreenOn(context)) {
                LLog.d(TAG, "loadAd admob native 2.");
                if (null != nativeAdStatusCallBack) {
                    nativeAdStatusCallBack.nextMediaAppAdReq(Constants.NODE_NEXT_MEDIA_AD_REQ, AD_TYPE, "isScreenOff", -2, AdmobNativeManager.mAdUnitId, Constants.SCENARIO_NATIVE_CLEAR);
                }
                return;
            }
            if (!GoogleMobileAdsConsentManager.getInstance(context).canRequestAds()) {
                LLog.d(TAG, "loadAd admob native canRequestAds false.");
                if (null != nativeAdStatusCallBack) {
                    nativeAdStatusCallBack.nextMediaAppAdReq(Constants.NODE_NEXT_MEDIA_AD_REQ, AD_TYPE, "canRequestAds false" , -1, AdmobNativeManager.mAdUnitId, Constants.SCENARIO_NATIVE_CLEAR);
                }
                return;
            }
            if (isAdAvailable()) {
                LLog.d(TAG, "loadAd admob native 3.");
                if (null != nativeAdStatusCallBack) {
                    nativeAdStatusCallBack.nextMediaAppAdReq(Constants.NODE_NEXT_MEDIA_AD_REQ, AD_TYPE, "has cache", -2, AdmobNativeManager.mAdUnitId, Constants.SCENARIO_NATIVE_CLEAR);
                }
                return;
            }
            this.loadIndex = loadIndex + 1;
            loadNativeAd(context, mAdUnitId);
        } catch (Exception e) {
            LLog.d(TAG, "loadAd native. e ----" + e.getMessage());
        }
    }

    private boolean isScreenLock(Context context) {
        try {
            KeyguardManager km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
            if (km == null) return false;
            return km.inKeyguardRestrictedInputMode();
        } catch (Exception e) {
            return false;
        }
    }

    public static boolean isScreenOn(Context context) {
        PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        return powerManager.isInteractive();
    }

    public void setAdPosition(String adPosition) {
        this.adPosition = adPosition;
    }

    public String getAdPosition() {
        return adPosition;
    }
}
