import { advertising } from '@kit.AdsKit';
import { common } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError, commonEventManager, emitter } from '@kit.BasicServicesKit';
import { AdStatus } from '../constants';
import { YTLog, yTToast } from '../../../../Index';
import { IBestToast } from '@ibestservices/ibest-ui';

const KEY_REWARD_DATA = "reward_ad_data";
const KEY_REWARD_STATUS = "reward_ad_status";

export class RewardAd {
  private ads: Array<advertising.Advertisement> = [];
  private uIContext: common.UIAbilityContext
  private load: advertising.AdLoader
  // 用于保存创建成功的订阅者对象，后续使用其完成订阅及退订的动作
  private subscriber: commonEventManager.CommonEventSubscriber | null = null;
  private displayOptions: advertising.AdDisplayOptions = {
    // 激励广告视频播放是否静音
    mute: true
  };
  private isReward = false

  constructor(uIContext: common.UIAbilityContext) {
    this.uIContext = uIContext
    this.load = new advertising.AdLoader(this.uIContext);
    this.requestAndShowAd(this.load)
  }

  // 订阅方法，需要在每次展示广告前调用
  public registerPPSReceiver(): void {
    if (this.subscriber) {
      this.unRegisterPPSReceiver();
    }
    // 订阅者信息
    const subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
      events: ["com.huawei.hms.pps.action.PPS_REWARD_STATUS_CHANGED"],
      // publisherBundleName被设置为"com.huawei.hms.adsservice",这意味着只有来自该包名的事件才会被订阅者接受和处理。
      // 如果没有明确声明publisherBundleName，那么订阅者可能会收到来自其它包名的伪造事件，从而导致安全性问题或误导。
      publisherBundleName: "com.huawei.hms.adsservice"
    };
    // 创建订阅者回调
    commonEventManager.createSubscriber(subscribeInfo, (err: BusinessError, commonEventSubscriber:
      commonEventManager.CommonEventSubscriber) => {
      if (err) {
        hilog.error(0x0000, 'testTag', '%{public}s',
          `createSubscriber error, code: ${err.code}, message: ${err.message}`);
        return;
      }
      hilog.info(0x0000, 'testTag', '%{public}s', `Succeeded in creating subscriber`);
      this.subscriber = commonEventSubscriber;
      // 订阅公共事件回调
      if (!this.subscriber) {
        hilog.warn(0x0000, 'testTag', '%{public}s', `Need create subscriber`);
        return;
      }
      commonEventManager.subscribe(this.subscriber, (err: BusinessError, commonEventSubscriber:
        commonEventManager.CommonEventData) => {
        if (err) {
          hilog.error(0x0000, 'testTag', '%{public}s', `Subscribe error, code: ${err.code}, message: ${err.message}`);
        } else {
          hilog.info(0x0000, 'testTag', '%{public}s', 'Subscribe data');
          const status: string = commonEventSubscriber?.parameters?.[KEY_REWARD_STATUS];
          switch (status) {
            case AdStatus.AD_OPEN:
              hilog.info(0x0000, 'testTag', '%{public}s', `onAdOpen`);
              //关闭弹窗
              IBestToast.hide()
              yTToast.hide()
              break;
            case AdStatus.AD_CLICKED:
              hilog.info(0x0000, 'testTag', '%{public}s', `onAdClick`);
              break;
            case AdStatus.AD_CLOSED:
              hilog.info(0x0000, 'testTag', '%{public}s', `onAdClose`);
              this.unRegisterPPSReceiver();

              if (this.isReward) {
                this.isReward = false
                if (AppStorage.get<number>('RewardNum')! < 5) {
                  setTimeout(() => {
                    // YTToast.getInstance().getReward({ number: 500 })
                  }, 500)
                }
              }


              break;
            case AdStatus.AD_REWARDED:
              const rewardData: Record<string, string | number> = commonEventSubscriber?.parameters?.[KEY_REWARD_DATA];
              const rewardType: string = rewardData?.rewardType as string;
              const rewardAmount: number = rewardData?.rewardAmount as number;
              //奖励位置
              this.isReward = true
              YTLog.info('发送奖励')
              emitter.emit('getReward')

              break;
            case AdStatus.AD_VIDEO_START:
              hilog.info(0x0000, 'testTag', '%{public}s', `onAdVideoStart`);
              break;
            case AdStatus.AD_COMPLETED:
              hilog.info(0x0000, 'testTag', '%{public}s', `onAdCompleted`);
              break;

            default:
              IBestToast.hide()
              IBestToast.show({ message: '加载失败' })
              break;
          }
        }
      });
    });
  }

  // 取消订阅
  public unRegisterPPSReceiver(): void {
    commonEventManager.unsubscribe(this.subscriber, (err: BusinessError) => {
      if (err) {
        hilog.error(0x0000, 'testTag', '%{public}s', `Unsubscribe error, code: ${err.code}, message: ${err.message}`);
      } else {
        hilog.info(0x0000, 'testTag', '%{public}s', `Succeeded in unsubscribing`);
        this.subscriber = null;
      }
    });
  }

  private requestAndShowAd(adLoader: advertising.AdLoader): void {
    const adRequestParam: advertising.AdRequestParams = {
      // 广告类型：激励广告
      adType: 7,
      // 'testx9dtjwj8hp'为测试专用的广告位ID，应用正式发布时需要改为正式的广告位ID
      adId: 'testx9dtjwj8hp',
    };
    const adOption: advertising.AdOptions = {
      // 设置是否请求非个性化广告
      nonPersonalizedAd: 0,
      // 是否允许流量下载0：不允许，1：允许，不设置以广告主设置为准
      allowMobileTraffic: 0,
      // 是否希望根据 COPPA 的规定将您的内容视为面向儿童的内容: -1默认值，不确定 0不希望 1希望
      tagForChildProtection: -1,
      // 是否希望按适合未达到法定承诺年龄的欧洲经济区 (EEA) 用户的方式处理该广告请求： -1默认值，不确定 0不希望 1希望
      tagForUnderAgeOfPromise: -1,
      // 设置广告内容分级上限: W: 3+,所有受众 PI: 7+,家长指导 J:12+,青少年 A: 16+/18+，成人受众
      adContentClassification: 'A'
    };
    const adLoaderListener: advertising.AdLoadListener = {
      onAdLoadFailure: (errorCode: number, errorMsg: string) => {
        setTimeout(() => {
          IBestToast.hide()
          setTimeout(() => {
            IBestToast.show({ message: '加载失败' })
          }, 100)
        }, 1000)
      },
      onAdLoadSuccess: (ads: Array<advertising.Advertisement>) => {
        hilog.info(0x0000, 'testTag', '%{public}s', `Succeeded in requesting ad`);
        this.ads.push(...ads);
        this.showAd()
      },
    };
    adLoader.loadAd(adRequestParam, adOption, adLoaderListener);
  }

  //展示广告
  private showAd() {
    // 请在此处自行增加步骤2中的，注册激励广告状态监听器
    this.registerPPSReceiver()

    // 此处ads[0]表示请求到的第一个广告，用户根据实际情况选择
    advertising.showAd(this.ads[0], this.displayOptions, this.uIContext);
  }
}


