import 'dart:convert'; import 'dart:developer' as developer; class PaketModel { final String id; final String nama; final String deskripsi; final double harga; final int kuantitas; final String status; List foto; List> satuanWaktuSewa; final DateTime createdAt; final DateTime updatedAt; String? foto_paket; // Main photo URL List? images; // List of photo URLs PaketModel({ required this.id, required this.nama, required this.deskripsi, required this.harga, required this.kuantitas, this.status = 'aktif', required List foto, required List> satuanWaktuSewa, this.foto_paket, List? images, required this.createdAt, required this.updatedAt, }) : foto = List.from(foto), satuanWaktuSewa = List.from(satuanWaktuSewa), images = images != null ? List.from(images) : []; // Add copyWith method for immutability patterns PaketModel copyWith({ String? id, String? nama, String? deskripsi, double? harga, int? kuantitas, String? status, List? foto, List>? satuanWaktuSewa, String? foto_paket, List? images, DateTime? createdAt, DateTime? updatedAt, }) { return PaketModel( id: id ?? this.id, nama: nama ?? this.nama, deskripsi: deskripsi ?? this.deskripsi, harga: harga ?? this.harga, kuantitas: kuantitas ?? this.kuantitas, status: status ?? this.status, foto: foto ?? List.from(this.foto), satuanWaktuSewa: satuanWaktuSewa ?? List.from(this.satuanWaktuSewa), foto_paket: foto_paket ?? this.foto_paket, images: images ?? (this.images != null ? List.from(this.images!) : null), createdAt: createdAt ?? this.createdAt, updatedAt: updatedAt ?? this.updatedAt, ); } // Alias for fromJson to maintain compatibility factory PaketModel.fromMap(Map json) => PaketModel.fromJson(json); factory PaketModel.fromJson(Map json) { // Handle different possible JSON structures final fotoList = []; // Check for different possible photo field names if (json['foto'] != null) { if (json['foto'] is String) { fotoList.add(json['foto']); } else if (json['foto'] is List) { fotoList.addAll((json['foto'] as List).whereType()); } } if (json['foto_paket'] != null) { if (json['foto_paket'] is String) { fotoList.add(json['foto_paket']); } else if (json['foto_paket'] is List) { fotoList.addAll((json['foto_paket'] as List).whereType()); } } // Handle satuan_waktu_sewa List> satuanWaktuList = []; if (json['satuan_waktu_sewa'] != null) { if (json['satuan_waktu_sewa'] is List) { satuanWaktuList = List>.from( json['satuan_waktu_sewa'].map((x) => x is Map ? Map.from(x) : {}) ); } else if (json['satuan_waktu_sewa'] is Map) { satuanWaktuList = [Map.from(json['satuan_waktu_sewa'])]; } } developer.log('📦 [PaketModel.fromJson] Raw status: ${json['status']} (type: ${json['status']?.runtimeType})'); final status = json['status']?.toString().toLowerCase() ?? 'aktif'; developer.log(' 🏷️ Processed status: $status'); return PaketModel( id: json['id']?.toString() ?? '', nama: json['nama']?.toString() ?? '', deskripsi: json['deskripsi']?.toString() ?? '', status: status, harga: (json['harga'] is num) ? (json['harga'] as num).toDouble() : 0.0, kuantitas: (json['kuantitas'] is num) ? (json['kuantitas'] as num).toInt() : 1, foto: fotoList, satuanWaktuSewa: satuanWaktuList, foto_paket: json['foto_paket']?.toString(), images: json['images'] != null ? List.from(json['images']) : null, createdAt: json['created_at'] != null ? DateTime.parse(json['created_at'].toString()) : DateTime.now(), updatedAt: json['updated_at'] != null ? DateTime.parse(json['updated_at'].toString()) : DateTime.now(), ); } // Convert to JSON Map toJson() => { 'id': id, 'nama': nama, 'deskripsi': deskripsi, 'harga': harga, 'kuantitas': kuantitas, 'foto': foto, 'foto_paket': foto_paket, 'images': images, 'satuan_waktu_sewa': satuanWaktuSewa, 'created_at': createdAt.toIso8601String(), 'updated_at': updatedAt.toIso8601String(), }; // Get the first photo URL or a placeholder String get firstPhotoUrl => foto.isNotEmpty ? foto.first : ''; // Get the formatted price String get formattedPrice => 'Rp${harga.toStringAsFixed(0).replaceAllMapped( RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]}.', )}'; // Check if the package is available bool get isAvailable => kuantitas > 0; // Get the first available time unit Map? get defaultTimeUnit => satuanWaktuSewa.isNotEmpty ? satuanWaktuSewa.first : null; // Get the price for a specific time unit double getPriceForTimeUnit(String timeUnitId) { try { final unit = satuanWaktuSewa.firstWhere( (unit) => unit['id'] == timeUnitId || unit['id'].toString() == timeUnitId, ); return (unit['harga'] as num?)?.toDouble() ?? 0.0; } catch (e) { return 0.0; } } }