GrxAddressSchemaModel.fromMap constructor

GrxAddressSchemaModel.fromMap({
  1. required Map<String, dynamic> map,
})

Implementation

factory GrxAddressSchemaModel.fromMap({required Map<String, dynamic> map}) {
  String normalizeFieldId(String fieldId) {
    switch (fieldId) {
      case 'postalCode':
        return 'postal_code';
      case 'administrativeArea':
        return 'administrative_area';
      case 'dependentLocality':
        return 'dependent_locality';
      case 'countryCode':
        return 'country_code';
      case 'line1':
      case 'line2':
      case 'locality':
      case 'country':
      case 'country_code':
      case 'postal_code':
      case 'administrative_area':
      case 'dependent_locality':
        return fieldId;
      default:
        return fieldId
            .replaceAllMapped(
              RegExp('([A-Z])'),
              (match) => '_${match.group(1)!.toLowerCase()}',
            )
            .toLowerCase();
    }
  }

  final labelsMap = map['labels'] as Map? ?? {};
  final labels = <String, String>{};
  final processedKeys = <String>{};

  labelsMap.forEach((key, value) {
    final keyStr = key.toString();
    final normalizedKey = normalizeFieldId(keyStr);
    final isCamelCase =
        keyStr != normalizedKey && RegExp('[A-Z]').hasMatch(keyStr);
    if (isCamelCase && !processedKeys.contains(normalizedKey)) {
      labels[normalizedKey] = value?.toString() ?? '';
      processedKeys.add(normalizedKey);
    }
  });

  labelsMap.forEach((key, value) {
    final keyStr = key.toString();
    final normalizedKey = normalizeFieldId(keyStr);
    if (!processedKeys.contains(normalizedKey)) {
      labels[normalizedKey] = value?.toString() ?? '';
      processedKeys.add(normalizedKey);
    }
  });

  final orderList = map['order'] as List? ?? [];
  final normalizedOrder = <String>[];
  final seenFields = <String>{};
  for (final item in orderList) {
    final fieldId = item?.toString() ?? '';
    if (fieldId.isEmpty) continue;

    final normalized = normalizeFieldId(fieldId);
    if (normalized != 'country_code' &&
        normalized != 'country' &&
        !seenFields.contains(normalized)) {
      normalizedOrder.add(normalized);
      seenFields.add(normalized);
    }
  }

  final requiredList = map['required'] as List? ?? [];
  final normalizedRequired = <String>[];
  final seenRequired = <String>{};
  for (final item in requiredList) {
    final fieldId = item?.toString() ?? '';
    if (fieldId.isEmpty) continue;

    final normalized = normalizeFieldId(fieldId);
    if (normalized != 'country_code' &&
        normalized != 'country' &&
        !seenRequired.contains(normalized)) {
      normalizedRequired.add(normalized);
      seenRequired.add(normalized);
    }
  }

  List<String>? notes;
  final notesValue = map['notes'];
  if (notesValue != null) {
    if (notesValue is List) {
      notes = notesValue.map((item) => item?.toString() ?? '').toList();
    } else if (notesValue is String) {
      notes = [notesValue];
    }
  }

  List<GrxSubdivisionModel>? subdivisions;
  final subdivisionsValue = map['subdivisions'];
  if (subdivisionsValue != null && subdivisionsValue is List) {
    subdivisions = <GrxSubdivisionModel>[];
    for (final item in subdivisionsValue) {
      if (item is Map) {
        try {
          subdivisions.add(
            GrxSubdivisionModel.fromMap(Map<String, dynamic>.from(item)),
          );
        } catch (_) {
          continue;
        }
      }
    }
    if (subdivisions.isEmpty) {
      subdivisions = null;
    }
  }

  GrxPostalCodeUiModel? postalCodeUi;
  final postalCodeUiValue = map['postalCodeUi'] ?? map['postal_code_ui'];
  if (postalCodeUiValue != null && postalCodeUiValue is Map<String, dynamic>) {
    try {
      postalCodeUi = GrxPostalCodeUiModel.fromMap(postalCodeUiValue);
    } catch (_) {
      postalCodeUi = null;
    }
  }

  final countryCodeValue = map['countryCode'] ?? map['country_code'];
  if (countryCodeValue is! String) {
    throw ArgumentError('Missing required field: countryCode');
  }

  final postalCodeRuleMap =
      map['postalCodeRule'] as Map<String, dynamic>? ??
      map['postal_code_rule'] as Map<String, dynamic>?;

  return GrxAddressSchemaModel(
    countryCode: countryCodeValue,
    labels: labels,
    order: normalizedOrder,
    required: normalizedRequired,
    postalCodeRule: GrxPostalCodeRule.fromMap(postalCodeRuleMap),
    postalCodeUi: postalCodeUi,
    notes: notes,
    subdivisions: subdivisions,
  );
}