import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:firebase_database/firebase_database.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'wait_for_rfid_screen.dart'; class StartActivityScreen extends StatefulWidget { const StartActivityScreen({super.key}); @override State createState() => _StartActivityScreenState(); } class _StartActivityScreenState extends State { String? _selectedType; final _lapController = TextEditingController(); // Untuk input jumlah putaran final _calculatedDistanceController = TextEditingController(); // Untuk menampilkan jarak total String _unit = 'KM'; // Variabel untuk menghitung waktu setiap lap DateTime lapStartTime = DateTime.now(); DateTime lapEndTime = DateTime.now(); double lapTimeInSeconds = 0; double speed = 0.0; // Kecepatan dalam m/s void _showError(String message) { showDialog( context: context, builder: (context) => AlertDialog( title: const Text("Error", style: TextStyle(color: Colors.red)), content: Text(message), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text("OK", style: TextStyle(color: Colors.blue)), ) ], ), ); } // Fungsi untuk memulai timer saat lap dimulai void startLapTimer() { lapStartTime = DateTime.now(); // Mulai timer dengan DateTime } // Fungsi untuk menghentikan timer saat lap selesai dan menghitung kecepatan void endLapTimer(double lapDistance, String uidTag) { lapEndTime = DateTime.now(); // Hentikan timer dengan DateTime lapTimeInSeconds = lapEndTime.difference(lapStartTime).inSeconds.toDouble(); // Hitung waktu dalam detik speed = lapDistance / lapTimeInSeconds; // Hitung kecepatan dalam meter per detik // Simpan kecepatan per lap di Firebase saveSpeedToFirebase(uidTag, speed); } // Fungsi untuk menyimpan kecepatan per lap ke Firebase (RTDB) void saveSpeedToFirebase(String uidTag, double speed) { final user = FirebaseAuth.instance.currentUser; if (user == null) { print("User tidak ditemukan"); return; } try { final db = FirebaseDatabase.instanceFor( app: Firebase.app(), databaseURL: "https://ta-running-default-rtdb.asia-southeast1.firebasedatabase.app", ); final ref = db.ref("activities/$uidTag"); // Simpan kecepatan per lap ref.child('kecepatan_lap').push().set({ 'speed': speed, 'timestamp': DateTime.now().toIso8601String(), }); print("Kecepatan lap $uidTag berhasil disimpan: $speed m/s"); } catch (e) { print("❌ Gagal menyimpan kecepatan lap: $e"); } } // Fungsi untuk mengupdate jarak dan kecepatan setiap lap void _updateDistance() { final laps = int.tryParse(_lapController.text); if (laps != null && laps >= 3) { final totalDistance = laps * 400; // 400 meter per putaran _calculatedDistanceController.text = totalDistance.toString(); } else if (laps != null && laps < 3) { _calculatedDistanceController.text = ''; _showError("Jumlah putaran minimal adalah 3 (1200m)."); } else { _calculatedDistanceController.text = ''; } } // Fungsi untuk submit aktivitas ke Firebase void _submit() { if (_selectedType == 'Lintasan') { final laps = int.tryParse(_lapController.text); if (laps == null || laps < 3) { _showError("Masukkan jumlah putaran yang valid (minimal 3)."); return; } final totalDistance = laps * 400; // 400 meter per putaran _calculatedDistanceController.text = totalDistance.toString(); submitToFirebase( jarak: totalDistance.toDouble(), jenisAktivitas: 'lintasan', satuan: 'M', putaran: laps, ); } else if (_selectedType == 'Non-Lintasan') { final jarak = double.tryParse(_lapController.text); if (jarak == null || jarak <= 0) { _showError("Masukkan jarak yang valid."); return; } submitToFirebase( jarak: jarak, jenisAktivitas: 'non-lintasan', satuan: _unit, ); } else { _showError("Pilih jenis aktivitas terlebih dahulu."); } } // Fungsi untuk submit data ke Firebase void submitToFirebase({ required double jarak, required String jenisAktivitas, required String satuan, int? putaran, }) async { final user = FirebaseAuth.instance.currentUser; if (user == null) { print("User tidak ditemukan"); return; } try { final userDoc = await FirebaseFirestore.instance .collection("users") .doc(user.uid) .get(); final userData = userDoc.data(); if (userData == null || !userData.containsKey("idGelang")) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("Silakan daftarkan gelang RFID terlebih dahulu.")), ); return; } final uidTag = userData["idGelang"]; final db = FirebaseDatabase.instanceFor( app: Firebase.app(), databaseURL: "https://ta-running-default-rtdb.asia-southeast1.firebasedatabase.app", ); final ref = db.ref("activities/$uidTag"); await ref.set({ 'uid_apk': user.uid, 'jarak': jarak, 'satuan': satuan, 'putaran': putaran, 'type': jenisAktivitas, 'status': 'waiting_for_rfid', 'timestamp': DateTime.now().toIso8601String(), }); print("✅ Data aktivitas dikirim ke Firebase dengan UID tag: $uidTag"); Navigator.pushReplacement( context, MaterialPageRoute( builder: (_) => WaitForRfidScreen(uidTag: uidTag), ), ); } catch (e) { print("❌ Gagal mengirim aktivitas: $e"); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("Gagal mengirim aktivitas: $e")), ); } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: PreferredSize( preferredSize: const Size.fromHeight(80), child: Container( decoration: const BoxDecoration( color: Colors.blue, borderRadius: BorderRadius.only( bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20), ), ), padding: const EdgeInsets.only(top: 40, left: 16, right: 16), child: Row( children: [ if (_selectedType != null) IconButton( icon: const Icon(Icons.arrow_back, color: Colors.white), onPressed: () => setState(() => _selectedType = null), ) else const SizedBox(width: 48), Expanded( child: Center( child: Text( "Start Activity", style: const TextStyle( color: Colors.white, fontSize: 28, fontWeight: FontWeight.bold, ), ), ), ), const SizedBox(width: 48), ], ), ), ), body: SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 32), child: _selectedType == null ? Column( children: [ const SizedBox(height: 70), Image.asset( 'images/run.png', width: 100, height: 100, ), const SizedBox(height: 80), const Text( 'Pilih Jenis Aktivitas', style: TextStyle(fontSize: 28, fontWeight: FontWeight.w800), textAlign: TextAlign.center, ), const SizedBox(height: 28), Row( children: [ Expanded( child: ElevatedButton( onPressed: () => setState(() => _selectedType = 'Lintasan'), style: ElevatedButton.styleFrom( backgroundColor: _selectedType == 'Lintasan' ? Colors.blueAccent : Colors.white, side: const BorderSide(color: Colors.blueAccent), foregroundColor: _selectedType == 'Lintasan' ? Colors.white : Colors.blueAccent, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), padding: const EdgeInsets.symmetric(vertical: 14), ), child: const Text('LINTASAN'), ), ), const SizedBox(width: 12), Expanded( child: ElevatedButton( onPressed: () => setState(() => _selectedType = 'Non-Lintasan'), style: ElevatedButton.styleFrom( backgroundColor: _selectedType == 'Non-Lintasan' ? Colors.blueAccent : Colors.white, side: const BorderSide(color: Colors.blueAccent), foregroundColor: _selectedType == 'Non-Lintasan' ? Colors.white : Colors.blueAccent, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), padding: const EdgeInsets.symmetric(vertical: 14), ), child: const Text('NON-LINTASAN'), ), ), ], ), ], ) : Column( children: [ const SizedBox(height: 70), Image.asset( 'images/run.png', width: 100, height: 100, fit: BoxFit.contain, ), const SizedBox(height: 80), Text( _selectedType!, style: const TextStyle(fontSize: 28, fontWeight: FontWeight.w800), ), const SizedBox(height: 20), if (_selectedType == 'Lintasan') ...[ TextField( controller: _lapController, keyboardType: TextInputType.number, decoration: const InputDecoration( labelText: 'Jumlah Putaran (400M/Putaran)', border: OutlineInputBorder(), ), onChanged: (text) { _updateDistance(); // Update jarak total setiap kali jumlah putaran diubah }, ), const SizedBox(height: 12), TextField( controller: _calculatedDistanceController, enabled: false, // Disable editing decoration: const InputDecoration( labelText: 'Jarak Total (M)', border: OutlineInputBorder(), ), ), ] else ...[ Row( children: [ Expanded( child: TextField( controller: _lapController, // Menggunakan lapController untuk Non-Lintasan keyboardType: TextInputType.number, decoration: const InputDecoration( labelText: 'Jarak', border: OutlineInputBorder(), ), ), ), const SizedBox(width: 12), DropdownButton( value: _unit, items: const [ DropdownMenuItem(value: 'KM', child: Text('KM')), DropdownMenuItem(value: 'M', child: Text('M')), ], onChanged: (value) => setState(() => _unit = value!), ), ], ), ], const SizedBox(height: 20), ElevatedButton( onPressed: _submit, style: ElevatedButton.styleFrom( backgroundColor: Colors.blueAccent, padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), ), child: const Text( 'Submit dan Scan RFID', style: TextStyle(fontSize: 16, color: Colors.white), ), ), ], ), ), ); } }