class GeofenceConfig { GeofenceConfig({this.lat, this.lng, this.radiusMeters, this.polygon}); final double? lat; final double? lng; final double? radiusMeters; final List? polygon; bool get hasPolygon => polygon?.isNotEmpty == true; bool get hasCircle => lat != null && lng != null && radiusMeters != null && radiusMeters! > 0; bool containsPolygon(double pointLat, double pointLng) { final points = polygon; if (points == null || points.isEmpty) return false; var inside = false; for (var i = 0, j = points.length - 1; i < points.length; j = i++) { final xi = points[i].lng; final yi = points[i].lat; final xj = points[j].lng; final yj = points[j].lat; final intersects = ((yi > pointLat) != (yj > pointLat)) && (pointLng < (xj - xi) * (pointLat - yi) / (yj - yi) + xi); if (intersects) { inside = !inside; } } return inside; } factory GeofenceConfig.fromJson(Map json) { final rawPolygon = json['polygon'] ?? json['points']; final polygonPoints = []; if (rawPolygon is List) { for (final entry in rawPolygon) { if (entry is Map) { polygonPoints.add(GeofencePoint.fromJson(entry)); } else if (entry is Map) { polygonPoints.add( GeofencePoint.fromJson(Map.from(entry)), ); } } } return GeofenceConfig( lat: (json['lat'] as num?)?.toDouble(), lng: (json['lng'] as num?)?.toDouble(), radiusMeters: (json['radius_m'] as num?)?.toDouble(), polygon: polygonPoints.isEmpty ? null : polygonPoints, ); } } class GeofencePoint { const GeofencePoint({required this.lat, required this.lng}); final double lat; final double lng; factory GeofencePoint.fromJson(Map json) { return GeofencePoint( lat: (json['lat'] as num).toDouble(), lng: (json['lng'] as num).toDouble(), ); } } class AppSetting { AppSetting({required this.key, required this.value}); final String key; final Map value; factory AppSetting.fromMap(Map map) { return AppSetting( key: map['key'] as String, value: Map.from(map['value'] as Map), ); } } class RamadanConfig { RamadanConfig({required this.enabled, required this.autoDetect}); final bool enabled; final bool autoDetect; factory RamadanConfig.fromJson(Map json) { return RamadanConfig( enabled: json['enabled'] as bool? ?? false, autoDetect: json['auto_detect'] as bool? ?? true, ); } Map toJson() => { 'enabled': enabled, 'auto_detect': autoDetect, }; }