class BusStopModel { final String id; final String name; final double lat; final double lng; final String? city; final String? address; final String? parentId; final String? side; final String stopType; final bool hasShelter; final bool hasSeating; final bool isAccessible; final DateTime? createdAt; final DateTime? updatedAt; // Route-specific fields (from route_stops junction table) final int? stopOrder; final int? travelTimeMinutes; final bool? isPickupPoint; final bool? isDropoffPoint; BusStopModel({ required this.id, required this.name, required this.lat, required this.lng, this.city, this.address, this.parentId, this.side, this.stopType = 'regular', this.hasShelter = false, this.hasSeating = false, this.isAccessible = false, this.createdAt, this.updatedAt, this.stopOrder, this.travelTimeMinutes, this.isPickupPoint, this.isDropoffPoint, }); factory BusStopModel.fromJson(Map json) { return BusStopModel( id: json['id']?.toString() ?? '', name: json['name']?.toString() ?? '', lat: double.tryParse(json['lat']?.toString() ?? '0') ?? 0.0, lng: double.tryParse(json['lng']?.toString() ?? '0') ?? 0.0, city: json['city']?.toString(), address: json['address']?.toString(), parentId: json['parent_id']?.toString(), side: json['side']?.toString(), stopType: json['stop_type']?.toString() ?? 'regular', hasShelter: json['has_shelter'] == true, hasSeating: json['has_seating'] == true, isAccessible: json['is_accessible'] == true, createdAt: json['created_at'] != null ? DateTime.tryParse(json['created_at'].toString()) : null, updatedAt: json['updated_at'] != null ? DateTime.tryParse(json['updated_at'].toString()) : null, stopOrder: json['stop_order'] != null ? int.tryParse(json['stop_order'].toString()) : null, travelTimeMinutes: json['travel_time_minutes'] != null ? int.tryParse(json['travel_time_minutes'].toString()) : null, isPickupPoint: json['is_pickup_point'] == true, isDropoffPoint: json['is_dropoff_point'] == true, ); } Map toJson() { return { 'id': id, 'name': name, 'lat': lat, 'lng': lng, 'city': city, 'address': address, 'parent_id': parentId, 'side': side, 'stop_type': stopType, 'has_shelter': hasShelter, 'has_seating': hasSeating, 'is_accessible': isAccessible, 'created_at': createdAt?.toIso8601String(), 'updated_at': updatedAt?.toIso8601String(), 'stop_order': stopOrder, 'travel_time_minutes': travelTimeMinutes, 'is_pickup_point': isPickupPoint, 'is_dropoff_point': isDropoffPoint, }; } // Helper getters String get displayName => name; String get fullAddress { if (address != null && address!.isNotEmpty) { return city != null ? '$address, $city' : address!; } return city ?? 'Ubicación desconocida'; } String get stopTypeDisplay { switch (stopType) { case 'terminal': return 'Terminal'; case 'express_only': return 'Solo Express'; case 'regular': default: return 'Parada Regular'; } } List get amenities { List amenityList = []; if (hasShelter) amenityList.add('Refugio'); if (hasSeating) amenityList.add('Asientos'); if (isAccessible) amenityList.add('Accesible'); return amenityList; } String get amenitiesText { final amenityList = amenities; if (amenityList.isEmpty) return 'Sin servicios especiales'; return amenityList.join(', '); } bool get isTerminal => stopType == 'terminal'; bool get isExpressOnly => stopType == 'express_only'; String get travelTimeText { if (travelTimeMinutes != null && travelTimeMinutes! > 0) { return '${travelTimeMinutes} min'; } return 'N/A'; } BusStopModel copyWith({ String? id, String? name, double? lat, double? lng, String? city, String? address, String? parentId, String? side, String? stopType, bool? hasShelter, bool? hasSeating, bool? isAccessible, DateTime? createdAt, DateTime? updatedAt, int? stopOrder, int? travelTimeMinutes, bool? isPickupPoint, bool? isDropoffPoint, }) { return BusStopModel( id: id ?? this.id, name: name ?? this.name, lat: lat ?? this.lat, lng: lng ?? this.lng, city: city ?? this.city, address: address ?? this.address, parentId: parentId ?? this.parentId, side: side ?? this.side, stopType: stopType ?? this.stopType, hasShelter: hasShelter ?? this.hasShelter, hasSeating: hasSeating ?? this.hasSeating, isAccessible: isAccessible ?? this.isAccessible, createdAt: createdAt ?? this.createdAt, updatedAt: updatedAt ?? this.updatedAt, stopOrder: stopOrder ?? this.stopOrder, travelTimeMinutes: travelTimeMinutes ?? this.travelTimeMinutes, isPickupPoint: isPickupPoint ?? this.isPickupPoint, isDropoffPoint: isDropoffPoint ?? this.isDropoffPoint, ); } @override String toString() { return 'BusStopModel(id: $id, name: $name, city: $city, stopType: $stopType)'; } @override bool operator ==(Object other) { if (identical(this, other)) return true; return other is BusStopModel && other.id == id; } @override int get hashCode => id.hashCode; }