import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flux_interface/flux_interface.dart';
import 'package:fstore/models/index.dart';

class FirebaseAnalyticsServiceImpl extends FirebaseAnalyticsService {
  late final FirebaseAnalytics analytics;

  FirebaseAnalyticsServiceImpl({FirebaseApp? app}) {
    analytics = app != null
        ? FirebaseAnalytics.instanceFor(app: app)
        : FirebaseAnalytics.instance;
  }

  @override
  void init({
    bool? adStorageConsentGranted,
    bool? analyticsStorageConsentGranted,
    bool? adPersonalizationSignalsConsentGranted,
    bool? adUserDataConsentGranted,
    bool? functionalityStorageConsentGranted,
    bool? personalizationStorageConsentGranted,
    bool? securityStorageConsentGranted,
  }) {
    analytics.logAppOpen();
    analytics.setConsent(
      adStorageConsentGranted: adStorageConsentGranted,
      analyticsStorageConsentGranted: analyticsStorageConsentGranted,
      adPersonalizationSignalsConsentGranted:
          adPersonalizationSignalsConsentGranted,
      adUserDataConsentGranted: adUserDataConsentGranted,
      functionalityStorageConsentGranted: functionalityStorageConsentGranted,
      personalizationStorageConsentGranted:
          personalizationStorageConsentGranted,
      securityStorageConsentGranted: securityStorageConsentGranted,
    );
  }

  @override
  List<NavigatorObserver> getMNavigatorObservers() {
    return <NavigatorObserver>[FirebaseAnalyticsObserver(analytics: analytics)];
  }

  @override
  Future<void> logCustomEvent({
    required String name,
    Map<String, Object>? parameter,
  }) async {
    await analytics.logEvent(name: name, parameters: parameter);
  }

  @override
  Future<void> logViewItemList({
    String? itemListId,
    String? itemListName,
    dynamic data,
  }) async {
    List<AnalyticsEventItem>? items;
    if (data is List<Product>) {
      items = [];
      for (var item in data) {
        items.add(
          AnalyticsEventItem(
            itemId: item.id,
            itemName: item.name,
            itemCategory: item.type ?? item.categoryId,
            price: double.tryParse(item.price ?? ''),
            // currency: data.
          ),
        );
      }
    }
    await analytics.logViewItemList(
      itemListId: itemListId,
      itemListName: itemListName,
      items: items,
    );
  }

  @override
  Future<void> logSelectItem({
    String? itemListId,
    String? itemListName,
    dynamic data,
  }) async {
    List<AnalyticsEventItem>? items;
    if (data is Product) {
      items = [
        AnalyticsEventItem(
          itemId: data.id,
          itemName: data.name,
          itemCategory: data.type ?? data.categoryId,
          price: double.tryParse(data.price ?? ''),
          // currency: data.
        ),
      ];
    }
    await analytics.logSelectItem(
      itemListId: itemListId,
      itemListName: itemListName,
      items: items,
    );
  }

  @override
  Future<void> logViewItem({
    String? currency,
    double? price,
    dynamic data,
  }) async {
    List<AnalyticsEventItem>? items;
    if (data is Product) {
      items = [
        AnalyticsEventItem(
          itemId: data.id,
          itemName: data.name,
          itemCategory: data.type ?? data.categoryId,
          price: double.tryParse(data.price ?? ''),
          currency: currency,
        ),
      ];
    }
    await analytics.logViewItem(currency: currency, value: price, items: items);
  }

  @override
  Future<void> logAddToWishlist({
    String? currency,
    double? price,
    dynamic data,
  }) async {
    List<AnalyticsEventItem>? items;
    if (data is Product) {
      items = [
        AnalyticsEventItem(
          itemId: data.id,
          itemName: data.name,
          itemCategory: data.type ?? data.categoryId,
          price: double.tryParse(data.price ?? ''),
          currency: currency,
        ),
      ];
    }
    await analytics.logAddToWishlist(
      currency: currency,
      value: price,
      items: items,
    );
  }

  @override
  Future<void> logAddToCart({
    String? currency,
    double? price,
    dynamic data,
    int? quantity,
  }) async {
    List<AnalyticsEventItem>? items;
    if (data is Product) {
      items = [
        AnalyticsEventItem(
          itemId: data.id,
          itemName: data.name,
          itemCategory: data.type ?? data.categoryId,
          price: double.tryParse(data.price ?? ''),
          currency: currency,
          quantity: quantity,
        ),
      ];
    }
    await analytics.logAddToCart(
      currency: currency,
      value: price,
      items: items,
    );
  }

  @override
  Future<void> logViewCart({
    String? currency,
    double? price,
    dynamic data,
  }) async {
    List<AnalyticsEventItem>? items;
    if (data is Map) {
      items = [];
      for (var item in data.values) {
        var product = item['product'];
        if (product is Product) {
          items.add(
            AnalyticsEventItem(
              itemId: item['key'],
              itemName: product.name,
              itemCategory: product.type ?? product.categoryId,
              price: double.tryParse(product.price ?? ''),
              quantity: item['quantity'],
              currency: currency,
            ),
          );
        }
      }
    }
    await analytics.logViewCart(currency: currency, value: price, items: items);
  }

  @override
  Future<void> logRemoveFromCart({
    String? currency,
    double? price,
    dynamic data,
    int? quantity,
  }) async {
    var items = <AnalyticsEventItem>[];
    if (data is Product) {
      items.add(
        AnalyticsEventItem(
          itemId: data.id,
          itemName: data.name,
          itemCategory: data.type ?? data.categoryId,
          price: double.tryParse(data.price ?? ''),
          quantity: quantity,
          currency: currency,
        ),
      );
    }
    await analytics.logRemoveFromCart(
      currency: currency,
      value: price,
      items: items,
    );
  }

  @override
  Future<void> logBeginCheckout({
    String? currency,
    double? price,
    dynamic data,
    String? coupon,
  }) async {
    List<AnalyticsEventItem>? items;
    if (data is List) {
      items = [];
      for (var item in data) {
        var product = item['product'];
        if (product is Product) {
          items.add(
            AnalyticsEventItem(
              itemId: item['key'],
              itemName: product.name,
              itemCategory: product.type ?? product.categoryId,
              price: double.tryParse(product.price ?? ''),
              quantity: item['quantity'],
              currency: currency,
            ),
          );
        }
      }
    }
    await analytics.logBeginCheckout(
      currency: currency,
      value: price,
      coupon: coupon,
      items: items,
    );
  }

  @override
  Future<void> logAddShippingInfo({
    String? currency,
    double? price,
    dynamic data,
    String? coupon,
    String? shippingTier,
  }) async {
    List<AnalyticsEventItem>? items;
    if (data is List) {
      items = [];
      for (var item in data) {
        var product = item['product'];
        if (product is Product) {
          items.add(
            AnalyticsEventItem(
              itemId: item['key'],
              itemName: product.name,
              itemCategory: product.type ?? product.categoryId,
              price: double.tryParse(product.price ?? ''),
              quantity: item['quantity'],
              currency: currency,
            ),
          );
        }
      }
    }
    await analytics.logAddShippingInfo(
      currency: currency,
      value: price,
      coupon: coupon,
      items: items,
      shippingTier: shippingTier,
    );
  }

  @override
  Future<void> logAddPaymentInfo({
    String? currency,
    double? price,
    dynamic data,
    String? coupon,
    String? paymentType,
  }) async {
    List<AnalyticsEventItem>? items;
    if (data is List) {
      items = [];
      for (var item in data) {
        var product = item['product'];
        if (product is Product) {
          items.add(
            AnalyticsEventItem(
              itemId: item['key'],
              itemName: product.name,
              itemCategory: product.type ?? product.categoryId,
              price: double.tryParse(product.price ?? ''),
              quantity: item['quantity'],
              currency: currency,
            ),
          );
        }
      }
    }
    await analytics.logAddPaymentInfo(
      currency: currency,
      value: price,
      coupon: coupon,
      paymentType: paymentType,
      items: items,
    );
  }

  @override
  Future<void> logPurchase({
    String? orderId,
    String? currency,
    double? price,
    double? shipping,
    double? tax,
    dynamic data,
    String? coupon,
  }) async {
    List<AnalyticsEventItem>? items;
    if (data is List) {
      items = [];
      for (var item in data) {
        var product = item['product'];
        if (product is Product) {
          items.add(
            AnalyticsEventItem(
              itemId: item['key'],
              itemName: product.name,
              itemCategory: product.type ?? product.categoryId,
              price: double.tryParse(product.price ?? ''),
              quantity: item['quantity'],
              currency: currency,
            ),
          );
        }
      }
    }
    await analytics.logPurchase(
      transactionId: orderId,
      currency: currency,
      value: price,
      shipping: shipping,
      tax: tax,
      coupon: coupon,
      items: items,
      // affiliation: 'Google Store',
    );
  }

  @override
  Future<void> logRefund({
    String? orderId,
    String? currency,
    double? price,
    dynamic data,
  }) async {
    List<AnalyticsEventItem>? items;
    if (data is List) {
      items = [];
      for (var item in data) {
        if (item is ProductItem) {
          items.add(
            AnalyticsEventItem(
              itemId: item.id,
              itemName: item.name,
              itemCategory: item.product?.type ?? item.product?.categoryId,
              price: double.tryParse(item.product?.price ?? ''),
              quantity: item.quantity,
              currency: currency,
            ),
          );
        }
      }
    }
    await analytics.logRefund(
      transactionId: orderId,
      currency: currency,
      value: price,
      items: items,
      // affiliation: 'Google Store',
    );
  }

  @override
  Future<void> logViewPromotion({
    String? promotionId,
    String? promotionName,
    String? creativeName,
    String? creativeSlot,
    String? locationId,
    dynamic data,
  }) async {
    List<AnalyticsEventItem>? items;
    await analytics.logViewPromotion(
      promotionId: promotionId,
      promotionName: promotionName,
      creativeName: creativeName,
      creativeSlot: creativeSlot,
      locationId: locationId,
      items: items,
    );
  }

  @override
  Future<void> logSelectPromotion({
    String? promotionId,
    String? promotionName,
    String? creativeName,
    String? creativeSlot,
    String? locationId,
    dynamic data,
  }) async {
    List<AnalyticsEventItem>? items;
    await analytics.logSelectPromotion(
      promotionId: promotionId,
      promotionName: promotionName,
      creativeName: creativeName,
      creativeSlot: creativeSlot,
      locationId: locationId,
      items: items,
    );
  }
}
