import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:mnemo_cards/managers/user_manager.dart';
import 'package:mnemo_cards/utils/iterable_helper.dart';
import 'package:mnemo_cards_common/mnemo_cards_common.dart';

class Analytics {
  static final _analytics = FirebaseAnalytics.instance;
  static final _crashlytics = FirebaseCrashlytics.instance;

  static Future<void> setUser(UserDto user) {
    return _analytics.setUserId(id: user.id?.toString());
  }

  static Future<void> login(ExternalIdType idType) {
    return _analytics.logLogin(loginMethod: idType.name);
  }

  static Future<void> logout(UserDto? dto) async {
    await _analytics.logEvent(
      name: 'logout',
      parameters: {
        'id': dto?.id,
      }.asFirebaseMap,
    );
    return _analytics.setUserId(id: dto?.id?.toString());
  }

  static Future<void> profilePageOpened(UserDto? dto) {
    return _analytics.logScreenView(
        screenClass: 'profile',
        screenName: 'profile',
        parameters: {
          'id': dto?.id,
        }.asFirebaseMap);
  }

  static Future<void> availablePackOpened(CardPackDto dto) {
    return _analytics.logScreenView(
        screenClass: 'pack',
        screenName: 'available',
        parameters: {
          'id': dto.id,
          'title': dto.title,
          'version': dto.version,
        }.asFirebaseMap);
  }

  static Future<void> buyPackOpened(CardPackBuyDto dto) {
    return _analytics.logScreenView(
        screenClass: 'pack',
        screenName: 'buy',
        parameters: {
          'id': dto.id,
          'title': dto.title,
          'version': dto.version,
          'price': dto.price,
        }.asFirebaseMap);
  }

  static Future<void> buyPackPressed(CardPackBuyDto dto, PaymentSystem system) {
    return _analytics.logEvent(
        name: 'buy',
        parameters: {
          'id': dto.id,
          'title': dto.title,
          'version': dto.version,
          'price': dto.price,
          'system': system.name,
        }.asFirebaseMap);
  }

  static Future<void> buyError(
    CardPackBuyDto? dto,
    PaymentSystem system, {
    Map<String, String?>? data,
    String? message,
  }) {
    return _analytics.logEvent(
        name: 'buy_error',
        parameters: {
          'id': dto?.id.toString(),
          'system': system.name,
          'version': dto?.version.toString(),
          'price': dto?.price.toString(),
          if (message != null) 'message': message,
          if (data != null) ...data,
        }.asFirebaseMap);
  }

  static Future<void> buyEvent(
    CardPackBuyDto? dto,
    PaymentSystem system, {
    Map<String, String?>? data,
    String? message,
  }) {
    return _analytics.logEvent(
        name: 'buy_event',
        parameters: {
          'id': dto?.id,
          'system': system.name,
          'version': dto?.version,
          'price': dto?.price,
          if (message != null) 'message': message,
          if (data != null) ...data,
        }.asFirebaseMap);
  }

  static Future<void> buyComplete(
    CardPackBuyDto? dto,
    PaymentSystem system, {
    Map<String, String?>? data,
    String? message,
  }) {
    return _analytics.logEvent(
      name: 'buy_complete',
      parameters: {
        'id': dto?.id,
        'system': system.name,
        'version': dto?.version,
        'price': dto?.price,
        if (message != null) 'message': message,
        if (data != null) ...data,
      }.asFirebaseMap,
    );
  }

  static Future<void> loadingPackOpened(CardPackDto dto, int timeMillis) {
    return _analytics.logScreenView(
        screenClass: 'pack',
        screenName: 'loading',
        parameters: {
          'id': dto.id,
          'title': dto.title,
          'version': dto.version,
          'time': timeMillis,
        }.asFirebaseMap);
  }

  static Future<void> testOpened(TestDto dto) {
    return _analytics.logScreenView(
        screenClass: 'test',
        screenName: 'test',
        parameters: {
          'id': dto.id,
          'name': dto.name,
          'version': dto.version,
          'questions': dto.questions.length,
        }.asFirebaseMap);
  }

  static crashlyticsError({
    Object? e,
    StackTrace? s,
    String? message,
    Map<String, Object?>? data,
  }) =>
      _crashlytics.recordError(
        e,
        s,
        reason: message,
        information: data?.asFirebaseMap.entries.toList() ?? [],
      );
}

extension on Map {
  Map<String, Object?> get asFirebaseMap => (Map.from(this)
        ..removeWhere((k, v) => v == null))
      .map((k, v) => MapEntry(k, (v is String || v is num) ? v : v.toString()));
}
