package com.datarecovery.master.sdk.ad;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.PopupWindow;

import com.atmob.common.logging.AtmobLog;
import com.atmob.common.runtime.ActivityUtil;
import com.atmob.common.runtime.ProcessUtil;
import com.atmob.common.ui.SizeUtil;
import com.atmob.mediation.api.AdConstants;
import com.atmob.mediation.api.AdError;
import com.atmob.mediation.api.AtmobAdSdk;
import com.atmob.mediation.api.EcpmInfo;
import com.atmob.mediation.api.ad.AtmobAdLoadCallback;
import com.atmob.mediation.api.ad.interstitial.AtmobInterstitialAd;
import com.atmob.mediation.api.ad.nativead.AtmobNativeAd;
import com.atmob.mediation.api.ad.nativead.AtmobNativeAdListener;
import com.atmob.mediation.api.ad.reward.AtmobRewardAd;
import com.atmob.mediation.api.ad.splash.AtmobSplashAd;
import com.atmob.mediation.api.config.AtmobAdConfig;
import com.atmob.sdk.gravity_engine.GravityEngine;
import com.datarecovery.master.BuildConfig;
import com.datarecovery.master.R;
import com.datarecovery.master.data.consts.Constants;
import com.datarecovery.master.data.repositories.AdRepository;
import com.datarecovery.master.databinding.LayoutAdSkipButtonBinding;
import com.datarecovery.master.dialog.AdLoadingDialog;

import java.math.BigDecimal;
import java.math.RoundingMode;

import atmob.reactivex.rxjava3.disposables.Disposable;
import atmob.rxjava.utils.RxJavaUtil;
import dagger.hilt.EntryPoint;
import dagger.hilt.InstallIn;
import dagger.hilt.android.EntryPointAccessors;
import dagger.hilt.components.SingletonComponent;

public class AtmobAdHelper {

    private static final String TAG = "AtmobAdHelper";
    private static Handler handler;
    private static AdRepository adRepository;

    @SuppressLint("WrongConstant")
    public static void init(Application application) {
        if (!ProcessUtil.isMainProcess(application)) {
            return;
        }
        AtmobAdSdk.init(application, new AtmobAdConfig.Builder()
                .setDebug(BuildConfig.DEBUG)
                .setUseServerConfig(true)
                .setServerUrl("https://i90okxj.v8dashen.com:4695", false) // isOversea, false: 国内, true: 海外
                .build(), new AtmobAdSdk.AtmobAdSdkInitCallback() {
            @Override
            public void onSuccess() {
                AtmobLog.d(TAG, "AtmobAdSdk init success.");
            }

            @Override
            public void onFailed(AdError adError) {
                AtmobLog.e(TAG, "AtmobAdSdk init failed: %s.", adError);
            }
        });
        AtmobAdHelperEntryPoint entryPoint = EntryPointAccessors.fromApplication(application, AtmobAdHelperEntryPoint.class);
        adRepository = entryPoint.adRepository();
        handler = new Handler(Looper.getMainLooper());
    }

    public static void showVideo(int adFuncId, RewardVideoListenerAdapter listener) {
        if (BuildConfig.isSkipVideoAd) {
            simulateVideo(adFuncId, listener);
            return;
        }
        Activity topActivity = ActivityUtil.getTopActivity();
        int loadingLayoutRes = R.layout.dialog_ad_loading;
        int loadingStyleRes = R.style.Theme_Common_Dialog;
        AdLoadingDialog adLoadingDialog = new AdLoadingDialog(topActivity, loadingLayoutRes, loadingStyleRes);
        Runnable showVideoRunnable = () -> {
            if (!adLoadingDialog.isShowing()) {
                adLoadingDialog.show();
            }
            AtmobRewardAd atmobRewardAd = new AtmobRewardAd(ActivityUtil.getTopActivity(), String.valueOf(adFuncId));
            RewardVideoListenerAdapter atmobRewardAdListener = new RewardVideoListenerAdapter() {
                private PopupWindow adSkipPopWindow;
                private String token;
                private Disposable showSkipButtonDisposable;
                private long startTime;

                @Override
                public void onRewardAdShow() {
                    AtmobLog.d(TAG, "showVideo(%d) onShow.", adFuncId);
                    adLoadingDialog.forceDismiss();
                    getVideoToken();
                    showSkipButton();
                    startTime = System.currentTimeMillis();
                    AtmobAdHelper.onAdPlayStart(atmobRewardAd.getEcpmInfo());
                    AtmobAdHelper.onAdShow(AdConstants.RewardVideo, atmobRewardAd.getEcpmInfo());
                }

                private void showSkipButton() {
                    if (!Constants.isStoreChannel()) {
                        return;
                    }
                    showSkipButtonDisposable = adRepository.isAttributed()
                            .compose(RxJavaUtil.SingleSchedule.io2Main())
                            .subscribe(attributed -> {
                                if (attributed) {
                                    return;
                                }
                                Activity topActivity = ActivityUtil.getTopActivity();
                                if (topActivity == null || topActivity.isFinishing() || topActivity.isDestroyed()) {
                                    return;
                                }
                                if (!isAdActivity(topActivity)) {
                                    return;
                                }
                                LayoutAdSkipButtonBinding binding = LayoutAdSkipButtonBinding.inflate(topActivity.getLayoutInflater());
                                binding.getRoot().setOnClickListener(v -> {
                                    topActivity.finish();
                                    dispose();
                                });
                                adSkipPopWindow = new PopupWindow(topActivity);
                                adSkipPopWindow.setBackgroundDrawable(null);
                                adSkipPopWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
                                adSkipPopWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
                                adSkipPopWindow.setContentView(binding.getRoot());
                                adSkipPopWindow.showAsDropDown(topActivity.getWindow().getDecorView(),
                                        (int) SizeUtil.dp2px(16),
                                        (int) (SizeUtil.getStatusBarHeight() + SizeUtil.dp2px(10)));
                            }, throwable -> AtmobLog.e(TAG, "showVideo(%d) showSkipButton error: %s.", adFuncId, throwable.getMessage()));
                }

                private void getVideoToken() {
                }

                @Override
                public void onRewardAdClosed() {
                    AtmobLog.d(TAG, "showVideo(%d) onClose.", adFuncId);
                    dispose();
                    if (listener != null) {
                        if (isRewarded) {
                            listener.onRewarded(token);
                        }
                        listener.onRewardAdClosed();
                    }

                    int duration = (int) ((System.currentTimeMillis() - startTime) / 1000);
                    onAdPlayEnd(atmobRewardAd.getEcpmInfo(), duration, isRewarded);
                }

                @Override
                public void onRewardAdShowFail(AdError adError) {
                    super.onRewardAdShowFail(adError);
                    AtmobLog.e(TAG, "showVideo(%d) onFail: %s.", adFuncId, adError);
                    dispose();
                    if (listener != null) {
                        listener.onRewardAdShowFail(adError);
                    }
                }

                @Override
                public void onRewardClick() {
                    AtmobLog.d(TAG, "showVideo(%d) onClick.", adFuncId);
                    if (listener != null) {
                        listener.onRewardClick();
                    }

                    AtmobAdHelper.onAdClick(AdConstants.RewardVideo, atmobRewardAd.getEcpmInfo());
                }

                @Override
                public void onAdLoaded() {
                    super.onAdLoaded();
                    AtmobLog.d(TAG, "showVideo(%d) onAdLoaded.", adFuncId);
                    atmobRewardAd.showRewardAd();

                    AtmobAdHelper.onAdLoaded(AdConstants.RewardVideo, atmobRewardAd.getEcpmInfo());
                }

                @Override
                public void onLoadFailed(AdError adError) {
                    super.onLoadFailed(adError);
                    AtmobLog.e(TAG, "showVideo(%d) onLoadFailed: %s.", adFuncId, adError);
                    adLoadingDialog.forceDismiss();
                    if (listener != null) {
                        listener.onLoadFailed(adError);
                    }
                }

                private void dispose() {
                    if (showSkipButtonDisposable != null) {
                        showSkipButtonDisposable.dispose();
                    }
                    if (adSkipPopWindow != null) {
                        adSkipPopWindow.dismiss();
                    }
                }
            };
            atmobRewardAd.setRewardAdListener(atmobRewardAdListener);
            AtmobLog.d(TAG, "showVideo(%d) start.", adFuncId);
            atmobRewardAd.loadAd(atmobRewardAdListener);
        };
        showVideoRunnable.run();
    }

    private static boolean isAdActivity(Activity topActivity) {
        if (topActivity == null) {
            return false;
        }
        return AtmobAdSdk.isAdActivity(topActivity.getClass());
    }

    @SuppressLint("CheckResult")
    private static void simulateVideo(int adFuncId, RewardVideoListenerAdapter listener) {
        AdLoadingDialog adLoadingDialog = new AdLoadingDialog(ActivityUtil.getTopActivity(), R.layout.dialog_simulate_ad, R.style.Theme_Common_Dialog);
        adLoadingDialog.show();
        if (listener != null) {
            listener.onAdLoaded();
            listener.onRewardAdShow();
        }
        handler.postDelayed(() -> {
            adLoadingDialog.dismiss();
            if (listener != null) {
                listener.onRewarded("");
            }
            if (listener != null) {
                listener.onRewardAdClosed();
            }
        }, 3000);
    }

    public static void showInterstitial(int adFuncId, InterstitialListenerAdapter listener) {
        if (BuildConfig.isSkipOtherAd) {
            if (listener != null) {
                listener.onFail("debug skip.");
            }
            return;
        }
        Runnable showInterstitialRunnable = () -> {
            AtmobInterstitialAd atmobInterstitialAd = new AtmobInterstitialAd(ActivityUtil.getTopActivity(), String.valueOf(adFuncId));
            InterstitialListenerAdapter interstitialListenerAdapter = new InterstitialListenerAdapter() {
                @Override
                public void onShow() {
                    AtmobLog.d(TAG, "showInterstitial(%d) onShow.", adFuncId);
                    if (listener != null) {
                        listener.onShow();
                    }

                    AtmobAdHelper.onAdShow(AdConstants.Interstitial, atmobInterstitialAd.getEcpmInfo());
                }

                @Override
                public void onClose() {
                    AtmobLog.d(TAG, "showInterstitial(%d) onClose.", adFuncId);
                    if (listener != null) {
                        listener.onClose();
                    }
                }

                @Override
                public void onFail(String s) {
                    AtmobLog.e(TAG, "showInterstitial(%d) onFail: %s.", adFuncId, s);
                    if (listener != null) {
                        listener.onFail(s);
                    }
                }

                @Override
                public void onClick() {
                    AtmobLog.d(TAG, "showInterstitial(%d) onClick.", adFuncId);
                    if (listener != null) {
                        listener.onClick();
                    }

                    AtmobAdHelper.onAdClick(AdConstants.Interstitial, atmobInterstitialAd.getEcpmInfo());
                }

                @Override
                public void onAdLoaded() {
                    super.onAdLoaded();
                    AtmobLog.d(TAG, "showInterstitial(%d) onAdLoaded.", adFuncId);
                    atmobInterstitialAd.showInterstitial();

                    AtmobAdHelper.onAdLoaded(AdConstants.Interstitial, atmobInterstitialAd.getEcpmInfo());
                }
            };
            atmobInterstitialAd.setInterstitialListener(interstitialListenerAdapter);
            AtmobLog.d(TAG, "showInterstitial(%d) start.", adFuncId);
            atmobInterstitialAd.loadAd(interstitialListenerAdapter);
        };
//        if (Constants.isStoreChannel()) {
//            AtmobLog.d(TAG, "showInterstitial(%d) attribute start.", adFuncId);
//            adRepository.isAttributed().compose(RxJavaUtil.SingleSchedule.io2Main()).subscribe(new SingleObserver<Boolean>() {
//                @Override
//                public void onSubscribe(@NonNull Disposable d) {
//
//                }
//
//                @Override
//                public void onSuccess(@NonNull Boolean attributed) {
//                    if (attributed) {
//                        AtmobLog.d(TAG, "showInterstitial(%d) attribute success.", adFuncId);
//                        showInterstitialRunnable.run();
//                    } else {
//                        AtmobLog.d(TAG, "showInterstitial(%d) skip, not attributed.", adFuncId);
//                        if (listener != null) {
//                            listener.onFail("not attributed.");
//                        }
//                    }
//                }
//
//                @Override
//                public void onError(@NonNull Throwable e) {
//                    AtmobLog.e(TAG, "showInterstitial(%d) attributed error: %s.", adFuncId, e.getMessage());
//                    showInterstitialRunnable.run();
//                }
//            });
//        } else {
//            showInterstitialRunnable.run();
//        }
        showInterstitialRunnable.run();
    }

    public static void showNative(int adFuncId, ViewGroup viewGroup) {
        if (BuildConfig.isSkipOtherAd) {
            return;
        }
        Runnable showNativeRunnable = () -> {
            AtmobNativeAd atmobNativeAd = new AtmobNativeAd(ActivityUtil.getTopActivity(), String.valueOf(adFuncId));
            atmobNativeAd.setNativeAdListener(new AtmobNativeAdListener() {
                @Override
                public void onAdClick() {
                    AtmobLog.d(TAG, "showNative(%d) onAdClick.", adFuncId);

                    AtmobAdHelper.onAdClick(AdConstants.NativeUnified, atmobNativeAd.getEcpmInfo());
                }

                @Override
                public void onAdShow() {
                    AtmobLog.d(TAG, "showNative(%d) onAdShow.", adFuncId);

                    AtmobAdHelper.onAdShow(AdConstants.NativeUnified, atmobNativeAd.getEcpmInfo());
                }
            });
            atmobNativeAd.loadAd(new AtmobAdLoadCallback() {
                @Override
                public void onAdLoaded() {
                    AtmobLog.d(TAG, "showNative(%d) onAdLoaded.", adFuncId);
                    View nativeView = atmobNativeAd.getNativeView();
                    if (nativeView != null) {
                        viewGroup.removeAllViews();
                        viewGroup.addView(nativeView, new ViewGroup.LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
                    }

                    AtmobAdHelper.onAdLoaded(AdConstants.NativeUnified, atmobNativeAd.getEcpmInfo());
                }

                @Override
                public void onLoadFailed(AdError adError) {
                    AtmobLog.e(TAG, "showNative(%d) onLoadFailed: %s.", adFuncId, adError);
                }
            });
        };
//        if (Constants.isStoreChannel()) {
//            AtmobLog.d(TAG, "showNative(%d) attribute start.", adFuncId);
//            adRepository.isAttributed().compose(RxJavaUtil.SingleSchedule.io2Main()).subscribe(new SingleObserver<Boolean>() {
//                @Override
//                public void onSubscribe(@NonNull Disposable d) {
//
//                }
//
//                @Override
//                public void onSuccess(@NonNull Boolean attributed) {
//                    if (attributed) {
//                        AtmobLog.d(TAG, "showNative(%d) attribute success.", adFuncId);
//                        showNativeRunnable.run();
//                    } else {
//                        AtmobLog.d(TAG, "showNative(%d) skip, not attributed.", adFuncId);
//                    }
//                }
//
//                @Override
//                public void onError(@NonNull Throwable e) {
//                    AtmobLog.e(TAG, "showNative(%d) attributed error: %s.", adFuncId, e.getMessage());
//                    showNativeRunnable.run();
//                }
//            });
//        } else {
//            showNativeRunnable.run();
//        }
        showNativeRunnable.run();
    }

    public static void showSplash(int adFuncId, ViewGroup viewGroup, SplashListenerAdapter listener) {
        if (BuildConfig.isSkipOtherAd) {
            if (listener != null) {
                listener.action();
            }
            return;
        }
        if (viewGroup != null) {
            viewGroup.removeAllViews();
        }
        Runnable showSplashRunnable = () -> {
            AtmobSplashAd atmobSplashAd = new AtmobSplashAd(ActivityUtil.getTopActivity(), String.valueOf(adFuncId));
            SplashListenerAdapter splashListenerAdapter = new SplashListenerAdapter() {
                @Override
                public void onShow() {
                    AtmobLog.d(TAG, "showSplash(%d) onShow.", adFuncId);
                    if (listener != null) {
                        listener.onShow();
                    }

                    AtmobAdHelper.onAdShow(AdConstants.Splash, atmobSplashAd.getEcpmInfo());
                }

                @Override
                public void onClose() {
                    AtmobLog.d(TAG, "showSplash(%d) onClose.", adFuncId);
                    if (listener != null) {
                        listener.onClose();
                    }
                }

                @Override
                public void onFail(String s) {
                    AtmobLog.e(TAG, "showSplash(%d) onFail: %s.", adFuncId, s);
                    if (listener != null) {
                        listener.onFail(s);
                    }
                }

                @Override
                public void onClick() {
                    AtmobLog.d(TAG, "showSplash(%d) onClick.", adFuncId);
                    if (listener != null) {
                        listener.onClick();
                    }

                    AtmobAdHelper.onAdClick(AdConstants.Splash, atmobSplashAd.getEcpmInfo());
                }

                @Override
                public void action() {
                    AtmobLog.d(TAG, "showSplash(%d) action.", adFuncId);
                    if (listener != null) {
                        listener.action();
                    }
                }

                @Override
                public void onAdLoaded() {
                    super.onAdLoaded();
                    AtmobLog.d(TAG, "showSplash(%d) onAdLoaded.", adFuncId);
                    if (viewGroup != null) {
                        viewGroup.removeAllViews();
                        atmobSplashAd.showSplashAd(viewGroup);
                    } else {
                        if (listener != null) {
                            listener.action();
                        }
                    }

                    AtmobAdHelper.onAdLoaded(AdConstants.Splash, atmobSplashAd.getEcpmInfo());
                }
            };
            atmobSplashAd.setSplashAdListener(splashListenerAdapter);
            AtmobLog.d(TAG, "showSplash(%d) start.", adFuncId);
            atmobSplashAd.loadAd(splashListenerAdapter, 6000);
        };
//        if (Constants.isStoreChannel()) {
//            AtmobLog.d(TAG, "showSplash(%d) attribute start.", adFuncId);
//            adRepository.isAttributed().compose(RxJavaUtil.SingleSchedule.io2Main()).subscribe(new SingleObserver<Boolean>() {
//                @Override
//                public void onSubscribe(@NonNull Disposable d) {
//
//                }
//
//                @Override
//                public void onSuccess(@NonNull Boolean attributed) {
//                    if (attributed) {
//                        AtmobLog.d(TAG, "showSplash(%d) attribute success.", adFuncId);
//                        showSplashRunnable.run();
//                    } else {
//                        AtmobLog.d(TAG, "showSplash(%d) skip, not attributed.", adFuncId);
//                        if (listener != null) {
//                            listener.onFail("not attributed.");
//                            listener.action();
//                        }
//                    }
//                }
//
//                @Override
//                public void onError(@NonNull Throwable e) {
//                    AtmobLog.e(TAG, "showSplash(%d) attributed error: %s.", adFuncId, e.getMessage());
//                    showSplashRunnable.run();
//                }
//            });
//        } else {
//            showSplashRunnable.run();
//        }
        showSplashRunnable.run();
    }

    private static void onAdLoaded(int adType, EcpmInfo ecpmInfo) {
        String adUnionType = getAdUnionType(ecpmInfo);
        String adPlacementId = ecpmInfo.getPositionId();
        String adSourceId = ecpmInfo.getShowPositionId();
        String adnType = getAdnType(ecpmInfo);
        GravityEngine.trackAdLoad(adUnionType, adPlacementId, adSourceId, getAdType(adType), adnType);
    }

    private static void onAdShow(int adType, EcpmInfo ecpmInfo) {
        String adUnionType = getAdUnionType(ecpmInfo);
        String adPlacementId = ecpmInfo.getPositionId();
        String adSourceId = ecpmInfo.getShowPositionId();
        String adnType = getAdnType(ecpmInfo);
        float ecpm = getEcpm(ecpmInfo);
        GravityEngine.trackAdShow(adUnionType, adPlacementId, adSourceId, getAdType(adType), adnType, ecpm);
    }

    private static void onAdClick(int adType, EcpmInfo ecpmInfo) {
        String adUnionType = getAdUnionType(ecpmInfo);
        String adPlacementId = ecpmInfo.getPositionId();
        String adSourceId = ecpmInfo.getShowPositionId();
        String adnType = getAdnType(ecpmInfo);
        float ecpm = getEcpm(ecpmInfo);
        GravityEngine.trackAdClick(adUnionType, adPlacementId, adSourceId, getAdType(adType), adnType, ecpm);
    }

    private static void onAdPlayStart(EcpmInfo ecpmInfo) {
        String adUnionType = getAdUnionType(ecpmInfo);
        String adPlacementId = ecpmInfo.getPositionId();
        String adSourceId = ecpmInfo.getShowPositionId();
        String adnType = getAdnType(ecpmInfo);
        float ecpm = getEcpm(ecpmInfo);
        GravityEngine.trackAdPlayStart(adUnionType, adPlacementId, adSourceId, getAdType(AdConstants.RewardVideo), adnType, ecpm);
    }

    private static void onAdPlayEnd(EcpmInfo ecpmInfo, int duration, boolean isPlayOver) {
        String adUnionType = getAdUnionType(ecpmInfo);
        String adPlacementId = ecpmInfo.getPositionId();
        String adSourceId = ecpmInfo.getShowPositionId();
        String adnType = getAdnType(ecpmInfo);
        float ecpm = getEcpm(ecpmInfo);
        GravityEngine.trackAdPlayEnd(adUnionType, adPlacementId, adSourceId, getAdType(AdConstants.RewardVideo), adnType, ecpm, duration, isPlayOver);
    }

    private static String getAdType(int adType) {
        switch (adType) {
            case AdConstants.Splash:
                return "splash";
            case AdConstants.NativeExpress:
            case AdConstants.NativeUnified:
                return "native";
            case AdConstants.Interstitial:
            case AdConstants.InterstitialFull:
                return "interstitial";
            case AdConstants.RewardVideo:
                return "reward";
            case AdConstants.BannerExpress:
                return "banner";
        }
        return "";
    }

    private static String getAdUnionType(EcpmInfo ecpmInfo) {
        if (ecpmInfo == null) {
            return "self";
        }
        int platformId = ecpmInfo.getPlatformId();
        switch (platformId) {
            case AdConstants.Gromore:
                return "gromore";
            case AdConstants.Taku:
            case AdConstants.TopOn:
                return "topon";
            case AdConstants.Max:
                return "max";
            case AdConstants.ToBid:
                return "tobid";
        }
        return "self";
    }

    private static String getAdnType(EcpmInfo ecpmInfo) {
        if (ecpmInfo == null) {
            return "other";
        }
        int showPlatformId = ecpmInfo.getShowPlatformId();
        switch (showPlatformId) {
            case AdConstants.CSJ:
                return "csj";
            case AdConstants.Tencent:
                return "gdt";
            case AdConstants.Kuaishou:
                return "ks";
            case AdConstants.Mintegral:
                return "mint";
            case AdConstants.Baidu:
                return "baidu";
        }
        return "other";
    }

    /**
     * @return 单位元
     */
    private static float getEcpm(EcpmInfo ecpmInfo) {
        if (ecpmInfo == null) {
            return 0;
        }
        double ecpmCent = ecpmInfo.getEcpmCent();
        BigDecimal bigDecimal = new BigDecimal(ecpmCent);
        return bigDecimal.divide(new BigDecimal(100), 2, RoundingMode.HALF_DOWN).floatValue();
    }

    @InstallIn(SingletonComponent.class)
    @EntryPoint
    interface AtmobAdHelperEntryPoint {
        AdRepository adRepository();
    }
}