/// Matches only alphabetic chars
final RegExp alphabeticPattern = RegExp(r'^[A-Za-z]+$');

/// Matches strings that contain alphanumeric chars and underscores
final RegExp alphaNumericPattern = RegExp(r'^[A-Za-z0-9_]+$');

/// Checks that the body of the request being sent to
/// GA4 is within the limitations
///
/// Limitations can be found:
/// https://developers.google.com/analytics/devguides/collection/protocol/ga4/sending-events?client_type=gtag#limitations
void checkBody(Map<String, Object?> body) {
  // Ensure we have the correct top level keys
  if (!body.keys.contains('client_id')) {
    throw AnalyticsException('client_id missing from top level keys');
  }
  if (!body.keys.contains('events')) {
    throw AnalyticsException('events missing from top level keys');
  }
  if (!body.keys.contains('user_properties')) {
    throw AnalyticsException('user_properties missing from top level keys');
  }

  final events = body['events'] as List;
  final userProperties = body['user_properties'] as Map<String, Object?>;

  // GA4 Limitation:
  // Requests can have a maximum of 25 events
  if (events.length > 25) {
    throw AnalyticsException('25 is the max number of events');
  }

  // Checks for each event object
  for (var eventMap in events.cast<Map<String, Object?>>()) {
    final eventName = eventMap['name'] as String;

    // GA4 Limitation:
    // Event names must be 40 characters or fewer, may only contain
    // alpha-numeric characters and underscores, and must start
    // with an alphabetic character
    if (eventName.length > 40) {
      throw AnalyticsException('Limit event names to 40 chars or less');
    }
    if (!alphaNumericPattern.hasMatch(eventName)) {
      throw AnalyticsException(
          'Event name can only have alphanumeric chars and underscores');
    }
    if (!alphabeticPattern.hasMatch(eventName[0])) {
      throw AnalyticsException('Event name first char must be alphabetic char');
    }

    final eventParams = eventMap['params'] as Map<String, Object?>;

    // GA4 Limitation:
    // Events can have a maximum of 25 parameters
    if (eventParams.length > 25) {
      throw AnalyticsException('Limit params for each event to less than 25');
    }

    // Loop through each of the event parameters
    for (var entry in eventParams.entries) {
      final key = entry.key;
      final value = entry.value;

      // GA4 Limitation:
      // Ensure that each value for the event params is one
      // of the following types:
      // `String`, `int`, `double`, or `bool`
      if (!(value is String ||
          value is int ||
          value is double ||
          value is bool)) {
        throw AnalyticsException(
            'Values for event params have to be String, int, double, or bool');
      }

      // GA4 Limitation:
      // Parameter names (including item parameters) must be 40 characters
      // or fewer, may only contain alpha-numeric characters and underscores,
      // and must start with an alphabetic character
      if (key.length > 40) {
        throw AnalyticsException('Limit event param names to 40 chars or less');
      }
      if (!alphaNumericPattern.hasMatch(key)) {
        throw AnalyticsException(
          'Event param name can only have alphanumeric chars and underscores',
        );
      }
      if (!alphabeticPattern.hasMatch(key[0])) {
        throw AnalyticsException(
            'Event param name first char must be alphabetic char');
      }

      // GA4 Limitation:
      // Parameter values (including item parameter values) must be 100
      // characters or fewer
      if (value.runtimeType == String) {
        value as String;
        if (value.length > 100) {
          throw AnalyticsException(
              'Limit characters in event param value to 100 chars or less');
        }
      }
    }
  }

  // GA4 Limitation:
  // Events can have a maximum of 25 user properties
  if (userProperties.length > 25) {
    throw AnalyticsException('Limit user properties to 25 or less');
  }

  // Checks for each user property item
  for (var entry in userProperties.entries) {
    final key = entry.key;
    final value = entry.value as Map<String, Object?>;

    // GA4 Limitation:
    // User property names must be 24 characters or fewer
    if (key.length > 24) {
      throw AnalyticsException('Limit user property names to 24 chars or less');
    }

    // GA4 Limitation:
    // User property values must be 36 characters or fewer
    final userPropValue = value['value'];
    if (userPropValue is String && userPropValue.length > 36) {
      throw AnalyticsException(
          'Limit user property values to 36 chars or less');
    }
  }
}

class AnalyticsException implements Exception {
  final String message;

  AnalyticsException(this.message);
}
