import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; import '../../../data/providers/aset_provider.dart'; import '../../../data/models/aset_model.dart'; import '../../../routes/app_routes.dart'; import '../../../data/models/pesanan_model.dart'; import '../../../data/models/satuan_waktu_model.dart'; import '../../../data/models/satuan_waktu_sewa_model.dart'; import '../../../data/providers/auth_provider.dart'; import '../../../data/providers/pesanan_provider.dart'; import '../../../services/navigation_service.dart'; import '../../../services/service_manager.dart'; import 'package:get_storage/get_storage.dart'; class SewaAsetController extends GetxController with GetSingleTickerProviderStateMixin { final AsetProvider _asetProvider = Get.find(); final AuthProvider authProvider = Get.find(); final PesananProvider pesananProvider = Get.put(PesananProvider()); final NavigationService navigationService = Get.find(); final box = GetStorage(); // Tab controller late TabController tabController; // Reactive tab index final currentTabIndex = 0.obs; // State variables final asets = [].obs; final filteredAsets = [].obs; // Paket-related variables final pakets = RxList([]); final filteredPakets = RxList([]); final isLoadingPakets = false.obs; final isLoading = true.obs; // Search controller final TextEditingController searchController = TextEditingController(); // Reactive variables final isOrdering = false.obs; final selectedAset = Rx(null); final selectedSatuanWaktuSewa = Rx(null); final selectedDurasi = 1.obs; final totalHarga = 0.obs; final selectedDate = DateTime.now().obs; final selectedTime = '08:00'.obs; final satuanWaktuDropdownItems = >[].obs; // Flag untuk menangani hot reload final hasInitialized = false.obs; @override void onInit() { super.onInit(); debugPrint('๐Ÿš€ SewaAsetController: onInit called'); // Initialize tab controller tabController = TabController(length: 2, vsync: this); // Listen for tab changes tabController.addListener(() { currentTabIndex.value = tabController.index; // Load packages data when switching to package tab for the first time if (currentTabIndex.value == 1 && pakets.isEmpty) { loadPakets(); } }); loadAsets(); searchController.addListener(() { if (currentTabIndex.value == 0) { filterAsets(searchController.text); } else { filterPakets(searchController.text); } }); hasInitialized.value = true; } @override void onReady() { super.onReady(); debugPrint('๐Ÿš€ SewaAsetController: onReady called'); // Set tab index from arguments (if any) after build Future.delayed(Duration.zero, () { final args = Get.arguments; if (args != null && args is Map && args['tab'] != null) { int initialTab = args['tab'] is int ? args['tab'] : int.tryParse(args['tab'].toString()) ?? 0; if (tabController.length > initialTab) { tabController.index = initialTab; } } }); } @override void onClose() { debugPrint('๐Ÿงน SewaAsetController: onClose called'); searchController.dispose(); tabController.dispose(); super.onClose(); } // Method untuk menangani hot reload void handleHotReload() { debugPrint('๐Ÿ”ฅ Hot reload detected in SewaAsetController'); if (!hasInitialized.value) { debugPrint('๐Ÿ”„ Reinitializing SewaAsetController after hot reload'); loadAsets(); if (currentTabIndex.value == 1) { loadPakets(); } hasInitialized.value = true; } } // Method untuk menangani tombol back void onBackPressed() { debugPrint('๐Ÿ”™ Back button pressed in SewaAsetView'); navigationService.backFromSewaAset(); } Future loadAsets() async { try { isLoading.value = true; final sewaAsets = await _asetProvider.getSewaAsets(); // Debug data satuan waktu sewa yang diterima debugPrint('===== DEBUG ASET & SATUAN WAKTU SEWA ====='); for (var aset in sewaAsets) { debugPrint('Aset: ${aset.nama} (ID: ${aset.id})'); if (aset.satuanWaktuSewa.isEmpty) { debugPrint(' - Tidak ada satuan waktu sewa yang terkait'); } else { debugPrint( ' - Memiliki ${aset.satuanWaktuSewa.length} satuan waktu sewa:', ); for (var sws in aset.satuanWaktuSewa) { debugPrint(' * ID: ${sws['id']}'); debugPrint(' Aset ID: ${sws['aset_id']}'); debugPrint(' Satuan Waktu ID: ${sws['satuan_waktu_id']}'); debugPrint(' Harga: ${sws['harga']}'); debugPrint(' Nama Satuan Waktu: ${sws['nama_satuan_waktu']}'); debugPrint(' -----'); } } debugPrint('====================================='); } asets.assignAll(sewaAsets); filteredAsets.assignAll(sewaAsets); // Tambahkan log info tentang jumlah aset yang berhasil dimuat debugPrint('Loaded ${sewaAsets.length} aset sewa successfully'); } catch (e) { debugPrint('Error loading asets: $e'); Get.snackbar( 'Error', 'Terjadi kesalahan saat memuat data aset', snackPosition: SnackPosition.BOTTOM, backgroundColor: Colors.red, colorText: Colors.white, ); } finally { isLoading.value = false; } } void filterAsets(String query) { if (query.isEmpty) { filteredAsets.assignAll(asets); } else { filteredAsets.assignAll( asets .where( (aset) => aset.nama.toLowerCase().contains(query.toLowerCase()), ) .toList(), ); } } void refreshAsets() { loadAsets(); } String formatPrice(dynamic price) { if (price == null) return 'Rp 0'; // Handle different types num numericPrice; if (price is int || price is double) { numericPrice = price; } else if (price is String) { numericPrice = double.tryParse(price) ?? 0; } else { return 'Rp 0'; } final formatter = NumberFormat.currency( locale: 'id', symbol: 'Rp ', decimalDigits: 0, ); return formatter.format(numericPrice); } void selectAset(AsetModel aset) { selectedAset.value = aset; // Reset related values selectedSatuanWaktuSewa.value = null; selectedDurasi.value = 1; totalHarga.value = 0; // Prepare dropdown items for satuan waktu sewa updateSatuanWaktuDropdown(); } void updateSatuanWaktuDropdown() { satuanWaktuDropdownItems.clear(); if (selectedAset.value != null && selectedAset.value!.satuanWaktuSewa.isNotEmpty) { for (var item in selectedAset.value!.satuanWaktuSewa) { final satuanWaktuSewa = SatuanWaktuSewaModel.fromJson(item); satuanWaktuDropdownItems.add( DropdownMenuItem( value: satuanWaktuSewa, child: Text( '${satuanWaktuSewa.namaSatuanWaktu ?? "Unknown"} - Rp${NumberFormat.decimalPattern('id').format(satuanWaktuSewa.harga)}', ), ), ); } } } void selectSatuanWaktu(SatuanWaktuSewaModel? satuanWaktuSewa) { selectedSatuanWaktuSewa.value = satuanWaktuSewa; calculateTotalPrice(); } void updateDurasi(int durasi) { if (durasi < 1) durasi = 1; selectedDurasi.value = durasi; calculateTotalPrice(); } void calculateTotalPrice() { if (selectedSatuanWaktuSewa.value != null) { totalHarga.value = selectedSatuanWaktuSewa.value!.harga * selectedDurasi.value; } else { totalHarga.value = 0; } } void pickDate(DateTime date) { selectedDate.value = date; } void pickTime(String time) { selectedTime.value = time; } // Helper method to show error snackbar void _showError(String message) { Get.snackbar( 'Error', message, snackPosition: SnackPosition.BOTTOM, backgroundColor: Colors.red, colorText: Colors.white, ); } // Method untuk melakukan pemesanan Future placeOrderAset() async { if (selectedAset.value == null) { _showError('Silakan pilih aset terlebih dahulu'); return; } if (selectedSatuanWaktuSewa.value == null) { _showError('Silakan pilih satuan waktu sewa'); return; } if (selectedDurasi.value <= 0) { _showError('Durasi sewa harus lebih dari 0'); return; } final userId = authProvider.getCurrentUserId(); if (userId == null) { _showError('Anda belum login, silakan login terlebih dahulu'); return; } try { final result = await _asetProvider.orderAset( userId: userId, asetId: selectedAset.value!.id, satuanWaktuSewaId: selectedSatuanWaktuSewa.value!.id, durasi: selectedDurasi.value, totalHarga: totalHarga.value, ); if (result) { Get.snackbar( 'Sukses', 'Pesanan berhasil dibuat', snackPosition: SnackPosition.BOTTOM, backgroundColor: Colors.green, colorText: Colors.white, ); resetSelections(); } else { _showError('Gagal membuat pesanan'); } } catch (e) { _showError('Terjadi kesalahan: $e'); } } // Method untuk reset pilihan setelah pemesanan berhasil void resetSelections() { selectedAset.value = null; selectedSatuanWaktuSewa.value = null; selectedDurasi.value = 1; totalHarga.value = 0; } // Load packages data from paket table Future loadPakets() async { try { isLoadingPakets.value = true; // Call the provider method to get paket data final paketData = await _asetProvider.getPakets(); // Debug paket data debugPrint('===== DEBUG PAKET & SATUAN WAKTU SEWA ====='); for (var paket in paketData) { debugPrint('Paket: ${paket['nama']} (ID: ${paket['id']})'); if (paket['satuanWaktuSewa'] == null || paket['satuanWaktuSewa'].isEmpty) { debugPrint(' - Tidak ada satuan waktu sewa yang terkait'); } else { debugPrint( ' - Memiliki ${paket['satuanWaktuSewa'].length} satuan waktu sewa:', ); for (var sws in paket['satuanWaktuSewa']) { debugPrint(' * ID: ${sws['id']}'); debugPrint(' Paket ID: ${sws['paket_id']}'); debugPrint(' Satuan Waktu ID: ${sws['satuan_waktu_id']}'); debugPrint(' Harga: ${sws['harga']}'); debugPrint(' Nama Satuan Waktu: ${sws['nama_satuan_waktu']}'); debugPrint(' -----'); } } debugPrint('====================================='); } pakets.assignAll(paketData); filteredPakets.assignAll(paketData); debugPrint('Loaded ${paketData.length} paket successfully'); } catch (e) { debugPrint('Error loading pakets: $e'); Get.snackbar( 'Error', 'Terjadi kesalahan saat memuat data paket', snackPosition: SnackPosition.BOTTOM, backgroundColor: Colors.red, colorText: Colors.white, ); } finally { isLoadingPakets.value = false; } } // Method to filter pakets based on search query void filterPakets(String query) { if (query.isEmpty) { filteredPakets.assignAll(pakets); } else { filteredPakets.assignAll( pakets .where( (paket) => paket['nama'].toString().toLowerCase().contains( query.toLowerCase(), ), ) .toList(), ); } } void refreshPakets() { loadPakets(); } // Method to load paket data Future loadPaketData() async { try { isLoadingPakets.value = true; final result = await _asetProvider.getPakets(); if (result != null) { pakets.clear(); filteredPakets.clear(); pakets.addAll(result); filteredPakets.addAll(result); } } catch (e) { debugPrint('Error loading pakets: $e'); Get.snackbar( 'Error', 'Gagal memuat data paket. Silakan coba lagi nanti.', snackPosition: SnackPosition.BOTTOM, backgroundColor: Colors.red, colorText: Colors.white, ); } finally { isLoadingPakets.value = false; } } // Method for placing an order for a paket Future placeOrderPaket({ required String paketId, required String satuanWaktuSewaId, required int durasi, required int totalHarga, }) async { debugPrint('===== PLACE ORDER PAKET ====='); debugPrint('paketId: $paketId'); debugPrint('satuanWaktuSewaId: $satuanWaktuSewaId'); debugPrint('durasi: $durasi'); debugPrint('totalHarga: $totalHarga'); final userId = authProvider.getCurrentUserId(); if (userId == null) { _showError('Anda belum login, silakan login terlebih dahulu'); return; } try { final result = await _asetProvider.orderPaket( userId: userId, paketId: paketId, satuanWaktuSewaId: satuanWaktuSewaId, durasi: durasi, totalHarga: totalHarga, ); if (result) { Get.snackbar( 'Sukses', 'Pesanan paket berhasil dibuat', snackPosition: SnackPosition.BOTTOM, backgroundColor: Colors.green, colorText: Colors.white, ); } else { _showError('Gagal membuat pesanan paket'); } } catch (e) { _showError('Terjadi kesalahan: $e'); } } }