import 'dart:ui'; import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; import 'package:flutter/foundation.dart'; // import kIsWeb import 'package:http/http.dart' as http; import '../utils/session_manager.dart'; import '../utils/api_config.dart'; import '../main.dart'; // import themeNotifier class ProfileScreen extends StatefulWidget { const ProfileScreen({super.key}); @override State createState() => _ProfileScreenState(); } class _ProfileScreenState extends State { bool _isUploading = false; // Fungsi untuk mengunggah foto profil Future _pickAndUploadPhoto() async { final picker = ImagePicker(); final pickedFile = await picker.pickImage(source: ImageSource.gallery, imageQuality: 70); if (pickedFile != null && mounted) { setState(() => _isUploading = true); try { var request = http.MultipartRequest('POST', Uri.parse('${ApiConfig.baseUrl}/upload_photo.php')); request.fields['id_users'] = SessionManager.userId.toString(); if (kIsWeb) { // Web needs readAsBytes since path is just a blob URL final bytes = await pickedFile.readAsBytes(); request.files.add(http.MultipartFile.fromBytes( 'photo', bytes, filename: pickedFile.name, )); } else { // Android/Mobile can use path request.files.add(await http.MultipartFile.fromPath('photo', pickedFile.path)); } var response = await request.send(); if (response.statusCode == 200) { var responseData = await response.stream.bytesToString(); var data = jsonDecode(responseData); // Check for 'status' instead of 'success' to match backend if (data['status'] == 'success') { setState(() { SessionManager.userPhoto = data['photo_url']; // Save url photo }); if(mounted) ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Foto profil diunggah!'))); } else { if(mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Gagal: ${data['message']}'))); } } } catch (e) { if(mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Gagal unggah foto: $e'))); } setState(() => _isUploading = false); } } // Fungsi Hapus Akun void _deleteAccount() { showDialog( context: context, builder: (BuildContext ctx) { return AlertDialog( title: const Text("Hapus Akun Permanen", style: TextStyle(color: Colors.red)), content: const Text("Apakah Anda yakin ingin menghapus akun ini secara permanen? Data yang dihapus tidak dapat dipulihkan."), actions: [ TextButton( onPressed: () => Navigator.pop(ctx), child: const Text("Batal", style: TextStyle(color: Colors.grey)), ), ElevatedButton( onPressed: () async { Navigator.pop(ctx); // Tutup dialog konfirmasi try { final response = await http.post( Uri.parse('${ApiConfig.baseUrl}/delete_account.php'), body: {'id_users': SessionManager.userId.toString()}, ); final data = jsonDecode(response.body); if (data['status'] == 'success' && mounted) { // Kosongkan sesi lokal SessionManager.userId = null; SessionManager.userName = null; SessionManager.userEmail = null; SessionManager.userPhoto = null; // Tampilkan pop-up keberhasilan showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), title: Column( children: [ Icon(Icons.check_circle_outline, color: Colors.greenAccent[400], size: 70), const SizedBox(height: 16), const Text("Akun Berhasil Dihapus", style: TextStyle(fontWeight: FontWeight.bold)), ], ), content: const Text( "Akun Anda telah dihapus secara permanen.", textAlign: TextAlign.center, style: TextStyle(fontSize: 15), ), ); }, ); // Berikan jeda 2.5 detik agar user sempat membaca popup await Future.delayed(const Duration(milliseconds: 2500)); if (mounted) { Navigator.pushNamedAndRemoveUntil(context, '/welcome', (route) => false); } } else { if(mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Gagal menghapus: ${data['message']}'))); } } catch(e) { if(mounted) ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Terjadi kesalahan koneksi saat menghapus akun'))); } }, style: ElevatedButton.styleFrom(backgroundColor: Colors.redAccent), child: const Text("Hapus", style: TextStyle(color: Colors.white)), ), ], ); } ); } // Fungsi untuk dummy dialog pusat bantuan void _showInfoDialog(String title, String content) { showDialog( context: context, builder: (ctx) => AlertDialog( title: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)), content: Text(content), actions: [ TextButton(onPressed: () => Navigator.pop(ctx), child: const Text("Tutup")), ], ) ); } @override Widget build(BuildContext context) { final isDark = Theme.of(context).brightness == Brightness.dark; return Scaffold( backgroundColor: Theme.of(context).scaffoldBackgroundColor, body: SingleChildScrollView( child: Column( children: [ // --- KARTU HEADER PROFIL DENGAN GRADIENT --- Container( width: double.infinity, padding: const EdgeInsets.only(top: 70, left: 24, right: 24, bottom: 40), decoration: const BoxDecoration( gradient: LinearGradient( colors: [Color(0xFF2196F3), Color(0xFF00BCD4)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.only( bottomLeft: Radius.circular(30), bottomRight: Radius.circular(30), ), ), child: Row( children: [ // Avatar dengan GestureDetector untuk Edit Photo GestureDetector( onTap: _isUploading ? null : _pickAndUploadPhoto, child: Container( padding: const EdgeInsets.all(4), decoration: const BoxDecoration( color: Colors.white, shape: BoxShape.circle, ), child: Stack( alignment: Alignment.center, children: [ CircleAvatar( radius: 38, backgroundColor: Colors.blueAccent, backgroundImage: (SessionManager.userPhoto != null && SessionManager.userPhoto!.isNotEmpty) ? NetworkImage("${ApiConfig.baseUrl}/${SessionManager.userPhoto}?t=${DateTime.now().millisecondsSinceEpoch}") : null, child: (SessionManager.userPhoto == null || SessionManager.userPhoto!.isEmpty) ? const Icon(Icons.person, size: 45, color: Colors.white) : null, ), if (_isUploading) const CircularProgressIndicator(color: Colors.white) else Positioned( bottom: 0, right: 0, child: Container( padding: const EdgeInsets.all(4), decoration: const BoxDecoration(color: Colors.black54, shape: BoxShape.circle), child: const Icon(Icons.camera_alt, color: Colors.white, size: 14), ), ) ], ), ), ), const SizedBox(width: 20), // Info nama dan email Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( SessionManager.userName ?? "Pengguna", style: const TextStyle( fontSize: 22, fontWeight: FontWeight.bold, color: Colors.white, ), ), const SizedBox(height: 4), Text( SessionManager.userEmail ?? "Tidak ada data", style: const TextStyle( color: Colors.white70, fontSize: 14, ), ), ], ), ), ], ), ), // --- KONTEN MENU PROFIL --- Padding( padding: const EdgeInsets.all(24.0), child: Column( children: [ // --- BAGIAN PENGATURAN AKUN --- _buildSectionHeader("Akun", isDark), _buildGlassMenuTile(Icons.person_outline, "Edit Profil", () async { final updated = await Navigator.pushNamed(context, '/edit_profile'); // Jika data kembali bernilai true, refresh halaman profil untuk menampilkan nama baru if (updated == true) { setState(() {}); } }, isDark), // Dark Mode Switch ditaruh di Akun _buildGlassMenuTile( themeNotifier.value == ThemeMode.dark ? Icons.dark_mode : Icons.light_mode, "Mode Gelap", () { setState(() { if(themeNotifier.value == ThemeMode.dark) { themeNotifier.value = ThemeMode.light; } else { themeNotifier.value = ThemeMode.dark; } }); }, isDark, trailingWidget: Switch( value: themeNotifier.value == ThemeMode.dark, onChanged: (val) { setState(() { themeNotifier.value = val ? ThemeMode.dark : ThemeMode.light; }); }, activeColor: Colors.blueAccent, ), ), const SizedBox(height: 24), // --- BAGIAN DUKUNGAN & LAINNYA --- _buildSectionHeader("Dukungan & Lainnya", isDark), _buildGlassMenuTile(Icons.help_outline, "Pusat Bantuan", () => _showInfoDialog("Pusat Bantuan", "Jika Anda memiliki kendala teknis atau saran perbaikan, hubungi tim kami di cs@smartcycling.com atau hubungi layanan Hotline bebas pulsa kami 1500-099."), isDark), _buildGlassMenuTile(Icons.info_outline, "Tentang Aplikasi", () => _showInfoDialog("Tentang Aplikasi", "Smart Cycling App Versi 1.0.\nDikembangkan secara khusus untuk memberikan rekomendasi rute bagi pesepeda secara efisien."), isDark), _buildGlassMenuTile(Icons.privacy_tip_outlined, "Kebijakan Privasi", () => _showInfoDialog("Kebijakan Privasi", "Informasi lokasi dan preferensi rute Anda tersimpan dengan aman hanya pada sesi aktif. Kami tidak memperjualbelikan rekam jejak pengguna."), isDark), const SizedBox(height: 32), // --- FITUR HAPUS AKUN & KELUAR --- _buildGlassMenuTile( Icons.delete_forever, "Hapus Akun", _deleteAccount, isDark, iconColor: Colors.orangeAccent, textColor: Colors.orangeAccent, showChevron: false, ), _buildGlassMenuTile( Icons.logout, "Keluar", () { // Tampilkan pop-up konfirmasi showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: const Text("Konfirmasi Keluar", style: TextStyle(fontWeight: FontWeight.bold, color: Colors.red)), content: const Text("Apakah anda yakin ingin keluar?"), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), // Tutup dialog child: const Text("Batal", style: TextStyle(color: Colors.grey, fontWeight: FontWeight.bold)), ), ElevatedButton( onPressed: () { Navigator.of(context).pop(); // Tutup dialog // Kosongkan sesi lokal SessionManager.userId = null; SessionManager.userName = null; SessionManager.userEmail = null; SessionManager.userPhoto = null; Navigator.pushNamedAndRemoveUntil(context, '/welcome', (route) => false); // Arahkan ke welcome & bersihkan stack }, style: ElevatedButton.styleFrom( backgroundColor: Colors.redAccent, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), ), child: const Text("Keluar", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), ), ], ); }, ); }, isDark, iconColor: Colors.redAccent, textColor: Colors.redAccent, showChevron: false, // Hilangkan panah khusus untuk tombol keluar ), const SizedBox(height: 24), ], ), ), ], ), ), ); } // --- HELPER WIDGETS --- Widget _buildSectionHeader(String title, bool isDark) { return Padding( padding: const EdgeInsets.only(left: 16.0, bottom: 8.0, top: 4.0), child: Align( alignment: Alignment.centerLeft, child: Text( title, style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: isDark ? Colors.white70 : Colors.black87, ), ), ), ); } Widget _buildGlassMenuTile(IconData icon, String title, VoidCallback onTap, bool isDark, {Color? iconColor, Color? textColor, bool showChevron = true, Widget? trailingWidget}) { Color defaultTxColor = isDark ? Colors.white : Colors.black87; Color defaultIcColor = isDark ? Colors.white70 : Colors.black54; return Container( margin: const EdgeInsets.only(bottom: 12), decoration: BoxDecoration( color: isDark ? Colors.white.withOpacity(0.1) : Colors.white.withOpacity(0.55), // Transparansi efek kaca yang disesuaikan tema borderRadius: BorderRadius.circular(15), border: Border.all(color: isDark ? Colors.white.withOpacity(0.2) : Colors.white.withOpacity(0.9), width: 1.5), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.02), blurRadius: 10, spreadRadius: 1, offset: const Offset(0, 4), ), ], ), child: ClipRRect( borderRadius: BorderRadius.circular(15), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), // Fitur blur khas glassmorphism child: ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 4.0), leading: Icon(icon, color: iconColor ?? defaultIcColor, size: 26), title: Text( title, style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: textColor ?? defaultTxColor), ), trailing: trailingWidget ?? (showChevron ? Icon(Icons.chevron_right, color: isDark ? Colors.white38 : Colors.black38, size: 20) : null), onTap: onTap, ), ), ), ); } }