import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import '../../../routes/app_pages.dart'; import '../../../widgets/numpad_nominal_widget.dart'; import '../../../widgets/numpad_pin_widget.dart'; import '../../../widgets/target_celengan_picker.dart'; class RegisterController extends GetxController { final namaController = TextEditingController(); final emailController = TextEditingController(); final passwordController = TextEditingController(); final targetCelenganController = TextEditingController(); final nominalTargetController = TextEditingController(); final pinController = TextEditingController(); final confirmPinController = TextEditingController(); final isPinVisible = false.obs; final isConfirmPinVisible = false.obs; final isLoading = false.obs; String _activeField = ''; final _auth = FirebaseAuth.instance; final _firestore = FirebaseFirestore.instance; @override void onClose() { namaController.dispose(); emailController.dispose(); passwordController.dispose(); targetCelenganController.dispose(); nominalTargetController.dispose(); pinController.dispose(); confirmPinController.dispose(); super.onClose(); } void togglePinVisibility() => isPinVisible.value = !isPinVisible.value; void toggleConfirmPinVisibility() => isConfirmPinVisible.value = !isConfirmPinVisible.value; void showTargetPicker(BuildContext context) { TargetCelenganPicker.show( context, selected: targetCelenganController.text.isEmpty ? null : targetCelenganController.text, onSelected: (label) => targetCelenganController.text = label, ); } void showNumpad(BuildContext context, String field) { _activeField = field; final activeCtrl = _getController(field); final isPinField = field == 'pin' || field == 'confirmPin'; if (isPinField) { NumpadPinInputWidget.show( context, controller: activeCtrl, onKey: _onNumpadKey, onSimpan: () => Get.back(), title: field == 'pin' ? 'Masukkan PIN' : 'Ulangi PIN', ); } else { NumpadNominalWidget.show( context, controller: activeCtrl, onKey: _onNumpadKey, onSimpan: () => Get.back(), ); } } TextEditingController _getController(String field) { if (field == 'pin') return pinController; if (field == 'confirmPin') return confirmPinController; return nominalTargetController; } void _onNumpadKey(String key) { final ctrl = _getController(_activeField); final isPinField = _activeField == 'pin' || _activeField == 'confirmPin'; if (key == 'del') { if (ctrl.text.isNotEmpty) ctrl.text = ctrl.text.substring(0, ctrl.text.length - 1); } else { if (isPinField && ctrl.text.length >= 6) return; ctrl.text += key; } } /// Parse nominal dari string seperti "Rp 2.500.000" → 2500000 int _parseNominal(String raw) { final cleaned = raw.replaceAll(RegExp(r'[^0-9]'), ''); return int.tryParse(cleaned) ?? 0; } Future simpan() async { if (namaController.text.isEmpty || emailController.text.isEmpty || passwordController.text.isEmpty || targetCelenganController.text.isEmpty || nominalTargetController.text.isEmpty || pinController.text.isEmpty || confirmPinController.text.isEmpty) { Get.snackbar( 'Perhatian', 'Semua field harus diisi!', snackPosition: SnackPosition.TOP, backgroundColor: Colors.red.shade100, ); return; } if (pinController.text != confirmPinController.text) { Get.snackbar( 'Perhatian', 'PIN tidak cocok!', snackPosition: SnackPosition.TOP, backgroundColor: Colors.red.shade100, ); return; } try { isLoading.value = true; // 1. Buat akun di Firebase Auth final credential = await _auth.createUserWithEmailAndPassword( email: emailController.text.trim(), password: passwordController.text.trim(), ); final uid = credential.user!.uid; final now = FieldValue.serverTimestamp(); // 2. Simpan ke collection 'users' await _firestore.collection('users').doc(uid).set({ 'email': emailController.text.trim(), 'password': 'hashed_password', // Hanya placeholder, auth sudah handle 'createdAt': now, }); // 3. Simpan ke collection 'profil' await _firestore.collection('profil').doc(uid).set({ 'userId': uid, 'nama': namaController.text.trim(), 'target': targetCelenganController.text.trim(), 'targetNominal': _parseNominal(nominalTargetController.text), 'pin': pinController.text, 'totalSaldo': 0, 'createdAt': now, }); Get.snackbar( 'Berhasil', 'Akun berhasil dibuat!', snackPosition: SnackPosition.TOP, backgroundColor: Colors.green.shade100, ); Get.offAllNamed(Routes.LOGIN); } on FirebaseAuthException catch (e) { String message = 'Registrasi gagal.'; if (e.code == 'email-already-in-use') { message = 'Email sudah digunakan.'; } else if (e.code == 'weak-password') { message = 'Password terlalu lemah (min. 6 karakter).'; } else if (e.code == 'invalid-email') { message = 'Format email tidak valid.'; } Get.snackbar( 'Registrasi Gagal', message, snackPosition: SnackPosition.TOP, backgroundColor: Colors.red.shade100, ); } finally { isLoading.value = false; } } }