// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// ignore_for_file: deprecated_member_use_from_same_package

import 'dart:async';
import 'dart:io' show Platform;

import 'package:flutter/services.dart';
import 'package:meta/meta.dart';

/// [MobileAd] status changes reported to [MobileAdListener]s.
///
/// Applications can wait until an ad is [MobileAdEvent.loaded] before showing
/// it, to ensure that the ad is displayed promptly.
enum MobileAdEvent {
  loaded,
  failedToLoad,
  clicked,
  impression,
  opened,
  leftApplication,
  closed,
}

/// The user's gender for the sake of ad targeting using [MobileAdTargetingInfo].
// Warning: the index values of the enums must match the values of the corresponding
// AdMob constants. For example MobileAdGender.female.index == kGADGenderFemale.
@Deprecated('This functionality is deprecated in AdMob without replacement.')
enum MobileAdGender {
  unknown,
  male,
  female,
}

/// Signature for a [MobileAd] status change callback.
typedef void MobileAdListener(MobileAdEvent event);

/// Targeting info per the native AdMob API.
///
/// This class's properties mirror the native AdRequest API. See for example:
/// [AdRequest.Builder for Android](https://firebase.google.com/docs/reference/android/com/google/android/gms/ads/AdRequest.Builder).
class MobileAdTargetingInfo {
  const MobileAdTargetingInfo(
      {this.keywords,
      this.contentUrl,
      @Deprecated('This functionality is deprecated in AdMob without replacement.')
          this.birthday,
      @Deprecated('This functionality is deprecated in AdMob without replacement.')
          this.gender,
      @Deprecated('Use `childDirected` instead.')
          this.designedForFamilies,
      this.childDirected,
      this.testDevices,
      this.nonPersonalizedAds});

  final List<String> keywords;
  final String contentUrl;
  @Deprecated('This functionality is deprecated in AdMob without replacement.')
  final DateTime birthday;
  @Deprecated('This functionality is deprecated in AdMob without replacement.')
  final MobileAdGender gender;
  @Deprecated(
      'This functionality is deprecated in AdMob.  Use `childDirected` instead.')
  final bool designedForFamilies;
  final bool childDirected;
  final List<String> testDevices;
  final bool nonPersonalizedAds;

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> json = <String, dynamic>{
      'requestAgent': 'flutter-alpha',
    };

    if (keywords != null && keywords.isNotEmpty) {
      assert(keywords.every((String s) => s != null && s.isNotEmpty));
      json['keywords'] = keywords;
    }
    if (nonPersonalizedAds != null)
      json['nonPersonalizedAds'] = nonPersonalizedAds;
    if (contentUrl != null && contentUrl.isNotEmpty)
      json['contentUrl'] = contentUrl;
    if (birthday != null) json['birthday'] = birthday.millisecondsSinceEpoch;
    if (gender != null) json['gender'] = gender.index;
    if (designedForFamilies != null)
      json['designedForFamilies'] = designedForFamilies;
    if (childDirected != null) json['childDirected'] = childDirected;
    if (testDevices != null && testDevices.isNotEmpty) {
      assert(testDevices.every((String s) => s != null && s.isNotEmpty));
      json['testDevices'] = testDevices;
    }

    return json;
  }
}

enum AnchorType { bottom, top }

// The types of ad sizes supported for banners. The names of the values are used
// in MethodChannel calls to iOS and Android, and should not be changed.
enum AdSizeType {
  WidthAndHeight,
  SmartBanner,
}

/// [AdSize] represents the size of a banner ad. There are six sizes available,
/// which are the same for both iOS and Android. See the guides for banners on
/// [Android](https://developers.google.com/admob/android/banner#banner_sizes)
/// and [iOS](https://developers.google.com/admob/ios/banner#banner_sizes) for
/// additional details.
class AdSize {
  // Private constructor. Apps should use the static constants rather than
  // create their own instances of [AdSize].
  const AdSize._({
    @required this.width,
    @required this.height,
    @required this.adSizeType,
  });

  final int height;
  final int width;
  final AdSizeType adSizeType;

  /// The standard banner (320x50) size.
  static const AdSize banner = AdSize._(
    width: 320,
    height: 50,
    adSizeType: AdSizeType.WidthAndHeight,
  );

  /// The large banner (320x100) size.
  static const AdSize largeBanner = AdSize._(
    width: 320,
    height: 100,
    adSizeType: AdSizeType.WidthAndHeight,
  );

  /// The medium rectangle (300x250) size.
  static const AdSize mediumRectangle = AdSize._(
    width: 300,
    height: 250,
    adSizeType: AdSizeType.WidthAndHeight,
  );

  /// The full banner (468x60) size.
  static const AdSize fullBanner = AdSize._(
    width: 468,
    height: 60,
    adSizeType: AdSizeType.WidthAndHeight,
  );

  /// The leaderboard (728x90) size.
  static const AdSize leaderboard = AdSize._(
    width: 728,
    height: 90,
    adSizeType: AdSizeType.WidthAndHeight,
  );

  /// The smart banner size. Smart banners are unique in that the width and
  /// height values declared here aren't used. At runtime, the Mobile Ads SDK
  /// will automatically adjust the banner's width to match the width of the
  /// displaying device's screen. It will also set the banner's height using a
  /// calculation based on the displaying device's height. For more info see the
  /// [Android](https://developers.google.com/admob/android/banner) and
  /// [iOS](https://developers.google.com/admob/ios/banner) banner ad guides.
  static const AdSize smartBanner = AdSize._(
    width: 0,
    height: 0,
    adSizeType: AdSizeType.SmartBanner,
  );
}

/// A mobile [BannerAd] or [InterstitialAd] for the [FirebaseAdMobPlugin].
///
/// A [MobileAd] must be loaded with [load] before it is shown with [show].
///
/// A valid [adUnitId] is required.
abstract class MobileAd {
  /// Default constructor, used by subclasses.
  MobileAd(
      {@required this.adUnitId,
      MobileAdTargetingInfo targetingInfo,
      this.listener})
      : _targetingInfo = targetingInfo ?? const MobileAdTargetingInfo() {
    assert(adUnitId != null && adUnitId.isNotEmpty);
    assert(_allAds[id] == null);
    _allAds[id] = this;
  }

  static final Map<int, MobileAd> _allAds = <int, MobileAd>{};

  /// Optional targeting info per the native AdMob API.
  MobileAdTargetingInfo get targetingInfo => _targetingInfo;
  final MobileAdTargetingInfo _targetingInfo;

  /// Identifies the source of ads for your application.
  ///
  /// For testing use a [sample ad unit](https://developers.google.com/admob/ios/test-ads#sample_ad_units).
  final String adUnitId;

  /// Called when the status of the ad changes.
  MobileAdListener listener;

  /// An internal id that identifies this mobile ad to the native AdMob plugin.
  ///
  /// Plugin log messages will identify this property as the ad's `mobileAdId`.
  int get id => hashCode;

  /// Start loading this ad.
  Future<bool> load();

  /// Show this ad.
  ///
  /// The ad must have been loaded with [load] first. If loading hasn't finished
  /// the ad will not actually appear until the ad has finished loading.
  ///
  /// The [listener] will be notified when the ad has finished loading or fails
  /// to do so. An ad that fails to load will not be shown.
  ///
  /// anchorOffset is the logical pixel offset from the edge of the screen (default 0.0)
  /// anchorType place advert at top or bottom of screen (default bottom)
  Future<bool> show(
      {double anchorOffset = 0.0, AnchorType anchorType = AnchorType.bottom}) {
    return _invokeBooleanMethod("showAd", <String, dynamic>{
      'id': id,
      'anchorOffset': anchorOffset.toString(),
      'anchorType': anchorType == AnchorType.top ? "top" : "bottom"
    });
  }

  /// Free the plugin resources associated with this ad.
  ///
  /// Disposing a banner ad that's been shown removes it from the screen.
  /// Interstitial ads can't be programmatically removed from view.
  Future<bool> dispose() {
    assert(_allAds[id] != null);
    _allAds[id] = null;
    return _invokeBooleanMethod("disposeAd", <String, dynamic>{'id': id});
  }

  Future<bool> isLoaded() {
    return _invokeBooleanMethod("isAdLoaded", <String, dynamic>{
      'id': id,
    });
  }
}

/// A banner ad for the [FirebaseAdMobPlugin].
class BannerAd extends MobileAd {
  /// Create a BannerAd.
  ///
  /// A valid [adUnitId] is required.
  BannerAd({
    @required String adUnitId,
    @required this.size,
    MobileAdTargetingInfo targetingInfo,
    MobileAdListener listener,
  }) : super(
            adUnitId: adUnitId,
            targetingInfo: targetingInfo,
            listener: listener);

  final AdSize size;

  /// These are AdMob's test ad unit IDs, which always return test ads. You're
  /// encouraged to use them for testing in your own apps.
  static final String testAdUnitId = Platform.isAndroid
      ? 'ca-app-pub-3940256099942544/6300978111'
      : 'ca-app-pub-3940256099942544/2934735716';

  @override
  Future<bool> load() {
    return _invokeBooleanMethod("loadBannerAd", <String, dynamic>{
      'id': id,
      'adUnitId': adUnitId,
      'targetingInfo': targetingInfo?.toJson(),
      'width': size.width,
      'height': size.height,
      'adSizeType': size.adSizeType.toString(),
    });
  }
}

/// A full-screen interstitial ad for the [FirebaseAdMobPlugin].
class InterstitialAd extends MobileAd {
  /// Create an Interstitial.
  ///
  /// A valid [adUnitId] is required.
  InterstitialAd({
    String adUnitId,
    MobileAdTargetingInfo targetingInfo,
    MobileAdListener listener,
  }) : super(
            adUnitId: adUnitId,
            targetingInfo: targetingInfo,
            listener: listener);

  /// A platform-specific AdMob test ad unit ID for interstitials. This ad unit
  /// has been specially configured to always return test ads, and developers
  /// are encouraged to use it while building and testing their apps.
  static final String testAdUnitId = Platform.isAndroid
      ? 'ca-app-pub-3940256099942544/1033173712'
      : 'ca-app-pub-3940256099942544/4411468910';

  @override
  Future<bool> load() {
    return _invokeBooleanMethod("loadInterstitialAd", <String, dynamic>{
      'id': id,
      'adUnitId': adUnitId,
      'targetingInfo': targetingInfo?.toJson(),
    });
  }
}

/// [RewardedVideoAd] status changes reported to [RewardedVideoAdListener]s.
///
/// The [rewarded] event is particularly important, since it indicates that the
/// user has watched a video for long enough to be given an in-app reward.
enum RewardedVideoAdEvent {
  loaded,
  failedToLoad,
  opened,
  leftApplication,
  closed,
  rewarded,
  started,
  completed,
}

/// Signature for a [RewardedVideoAd] status change callback. The optional
/// parameters are only used when the [RewardedVideoAdEvent.rewarded] event
/// is sent, when they'll contain the reward amount and reward type that were
/// configured for the AdMob ad unit when it was created. They will be null for
/// all other events.
typedef void RewardedVideoAdListener(RewardedVideoAdEvent event,
    {String rewardType, int rewardAmount});

/// An AdMob rewarded video ad.
///
/// This class is a singleton, and [RewardedVideoAd.instance] provides a
/// reference to the single instance, which is created at launch. The native
/// Android and iOS APIs for AdMob use a singleton to manage rewarded video ad
/// objects, and that pattern is reflected here.
///
/// Apps should assign a callback function to [RewardedVideoAd]'s listener
/// property in order to receive reward notifications from the AdMob SDK:
/// ```
/// RewardedVideoAd.instance.listener = (RewardedVideoAdEvent event,
///     [String rewardType, int rewardAmount]) {
///     print("You were rewarded with $rewardAmount $rewardType!");
///   }
/// };
/// ```
///
/// The function will be invoked when any of the events in
/// [RewardedVideoAdEvent] occur.
///
/// To load and show ads, call the load method:
/// ```
/// RewardedVideoAd.instance.load(myAdUnitString, myTargetingInfoObj);
/// ```
///
/// Later (any point after your listener callback receives the
/// RewardedVideoAdEvent.loaded event), call the show method:
/// ```
/// RewardedVideoAd.instance.show();
/// ```
///
/// Only one rewarded video ad can be loaded at a time. Because the video assets
/// are so large, it's a good idea to start loading an ad well in advance of
/// when it's likely to be needed.
class RewardedVideoAd {
  RewardedVideoAd._();

  /// A platform-specific AdMob test ad unit ID for rewarded video ads. This ad
  /// unit has been specially configured to always return test ads, and
  /// developers are encouraged to use it while building and testing their apps.
  static final String testAdUnitId = Platform.isAndroid
      ? 'ca-app-pub-3940256099942544/5224354917'
      : 'ca-app-pub-3940256099942544/1712485313';

  static final RewardedVideoAd _instance = RewardedVideoAd._();

  /// The one and only instance of this class.
  static RewardedVideoAd get instance => _instance;

  /// Callback invoked for events in the rewarded video ad lifecycle.
  RewardedVideoAdListener listener;

  /// Shows a rewarded video ad if one has been loaded.
  Future<bool> show() {
    return _invokeBooleanMethod("showRewardedVideoAd");
  }

  /// Loads a rewarded video ad using the provided ad unit ID.
  Future<bool> load(
      {@required String adUnitId, MobileAdTargetingInfo targetingInfo}) {
    assert(adUnitId.isNotEmpty);
    return _invokeBooleanMethod("loadRewardedVideoAd", <String, dynamic>{
      'adUnitId': adUnitId,
      'targetingInfo': targetingInfo?.toJson(),
    });
  }
}

/// Support for Google AdMob mobile ads.
///
/// Before loading or showing an ad the plugin must be initialized with
/// an AdMob app id:
/// ```
/// FirebaseAdMob.instance.initialize(appId: myAppId);
/// ```
///
/// Apps can create, load, and show mobile ads. For example:
/// ```
/// BannerAd myBanner = BannerAd(unitId: myBannerAdUnitId)
///   ..load()
///   ..show();
/// ```
///
/// See also:
///
///  * The example associated with this plugin.
///  * [BannerAd], a small rectangular ad displayed at the bottom of the screen.
///  * [InterstitialAd], a full screen ad that must be dismissed by the user.
///  * [RewardedVideoAd], a full screen video ad that provides in-app user
///    rewards.
class FirebaseAdMob {
  @visibleForTesting
  FirebaseAdMob.private(MethodChannel channel) : _channel = channel {
    _channel.setMethodCallHandler(_handleMethod);
  }

  // A placeholder AdMob App ID for testing. AdMob App IDs and ad unit IDs are
  // specific to a single operating system, so apps building for both Android and
  // iOS will need a set for each platform.
  static final String testAppId = Platform.isAndroid
      ? 'ca-app-pub-3940256099942544~3347511713'
      : 'ca-app-pub-3940256099942544~1458002511';

  static final FirebaseAdMob _instance = FirebaseAdMob.private(
    const MethodChannel('plugins.flutter.io/firebase_admob'),
  );

  /// The single shared instance of this plugin.
  static FirebaseAdMob get instance => _instance;

  final MethodChannel _channel;

  static const Map<String, MobileAdEvent> _methodToMobileAdEvent =
      <String, MobileAdEvent>{
    'onAdLoaded': MobileAdEvent.loaded,
    'onAdFailedToLoad': MobileAdEvent.failedToLoad,
    'onAdClicked': MobileAdEvent.clicked,
    'onAdImpression': MobileAdEvent.impression,
    'onAdOpened': MobileAdEvent.opened,
    'onAdLeftApplication': MobileAdEvent.leftApplication,
    'onAdClosed': MobileAdEvent.closed,
  };

  static const Map<String, RewardedVideoAdEvent> _methodToRewardedVideoAdEvent =
      <String, RewardedVideoAdEvent>{
    'onRewarded': RewardedVideoAdEvent.rewarded,
    'onRewardedVideoAdClosed': RewardedVideoAdEvent.closed,
    'onRewardedVideoAdFailedToLoad': RewardedVideoAdEvent.failedToLoad,
    'onRewardedVideoAdLeftApplication': RewardedVideoAdEvent.leftApplication,
    'onRewardedVideoAdLoaded': RewardedVideoAdEvent.loaded,
    'onRewardedVideoAdOpened': RewardedVideoAdEvent.opened,
    'onRewardedVideoStarted': RewardedVideoAdEvent.started,
    'onRewardedVideoCompleted': RewardedVideoAdEvent.completed,
  };

  /// Initialize this plugin for the AdMob app specified by `appId`.
  Future<bool> initialize(
      {@required String appId,
      String trackingId,
      bool analyticsEnabled = false}) {
    assert(appId != null && appId.isNotEmpty);
    assert(analyticsEnabled != null);
    return _invokeBooleanMethod("initialize", <String, dynamic>{
      'appId': appId,
      'trackingId': trackingId,
      'analyticsEnabled': analyticsEnabled,
    });
  }

  Future<dynamic> _handleMethod(MethodCall call) {
    assert(call.arguments is Map);
    final Map<dynamic, dynamic> argumentsMap = call.arguments;
    final RewardedVideoAdEvent rewardedEvent =
        _methodToRewardedVideoAdEvent[call.method];
    if (rewardedEvent != null) {
      if (RewardedVideoAd.instance.listener != null) {
        if (rewardedEvent == RewardedVideoAdEvent.rewarded) {
          RewardedVideoAd.instance.listener(rewardedEvent,
              rewardType: argumentsMap['rewardType'],
              rewardAmount: argumentsMap['rewardAmount']);
        } else {
          RewardedVideoAd.instance.listener(rewardedEvent);
        }
      }
    } else {
      final int id = argumentsMap['id'];
      if (id != null && MobileAd._allAds[id] != null) {
        final MobileAd ad = MobileAd._allAds[id];
        final MobileAdEvent mobileAdEvent = _methodToMobileAdEvent[call.method];
        if (mobileAdEvent != null && ad.listener != null) {
          ad.listener(mobileAdEvent);
        }
      }
    }

    return Future<dynamic>.value(null);
  }
}

Future<bool> _invokeBooleanMethod(String method, [dynamic arguments]) async {
  final bool result = await FirebaseAdMob.instance._channel.invokeMethod<bool>(
    method,
    arguments,
  );
  return result;
}
