import 'dart:io';

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

import 'gravity_engine_platform_interface.dart';

/// An implementation of [GravityEnginePlatform] that uses method channels.
class MethodChannelGravityEngine extends GravityEnginePlatform {
  /// The method channel used to interact with the native platform.
  @visibleForTesting
  final methodChannel = const MethodChannel('gravity_engine');

  /// Initializes the Gravity Engine SDK.
  /// Returns `true` if the user is attributed, `false` otherwise.
  @override
  Future<bool> initialize(String appId, String accessToken, String clientId,
      String channel, bool debug) async {
    final result = await methodChannel.invokeMethod<bool>(
      'initialize',
      <String, dynamic>{
        'appId': appId,
        'accessToken': accessToken,
        'debug': debug,
        'clientId': clientId,
        'channel': channel,
      },
    );
    return result ?? false;
  }

  @override
  Future<void> trackEvent(String eventName,
      {Map<String, dynamic>? eventProperties}) async {
    await methodChannel.invokeMethod<void>(
      'track',
      <String, dynamic>{
        'eventId': eventName,
        'eventParams': eventProperties,
      },
    );
  }

  @override
  Future<void> trackPay(String orderNo, String itemName, int amountCent,
      String currency, PayType payType) async {
    await methodChannel.invokeMethod<void>(
      'trackPay',
      <String, dynamic>{
        "orderNo": orderNo,
        "itemName": itemName,
        "amount": amountCent,
        "currency": currency,
        "payType": payType.name,
      },
    );
  }

  @override
  Future<void> logout() async {
    // if android
    if (Platform.isAndroid) {
      await methodChannel.invokeMethod<void>('logout');
    }
  }

  @override
  Future<void> login(String clientId) async {
    // if android
    if (Platform.isAndroid) {
      await methodChannel.invokeMethod<void>(
        'login',
        <String, dynamic>{
          'clientId': clientId,
        },
      );
    }
  }

  @override
  Future<void> trackAdLoadEvent(String? adUnionType, String? adPlacementId,
      String? adSourceId, String? adType, String? adnType) {
    return methodChannel.invokeMethod<void>(
      'trackAdLoadEvent',
      <String, dynamic>{
        'adUnionType': adUnionType,
        'adPlacementId': adPlacementId,
        'adSourceId': adSourceId,
        'adType': adType,
        'adnType': adnType,
      },
    );
  }

  @override
  Future<void> trackAdShowEvent(String? adUnionType, String? adPlacementId,
      String? adSourceId, String? adType, String? adnType, double? ecpm) {
    return methodChannel.invokeMethod<void>(
      'trackAdShowEvent',
      <String, dynamic>{
        'adUnionType': adUnionType,
        'adPlacementId': adPlacementId,
        'adSourceId': adSourceId,
        'adType': adType,
        'adnType': adnType,
        'ecpm': ecpm,
      },
    );
  }

  @override
  Future<void> trackAdClickEvent(String? adUnionType, String? adPlacementId,
      String? adSourceId, String? adType, String? adnType, double? ecpm) {
    return methodChannel.invokeMethod<void>(
      'trackAdClickEvent',
      <String, dynamic>{
        'adUnionType': adUnionType,
        'adPlacementId': adPlacementId,
        'adSourceId': adSourceId,
        'adType': adType,
        'adnType': adnType,
        'ecpm': ecpm,
      },
    );
  }

  @override
  Future<void> trackAdPlayStartEvent(String? adUnionType, String? adPlacementId,
      String? adSourceId, String? adType, String? adnType, double? ecpm) {
    return methodChannel.invokeMethod<void>(
      'trackAdPlayStartEvent',
      <String, dynamic>{
        'adUnionType': adUnionType,
        'adPlacementId': adPlacementId,
        'adSourceId': adSourceId,
        'adType': adType,
        'adnType': adnType,
        'ecpm': ecpm,
      },
    );
  }

  @override
  Future<void> trackAdPlayEndEvent(
      String? adUnionType,
      String? adPlacementId,
      String? adSourceId,
      String? adType,
      String? adnType,
      double? ecpm,
      int? duration,
      bool? isPlayOver) {
    return methodChannel.invokeMethod<void>(
      'trackAdPlayEndEvent',
      <String, dynamic>{
        'adUnionType': adUnionType,
        'adPlacementId': adPlacementId,
        'adSourceId': adSourceId,
        'adType': adType,
        'adnType': adnType,
        'ecpm': ecpm,
        'duration': duration,
        'isPlayOver': isPlayOver,
      },
    );
  }
}

enum PayType {
  alipay,
  wechat,
  apple,
  unknown,
}

extension PayTypeExtension on PayType {
  String get name {
    switch (this) {
      case PayType.alipay:
        return "支付宝";
      case PayType.wechat:
        return "微信";
      case PayType.apple:
        return "苹果支付";
      default:
        return "未知";
    }
  }
}
