import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:intl/intl.dart';
import 'detail_hasil_screen.dart';
import 'all_activity_screen.dart';

class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  Future<String> getUsername() async {
    final user = FirebaseAuth.instance.currentUser;
    if (user == null) return '';
    final doc = await FirebaseFirestore.instance.collection('users').doc(user.uid).get();
    return doc.data()?['username'] ?? '';
  }

  Future<Map<String, double>> fetchRunningData() async {
    final user = FirebaseAuth.instance.currentUser;
    if (user == null) return {};

    final now = DateTime.now();
    final startOfWeek = DateTime(now.year, now.month, now.day - (now.weekday - 1));
    final endOfWeek = startOfWeek.add(const Duration(days: 7)).subtract(const Duration(seconds: 1));

    final snapshot = await FirebaseFirestore.instance.collection('activities').get();
    final Map<String, double> distancePerDay = {};

    for (var doc in snapshot.docs) {
      final data = doc.data()['data'];
      if (data == null || data['userId'] != user.uid) continue;

      final timestamp = (data['timestamp'] as Timestamp?)?.toDate();
      if (timestamp == null || timestamp.isBefore(startOfWeek) || timestamp.isAfter(endOfWeek)) continue;

      final day = DateFormat('EEEE', 'id_ID').format(timestamp);
      final jarak = (data['jarak'] ?? 0).toDouble();
      final satuan = data['satuan'] ?? 'M';
      final jarakKm = satuan == 'M' ? jarak / 1000.0 : jarak;

      distancePerDay[day] = (distancePerDay[day] ?? 0) + jarakKm;
    }

    const sortedDays = ['Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu', 'Minggu'];
    for (var dayName in sortedDays) {
      distancePerDay.putIfAbsent(dayName, () => 0.0);
    }

    return distancePerDay;
  }

  Future<List<Map<String, dynamic>>> fetchRingkasanData() async {
    final user = FirebaseAuth.instance.currentUser;
    if (user == null) return [];

    final snapshot = await FirebaseFirestore.instance.collection('activities').get();
    final List<Map<String, dynamic>> result = [];

    for (var doc in snapshot.docs) {
      final data = doc.data()['data']; // penting!
      if (data == null || data['userId'] != user.uid) continue;
      result.add({
        ...data,
        'docId': doc.id, // tambahkan docId untuk referensi penghapusan nanti
      });
    }

    result.sort((a, b) {
      final aTime = (a['timestamp'] as Timestamp?)?.toDate() ?? DateTime(2000);
      final bTime = (b['timestamp'] as Timestamp?)?.toDate() ?? DateTime(2000);
      return bTime.compareTo(aTime);
    });

    return result;
  }

  String getGreeting() {
    final hour = DateTime.now().hour;
    if (hour >= 6 && hour <= 10) {
      return 'Selamat Pagi';
    } else if (hour >= 11 && hour <= 14) {
      return 'Selamat Siang';
    } else if (hour >= 15 && hour <= 17) {
      return 'Selamat Sore';
    } else {
      return 'Selamat Malam';
    }
  }

  DateTime? parseTimestamp(dynamic raw) {
    if (raw is Timestamp) {
      return raw.toDate();
    } else if (raw is DateTime) {
      return raw;
    } else if (raw is String) {
      return DateTime.tryParse(raw);
    } else if (raw is int) {
      return DateTime.fromMillisecondsSinceEpoch(raw);
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: PreferredSize(
        preferredSize: const Size.fromHeight(80),
        child: FutureBuilder(
          future: getUsername(),
          builder: (context, snapshot) {
            final greeting = getGreeting();
            final username = snapshot.data ?? '...';

            return 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: 20, right: 20, bottom: 20),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Text(
                    '$greeting, $username',
                    style: const TextStyle(
                      color: Colors.white,
                      fontSize: 20,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  Image.asset(
                    'images/run.png',
                    height: 55,
                    width: 55,
                  ),
                ],
              ),
            );
          },
        ),
      ),
      body: RefreshIndicator(
        onRefresh: () async {
          // Memanggil kembali data setelah pull-to-refresh
          fetchRunningData();
          fetchRingkasanData();
        },
        child: Padding(
          padding: const EdgeInsets.only(top: 0.0, bottom: 0.0, right: 14.0, left: 14.0),
          child: FutureBuilder(
            future: Future.wait([fetchRunningData(), fetchRingkasanData(), getUsername()]),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting) {
                return const Center(child: CircularProgressIndicator());
              }

              final runningData = snapshot.data?[0] as Map<String, double>? ?? {};
              final ringkasanData = snapshot.data?[1] as List<Map<String, dynamic>>? ?? [];

              final sortedDays = ['Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu', 'Minggu'];
              final values = sortedDays.map((day) => runningData[day] ?? 0.0).toList();
              final totalMinggu = values.fold(0.0, (a, b) => a + b);
              int totalDurasiDetik = 0;
              final now = DateTime.now();
              final startOfWeek = DateTime(now.year, now.month, now.day - (now.weekday - 1));
              final endOfWeek = startOfWeek.add(const Duration(days: 7)).subtract(const Duration(seconds: 1));

              for (var data in ringkasanData) {
                final timestamp = parseTimestamp(data['timestamp']);
                if (timestamp == null) continue;
                if (timestamp.isBefore(startOfWeek) || timestamp.isAfter(endOfWeek)) continue;

                totalDurasiDetik += (((data['duration'] ?? data['durasi'] ?? 0) as num).toInt() ~/ 1000);
              }

              String formatDurasi(int totalSeconds) {
                final jam = totalSeconds ~/ 3600;
                final menit = (totalSeconds % 3600) ~/ 60;
                final detik = totalSeconds % 60;
                return '${jam}j ${menit}m ${detik}d';
              }

              final totalDurasiFormatted = formatDurasi(totalDurasiDetik);

              final maxValue = values.reduce((a, b) => a > b ? a : b);
              final highestDay = sortedDays[values.indexOf(maxValue)];

              return SingleChildScrollView(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        const Text(
                          'Minggu ini',
                          style: TextStyle(
                            fontSize: 22,
                            fontWeight: FontWeight.w700,
                          ),
                        ),
                        TextButton(
                          onPressed: () {
                            Navigator.push(
                              context,
                              MaterialPageRoute(builder: (_) => const AllActivityScreen()),
                            );
                          },
                          child: const Text(
                            'View all weeks',
                            style: TextStyle(color: Colors.blue),
                          ),
                        ),
                      ],
                    ),
                    const SizedBox(height: 1),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: [
                        Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            const Text(
                              'Jarak',
                              style: TextStyle(fontSize: 12, fontWeight: FontWeight.normal),
                            ),
                            Text(
                              '${totalMinggu.toStringAsFixed(2)} km',
                              style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                            ),
                          ],
                        ),
                        const SizedBox(width: 20),
                        Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            const Text(
                              'Waktu',
                              style: TextStyle(fontSize: 12, fontWeight: FontWeight.normal),
                            ),
                            Text(
                              totalDurasiFormatted,
                              style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                            ),
                          ],
                        ),
                      ],
                    ),
                    const SizedBox(height: 20),
                    SizedBox(
                      height: 170,
                      child: Padding(
                        padding: const EdgeInsets.only(left: 5.0, right: 6.0),
                        child: LineChart(
                          LineChartData(
                            minY: 0.0,
                            maxY: (values.isEmpty ? 5.0 : values.reduce((a, b) => a > b ? a : b)),
                            gridData: FlGridData(
                              show: true,
                              drawVerticalLine: true,
                              drawHorizontalLine: false,
                              verticalInterval: 1,
                              getDrawingVerticalLine: (value) {
                                return FlLine(
                                  color: Colors.blue.withOpacity(0.2),
                                  strokeWidth: 1,
                                );
                              },
                            ),
                            extraLinesData: ExtraLinesData(
                              verticalLines: [
                                VerticalLine(
                                  x: 0,
                                  color: Colors.blue.withOpacity(0.2),
                                  strokeWidth: 1,
                                ),
                                VerticalLine(
                                  x: (sortedDays.length - 1).toDouble(),
                                  color: Colors.blue.withOpacity(0.2),
                                  strokeWidth: 1,
                                ),
                              ],
                            ),
                            titlesData: FlTitlesData(
                              bottomTitles: AxisTitles(
                                sideTitles: SideTitles(
                                  showTitles: true,
                                  interval: 1,
                                  getTitlesWidget: (value, meta) {
                                    int index = value.toInt();
                                    if (index < 0 || index >= sortedDays.length) {
                                      return const SizedBox.shrink();
                                    }
                                    EdgeInsets padding = EdgeInsets.zero;
                                    if (index == 0) {
                                      padding = const EdgeInsets.only(left: 12);
                                    } else if (index == sortedDays.length - 1) {
                                      padding = const EdgeInsets.only(right: 12);
                                    }
                                    return Padding(
                                      padding: padding.add(const EdgeInsets.only(top: 4)), // tambah jarak dari grafik ke teks
                                      child: Text(
                                        sortedDays[index].substring(0, 3),
                                        style: const TextStyle(fontSize: 10),
                                      ),
                                    );
                                  },
                                ),
                              ),
                              leftTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
                              rightTitles: AxisTitles(
                                sideTitles: SideTitles(
                                  showTitles: true,
                                  reservedSize: 35,
                                  getTitlesWidget: (value, _) {
                                    if (value == 0.0 || value == maxValue || value == (maxValue + 1)) {
                                      return Padding(
                                        padding: const EdgeInsets.only(left: 8),
                                        child: Text('${value.toStringAsFixed(1)} KM', style: const TextStyle(fontSize: 10)),
                                      );
                                    }
                                    return const SizedBox.shrink();
                                  },
                                ),
                              ),
                              topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
                            ),
                            borderData: FlBorderData(show: false),
                            lineBarsData: [
                              LineChartBarData(
                                spots: List.generate(values.length, (i) => FlSpot(i.toDouble(), values[i])),
                                isCurved: false,
                                barWidth: 3,
                                dotData: FlDotData(show: true),
                                belowBarData: BarAreaData(
                                  show: true,
                                  color: Colors.lightBlueAccent.withOpacity(0.3),
                                ),
                                color: Colors.blue,
                              ),
                            ],
                          ),
                        ),
                      ),
                    ),
                    const SizedBox(height: 24),
                    Text('Hari Teraktif: $highestDay (${maxValue.toStringAsFixed(2)} KM)',
                        style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500)),
                    const SizedBox(height: 16),

                    const Text('Ringkasan Hasil Lari',
                        style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600)),
                    const SizedBox(height: 8),

                    ringkasanData.isEmpty
                        ? const Text('Belum ada data untuk hari teraktif.')
                        : ListView.separated(
                            shrinkWrap: true,
                            physics: const NeverScrollableScrollPhysics(),
                            itemCount: ringkasanData.length,
                            separatorBuilder: (_, __) => const SizedBox(height: 12),
                            itemBuilder: (context, index) {
                              final data = ringkasanData[index];
                              final timestamp = (data['timestamp'] as Timestamp?)?.toDate();
                              if (timestamp == null) return const SizedBox();

                              final jarak = (data['jarak'] ?? 0).toDouble();
                              final satuan = data['satuan'] ?? 'M';
                              final jarakKm = satuan == 'M' ? jarak / 1000.0 : jarak;

                              return GestureDetector(
                                onTap: () {
                                  Navigator.push(
                                    context,
                                    MaterialPageRoute(
                                      builder: (_) => DetailHasilLariScreen(
                                        data: {
                                          ...data,
                                          'docId': ringkasanData[index]['docId'] ?? '', // tambahkan docId kalau tersedia
                                        },
                                      ),
                                    ),
                                  );
                                },

                                child: Card(
                                  color: const Color.fromARGB(255, 60, 193, 255),
                                  elevation: 2,
                                  shape: RoundedRectangleBorder(
                                    borderRadius: BorderRadius.circular(12),
                                  ),
                                  child: ListTile(
                                    leading: Padding(
                                      padding: const EdgeInsets.only(top: 12.0), // geser ke bawah
                                      child: const Icon(Icons.directions_run),
                                    ),
                                    title: Text('${jarak.toStringAsFixed(0)} $satuan'),
                                    subtitle: Text(
                                      '${DateFormat('dd MMM yyyy, HH:mm').format(timestamp)}\n(${jarakKm.toStringAsFixed(2)} KM)',
                                    ),
                                    isThreeLine: true,
                                    trailing: Padding(
                                      padding: const EdgeInsets.only(top: 12.0), // geser ke bawah
                                      child: const Icon(Icons.arrow_forward_ios, size: 16),
                                    ),
                                  ),
                                ),
                              );
                            },
                          ),
                  ],
                ),
              );
            },
          ),
        ),
      )
    );
  }
}
