import 'dart:async';
import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:intl/intl.dart';
import 'history.dart';
import 'notifikasi.dart';
import '../widgets/fade_in_up.dart';
import '../widgets/whatsapp_notification.dart';
import 'akun.dart';
import '../utils/knn_classifier.dart';

class DashboardPage extends StatefulWidget {
  const DashboardPage({super.key});

  @override
  State<DashboardPage> createState() => _DashboardPageState();
}

class _DashboardPageState extends State<DashboardPage> {
  final db = FirebaseDatabase.instance.ref();

  double ppm = 0.0;
  double displayPpm = 0.0;
  double lastTestedPpm = 0.0;
  Timer? _interpolationTimer;
  int fanStatus = 0;

  String selectedFood = "Monitoring";
  bool isTesting = false;
  bool isFoodMenuExpanded = false;

  // 🔥 REALTIME GRAPH
  List<FlSpot> realtimeData = [];
  int timeIndex = 0;

  StreamSubscription? startListener;
  StreamSubscription? _ppmSubscription;
  StreamSubscription? _historySubscription;
  StreamSubscription? _fanSubscription;
  bool _isInteractingWithChart = false;

  @override
  void initState() {
    super.initState();
    WhatsAppNotificationService().startListening();
    readData();
    // Inisialisasi awal Firebase ke mode monitoring
    db.child("kontrol").update({"makanan": "Monitoring", "start": 0});
  }

  @override
  void dispose() {
    startListener?.cancel();
    _ppmSubscription?.cancel();
    _historySubscription?.cancel();
    _fanSubscription?.cancel();
    _interpolationTimer?.cancel();
    super.dispose();
  }

  void readData() {
    // ================= SENSOR REALTIME =================
    _ppmSubscription?.cancel();
    _ppmSubscription = db.child("sensor/formalin_ppm").onValue.listen((event) {
      print("REALTIME PPM: ${event.snapshot.value}");

      final data = event.snapshot.value;

      if (data != null && mounted) {
        double val = double.tryParse(data.toString()) ?? 0.0;

        setState(() {
          ppm = val;
          if (!isTesting) {
            displayPpm = val;
            
            // Tambahkan data ke grafik secara realtime saat standby
            realtimeData.add(FlSpot(timeIndex.toDouble(), val));
            timeIndex++;
            if (realtimeData.length > 30) {
              realtimeData.removeAt(0);
            }
          }
        });
      }
    });

    // ================= LAST TEST RESULT =================
    _historySubscription?.cancel();
    _historySubscription = db.child("sensor/history").limitToLast(1).onValue.listen((event) {
      final data = event.snapshot.value as Map?;
      if (data != null && data.isNotEmpty && mounted) {
        final lastEntry = data.values.first as Map?;
        double lastPpm = double.tryParse(lastEntry?["ppm"]?.toString() ?? "") ?? 0.0;

        setState(() {
          lastTestedPpm = lastPpm;
        });
      }
    });

    // ================= FAN REALTIME =================
    _fanSubscription?.cancel();
    _fanSubscription = db.child("sensor/fan").onValue.listen((event) {
      print("REALTIME FAN: ${event.snapshot.value}");

      final data = event.snapshot.value;

      if (data != null && mounted) {
        int newFanStatus = int.tryParse(data.toString()) ?? 0;
        setState(() {
          fanStatus = newFanStatus;
        });
      }
    });

    // ================= START REALTIME =================
    startListener?.cancel();

    startListener = db.child("kontrol/start").onValue.listen((event) {
      print("REALTIME START: ${event.snapshot.value}");

      final val = event.snapshot.value;

      final startValue = int.tryParse(val.toString()) ?? 0;

      // TEST SELESAI
      if (startValue == 0 && isTesting && mounted) {
        final testedFood = selectedFood;
        _interpolationTimer?.cancel();
        
        // Delay 1 detik untuk menghindari race condition agar Firebase selesai memproses data baru dari ESP32
        Future.delayed(const Duration(milliseconds: 1000), () async {
          if (!mounted) return;
          
          double finalPpm = ppm;
          try {
            final snapshot = await db.child("sensor/hasil_akhir").get();
            if (snapshot.value != null) {
              finalPpm = double.tryParse(snapshot.value.toString()) ?? ppm;
            }
          } catch (e) {
            print("Error fetching hasil_akhir: $e");
          }

          if (mounted) {
            setState(() {
              isTesting = false;
              selectedFood = "Monitoring"; // Kembalikan ke mode monitoring di UI
              lastTestedPpm = finalPpm;
              displayPpm = finalPpm;
              realtimeData.clear();
              timeIndex = 0;
            });

            tampilkanHasil(testedFood);

            // Update Firebase ke mode monitoring
            db.child("kontrol").update({"makanan": "Monitoring", "start": 0});

            // 🔥 SINKRONISASI: Simpan hasil uji ke history Firebase
            final historyRef = db.child("sensor/history").push();
            final nowSeconds = DateTime.now().millisecondsSinceEpoch ~/ 1000;
            String statusKnn = klasifikasiKNN(finalPpm);
            historyRef.set({
              "makanan": testedFood,
              "ppm": finalPpm,
              "timestamp": nowSeconds,
              "keterangan": statusKnn,
            });

            // 🔥 SINKRONISASI: Kirim notifikasi / alert ke path notifikasi Firebase
            final notifRef = db.child("notifikasi").push();
            final timeString = DateFormat('HH:mm').format(DateTime.now());
            notifRef.set({
              "title": statusKnn == "Bahaya" ? "Peringatan Bahaya!" : (statusKnn == "Sedang" ? "Peringatan Sedang!" : "Pemberitahuan Aman"),
              "message": statusKnn == "Bahaya"
                  ? "Terdeteksi kandungan formalin tinggi pada $testedFood (${finalPpm.toStringAsFixed(2)} PPM)!"
                  : (statusKnn == "Sedang"
                      ? "Terdeteksi kandungan formalin sedang pada $testedFood (${finalPpm.toStringAsFixed(2)} PPM)."
                      : "$testedFood aman dari kandungan formalin (${finalPpm.toStringAsFixed(2)} PPM)."),
              "timestamp": DateTime.now().millisecondsSinceEpoch,
              "time": timeString,
            });
          }
        });
      }
    });
  }



  // ================= DETEKSI =================
  void mulaiPengujian(String makanan) async {
    if (isTesting) return;

    setState(() {
      isTesting = true;
      selectedFood = makanan;
      displayPpm = 0.0;

      // reset grafik realtime
      realtimeData.clear();
      timeIndex = 0;
    });

    _startInterpolation();

    await db.child("kontrol").update({"makanan": makanan, "start": 1});

    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text("Mendeteksi $makanan selama 10 detik...")),
    );
  }

  void batalkanPengujian() async {
    _interpolationTimer?.cancel();
    setState(() {
      isTesting = false;
      selectedFood = "Monitoring";
      displayPpm = ppm;
      realtimeData.clear();
      timeIndex = 0;
    });

    await db.child("kontrol").update({"makanan": "Monitoring", "start": 0, "reset": 1});

    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(
        duration: Duration(milliseconds: 1500),
        content: Text("Pengujian dibatalkan. Kembali ke mode Monitoring."),
      ),
    );
  }

  void _startInterpolation() {
    _interpolationTimer?.cancel();
    _interpolationTimer = Timer.periodic(const Duration(milliseconds: 100), (timer) {
      if (!mounted || !isTesting) {
        timer.cancel();
        return;
      }

      setState(() {
        if (displayPpm < ppm) {
          double diff = ppm - displayPpm;
          if (diff > 0.02) {
            displayPpm += diff * 0.12; // Asymptotical rise
          } else {
            displayPpm = ppm;
          }
        } else if (displayPpm > ppm) {
          double diff = displayPpm - ppm;
          if (diff > 0.02) {
            displayPpm -= diff * 0.12;
          } else {
            displayPpm = ppm;
          }
        }

        double roundedDisplay = double.parse((displayPpm ?? 0.0).toStringAsFixed(2));

        realtimeData.add(FlSpot(timeIndex.toDouble(), roundedDisplay));
        timeIndex++;
        if (realtimeData.length > 30) {
          realtimeData.removeAt(0);
        }
      });
    });
  }

  void tampilkanHasil(String makanan) {
    String status;
    String message;
    double resultPpm = lastTestedPpm ?? 0.0;
    String statusKnn = klasifikasiKNN(resultPpm);

    if (statusKnn == "Bahaya") {
      status = "Hasil Uji: BERBAHAYA!";
      message =
          "Peringatan! Terdeteksi kandungan FORMALIN TINGGI pada $makanan (Rata-rata: ${resultPpm.toStringAsFixed(2)} PPM). JANGAN DIKONSUMSI!";
    } else if (statusKnn == "Sedang") {
      status = "Hasil Uji: SEDANG";
      message = "Perhatian. Terdeteksi kandungan formalin tingkat SEDANG pada $makanan (Rata-rata: ${resultPpm.toStringAsFixed(2)} PPM). Disarankan untuk lebih waspada.";
    } else {
      status = "Hasil Uji: AMAN";
      message =
          "Makanan $makanan AMAN dari formalin. Silakan konsumsi!";
    }

    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text(
          status,
          style: TextStyle(
            color: statusKnn == "Bahaya"
                ? Colors.redAccent
                : (statusKnn == "Sedang" ? Colors.orangeAccent : const Color(0xFF1565C0)),
            fontWeight: FontWeight.bold,
          ),
        ),
        content: Text(
          "Kadar HCHO pada $makanan adalah ${resultPpm.toStringAsFixed(2)} PPM\n\n$message",
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text("OK"),
          ),
        ],
      ),
    );
  }




  @override
  Widget build(BuildContext context) {
    final statusKnn = klasifikasiKNN(displayPpm);
    bool isBahaya = statusKnn == "Bahaya";

    return Scaffold(
      body: Container(
        width: double.infinity,
        height: double.infinity,
        decoration: const BoxDecoration(
          gradient: LinearGradient(
            colors: [
              Colors.white,
              Color(0xFFE3F2FD), // Light blue
              Color(0xFF42A5F5), // Medium blue
              Color(0xFF1565C0), // Dark blue
            ],
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
          ),
        ),
        child: SafeArea(
          child: SingleChildScrollView(
            physics: _isInteractingWithChart
                ? const NeverScrollableScrollPhysics()
                : const BouncingScrollPhysics(),
            padding: const EdgeInsets.all(20),
            child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // 0. GREETING SECTION
              FadeInUp(
                delay: 50,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Text(
                      "Hello!",
                      style: TextStyle(
                        fontSize: 24,
                        fontWeight: FontWeight.bold,
                        color: Color(0xFF1565C0),
                      ),
                    ),
                    Text(
                      "Welcome to SafeBite",
                      style: TextStyle(
                        fontSize: 14,
                        fontWeight: FontWeight.w500,
                        color: const Color(0xFF1565C0).withOpacity(0.7),
                      ),
                    ),
                  ],
                ),
              ),

              const SizedBox(height: 15),

              // 1. FORMALIN PPM CARD (Replacing Status Aman/Berbahaya)
              FadeInUp(
                delay: 100,
                child: AnimatedContainer(
                  duration: const Duration(milliseconds: 600),
                  curve: Curves.easeInOut,
                  width: double.infinity,
                  padding: const EdgeInsets.symmetric(
                    vertical: 25,
                    horizontal: 20,
                  ),
                  decoration: BoxDecoration(
                    color: statusKnn == "Bahaya"
                        ? Colors.redAccent
                        : (statusKnn == "Sedang"
                              ? Colors.orangeAccent
                              : const Color(0xFF1565C0)),
                    borderRadius: BorderRadius.circular(18),
                    boxShadow: [
                      BoxShadow(
                        color: (statusKnn == "Bahaya"
                                ? Colors.redAccent
                                : (statusKnn == "Sedang"
                                    ? Colors.orangeAccent
                                    : const Color(0xFF1565C0)))
                            .withOpacity(statusKnn == "Bahaya" ? 0.45 : 0.25),
                        blurRadius: statusKnn == "Bahaya" ? 24 : 12,
                        spreadRadius: statusKnn == "Bahaya" ? 3 : 0,
                        offset: const Offset(0, 8),
                      ),
                    ],
                  ),
                  child: Column(
                    children: [
                      Text(
                        "FORMALIN PPM",
                        style: TextStyle(
                          fontSize: 16,
                          fontWeight: FontWeight.bold,
                          color: Colors.white.withOpacity(0.8),
                          letterSpacing: 1.2,
                        ),
                      ),
                      const SizedBox(height: 10),
                      TweenAnimationBuilder<double>(
                        tween: Tween<double>(begin: 0.0, end: displayPpm ?? 0.0),
                        duration: const Duration(milliseconds: 600),
                        curve: Curves.easeOutCubic,
                        builder: (context, val, child) {
                          return Text(
                            (val ?? 0.0).toStringAsFixed(2),
                            style: const TextStyle(
                              fontSize: 48,
                              fontWeight: FontWeight.bold,
                              color: Colors.white,
                            ),
                          );
                        },
                      ),
                      const SizedBox(height: 5),
                      AnimatedSwitcher(
                        duration: const Duration(milliseconds: 300),
                        transitionBuilder: (child, animation) {
                          return FadeTransition(
                            opacity: animation,
                            child: ScaleTransition(scale: animation, child: child),
                          );
                        },
                        child: Text(
                          statusKnn == "Bahaya"
                              ? "BAHAYA"
                              : (statusKnn == "Sedang"
                                    ? "SEDANG"
                                    : "AMAN"),
                          key: ValueKey<String>(statusKnn),
                          style: const TextStyle(
                            fontSize: 16,
                            fontWeight: FontWeight.bold,
                            color: Colors.white,
                            letterSpacing: 1.0,
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),

              const SizedBox(height: 25),

              // 2. PILIHAN MAKANAN
              FadeInUp(
                delay: 200,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    GestureDetector(
                      onTap: () {
                        if (!isTesting) {
                          setState(() {
                            isFoodMenuExpanded = !isFoodMenuExpanded;
                          });
                        }
                      },
                      child: AnimatedContainer(
                        duration: const Duration(milliseconds: 300),
                        padding: const EdgeInsets.symmetric(
                          horizontal: 20,
                          vertical: 16,
                        ),
                        decoration: BoxDecoration(
                          color: Colors.white,
                          borderRadius: BorderRadius.circular(18),
                          border: Border.all(
                            color: const Color(0xFF1565C0).withOpacity(0.12),
                            width: 1.5,
                          ),
                          boxShadow: [
                            BoxShadow(
                              color: const Color(0xFF1565C0).withOpacity(0.06),
                              blurRadius: 10,
                              offset: const Offset(0, 4),
                            ),
                          ],
                        ),
                        child: Row(
                          children: [
                            Container(
                              padding: const EdgeInsets.all(10),
                              decoration: const BoxDecoration(
                                color: Color(0xFFE3F2FD),
                                shape: BoxShape.circle,
                              ),
                              child: const Icon(
                                Icons.restaurant_menu_rounded,
                                color: Color(0xFF1565C0),
                                size: 24,
                              ),
                            ),
                            const SizedBox(width: 15),
                            Expanded(
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  const Text(
                                    "Pilih Menu Makanan",
                                    style: TextStyle(
                                      fontSize: 16,
                                      fontWeight: FontWeight.bold,
                                      color: Color(0xFF1565C0),
                                      letterSpacing: 0.3,
                                    ),
                                  ),
                                  const SizedBox(height: 3),
                                  Text(
                                    isTesting
                                        ? "Sedang Menguji: $selectedFood"
                                        : (selectedFood == "Monitoring"
                                              ? "Mode: Monitoring (Ketuk opsi di bawah)"
                                              : "Terpilih: $selectedFood (Ketuk untuk ganti)"),
                                    style: TextStyle(
                                      fontSize: 12,
                                      fontWeight: FontWeight.w500,
                                      color: (selectedFood == "Monitoring" || isTesting)
                                          ? Colors.grey.shade600
                                          : const Color(0xFF1565C0),
                                    ),
                                  ),
                                ],
                              ),
                            ),
                            const SizedBox(width: 5),
                            AnimatedRotation(
                              turns: isFoodMenuExpanded ? 0.5 : 0.0,
                              duration: const Duration(milliseconds: 300),
                              child: Icon(
                                Icons.keyboard_arrow_down_rounded,
                                color: const Color(0xFF1565C0).withOpacity(0.7),
                                size: 26,
                              ),
                            ),
                          ],
                        ),
                      ),
                    ),
                    AnimatedSize(
                      duration: const Duration(milliseconds: 300),
                      curve: Curves.easeInOut,
                      child: Container(
                        child: isFoodMenuExpanded
                            ? Padding(
                                padding: const EdgeInsets.only(top: 15.0),
                                child: Column(
                                  children: [
                                    Row(
                                      children: [
                                        Expanded(
                                          child: _foodButton(
                                            "Mie Ayam",
                                            Icons.ramen_dining,
                                          ),
                                        ),
                                        const SizedBox(width: 15),
                                        Expanded(
                                          child: _foodButton(
                                            "Bakso",
                                            Icons.soup_kitchen,
                                          ),
                                        ),
                                      ],
                                    ),
                                    const SizedBox(height: 15),
                                    Row(
                                      children: [
                                        Expanded(
                                          child: _foodButton(
                                            "Air Mineral",
                                            Icons.local_drink_rounded,
                                          ),
                                        ),
                                        const SizedBox(width: 15),
                                        const Expanded(
                                          child: SizedBox.shrink(),
                                        ),
                                      ],
                                    ),
                                  ],
                                ),
                              )
                            : const SizedBox.shrink(),
                      ),
                    ),
                  ],
                ),
              ),

              const SizedBox(height: 25),

              // 3. STATUS KIPAS
              FadeInUp(
                delay: 300,
                child: FanControlCard(
                  isFanActive: fanStatus == 1,
                ),
              ),

              const SizedBox(height: 25),

              // 4. GRAFIK
              FadeInUp(
                delay: 400,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Text(
                      "Grafik Realtime",
                      style: TextStyle(
                        fontSize: 16,
                        fontWeight: FontWeight.bold,
                        color: Colors.white,
                      ),
                    ),
                    const SizedBox(height: 10),
                    Container(
                      height: 200,
                      padding: const EdgeInsets.all(15),
                      decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius: BorderRadius.circular(15),
                      ),
                      child: Listener(
                        onPointerDown: (_) {
                          setState(() {
                            _isInteractingWithChart = true;
                          });
                        },
                        onPointerUp: (_) {
                          setState(() {
                            _isInteractingWithChart = false;
                          });
                        },
                        onPointerCancel: (_) {
                          setState(() {
                            _isInteractingWithChart = false;
                          });
                        },
                        child: InteractiveViewer(
                          panEnabled: true,
                          scaleEnabled: true,
                          minScale: 0.8,
                          maxScale: 5.0,
                          child: LineChart(
                          LineChartData(
                            gridData: FlGridData(
                              show: true,
                              drawVerticalLine: true,
                              horizontalInterval: 0.5,
                              verticalInterval: 5,
                              getDrawingHorizontalLine: (value) {
                                return FlLine(
                                  color: Colors.blue.shade50,
                                  strokeWidth: 1,
                                );
                              },
                              getDrawingVerticalLine: (value) {
                                return FlLine(
                                  color: Colors.blue.shade50,
                                  strokeWidth: 1,
                                );
                              },
                            ),
                            titlesData: const FlTitlesData(
                              show: true,
                              rightTitles: AxisTitles(
                                sideTitles: SideTitles(showTitles: false),
                              ),
                              topTitles: AxisTitles(
                                sideTitles: SideTitles(showTitles: false),
                              ),
                              leftTitles: AxisTitles(
                                sideTitles: SideTitles(
                                  showTitles: true,
                                  reservedSize: 30,
                                ),
                              ),
                              bottomTitles: AxisTitles(
                                sideTitles: SideTitles(
                                  showTitles: true,
                                  reservedSize: 22,
                                ),
                              ),
                            ),
                            borderData: FlBorderData(
                              show: true,
                              border: Border.all(color: Colors.blue.shade100, width: 1),
                            ),
                            lineTouchData: LineTouchData(
                              handleBuiltInTouches: true,
                              touchTooltipData: LineTouchTooltipData(
                                tooltipBgColor: const Color(0xFF1565C0).withOpacity(0.8),
                                getTooltipItems: (List<LineBarSpot> touchedBarSpots) {
                                  return touchedBarSpots.map((barSpot) {
                                    return LineTooltipItem(
                                      '${barSpot.y.toStringAsFixed(2)} PPM',
                                      const TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
                                    );
                                  }).toList();
                                },
                              ),
                            ),
                            lineBarsData: [
                              LineChartBarData(
                                spots: realtimeData.length >= 2
                                    ? realtimeData
                                    : [FlSpot(0, displayPpm), FlSpot(1, displayPpm)],
                                isCurved: true,
                                preventCurveOverShooting: true,
                                barWidth: 4,
                                color: isTesting
                                    ? Colors.orange
                                    : const Color(0xFF1565C0),
                                isStrokeCapRound: true,
                                dotData: FlDotData(
                                  show: true,
                                  getDotPainter: (spot, percent, barData, index) =>
                                      FlDotCirclePainter(
                                    radius: 3,
                                    color: isTesting ? Colors.orange : const Color(0xFF1565C0),
                                    strokeWidth: 1,
                                    strokeColor: Colors.white,
                                  ),
                                ),
                                belowBarData: BarAreaData(
                                  show: true,
                                  gradient: LinearGradient(
                                    colors: [
                                      (isTesting ? Colors.orange : const Color(0xFF1565C0))
                                          .withOpacity(0.2),
                                      (isTesting ? Colors.orange : const Color(0xFF1565C0))
                                          .withOpacity(0.0),
                                    ],
                                    begin: Alignment.topCenter,
                                    end: Alignment.bottomCenter,
                                  ),
                                ),
                              ),
                            ],
                          ),
                          duration: const Duration(milliseconds: 350),
                          curve: Curves.easeOutCubic,
                        ),
                      ),
                    ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    ),
    bottomNavigationBar: BottomNavigationBar(
        currentIndex: 0,
        selectedItemColor: const Color(0xFF1565C0),
        unselectedItemColor: Colors.grey,
        type: BottomNavigationBarType.fixed,
        onTap: (index) {
          if (index == 1) {
            Navigator.pushReplacement(
              context,
              MaterialPageRoute(builder: (context) => const RiwayatPage()),
            );
          } else if (index == 2) {
            Navigator.pushReplacement(
              context,
              MaterialPageRoute(builder: (context) => const NotifikasiPage()),
            );
          } else if (index == 3) {
            Navigator.pushReplacement(
              context,
              MaterialPageRoute(builder: (context) => const AkunPage()),
            );
          }
        },
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: "Home"),
          BottomNavigationBarItem(icon: Icon(Icons.history), label: "History"),
          BottomNavigationBarItem(
            icon: Icon(Icons.notifications),
            label: "Notif",
          ),
          BottomNavigationBarItem(icon: Icon(Icons.person), label: "Akun"),
        ],
      ),
    );
  }

  Widget _foodButton(String title, IconData icon) {
    bool isSelected = selectedFood == title;
    bool loading = isTesting && isSelected;

    return FoodSelectionCard(
      title: title,
      icon: icon,
      isSelected: isSelected,
      isLoading: loading,
      onTap: () {
        if (selectedFood == title) {
          batalkanPengujian();
        } else {
          mulaiPengujian(title);
        }
      },
    );
  }
}

class FoodSelectionCard extends StatefulWidget {
  final String title;
  final IconData icon;
  final bool isSelected;
  final bool isLoading;
  final VoidCallback onTap;

  const FoodSelectionCard({
    super.key,
    required this.title,
    required this.icon,
    required this.isSelected,
    required this.isLoading,
    required this.onTap,
  });

  @override
  State<FoodSelectionCard> createState() => _FoodSelectionCardState();
}

class _FoodSelectionCardState extends State<FoodSelectionCard>
    with SingleTickerProviderStateMixin {
  bool _isPressed = false;
  late AnimationController _rotationController;

  @override
  void initState() {
    super.initState();
    _rotationController = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    );
    if (widget.isLoading) {
      _rotationController.repeat();
    }
  }

  @override
  void didUpdateWidget(covariant FoodSelectionCard oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.isLoading && !_rotationController.isAnimating) {
      _rotationController.repeat();
    } else if (!widget.isLoading && _rotationController.isAnimating) {
      _rotationController.stop();
    }
  }

  @override
  void dispose() {
    _rotationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    double scale = 1.0;
    if (_isPressed) {
      scale = 0.94;
    } else if (widget.isSelected) {
      scale = 1.04;
    }

    Gradient gradient;
    List<BoxShadow> shadows;
    Color iconColor;
    Color textColor;
    Border border;

    if (widget.isLoading) {
      gradient = const LinearGradient(
        colors: [Color(0xFFFF9100), Color(0xFFFF3D00)],
        begin: Alignment.topLeft,
        end: Alignment.bottomRight,
      );
      shadows = [
        BoxShadow(
          color: Colors.deepOrange.withOpacity(0.4),
          blurRadius: 15,
          offset: const Offset(0, 8),
        ),
      ];
      iconColor = Colors.white;
      textColor = Colors.white;
      border = Border.all(color: Colors.transparent);
    } else if (widget.isSelected) {
      gradient = const LinearGradient(
        colors: [Color(0xFF2196F3), Color(0xFF0D47A1)],
        begin: Alignment.topLeft,
        end: Alignment.bottomRight,
      );
      shadows = [
        BoxShadow(
          color: const Color(0xFF0D47A1).withOpacity(0.4),
          blurRadius: 15,
          offset: const Offset(0, 8),
        ),
      ];
      iconColor = Colors.white;
      textColor = Colors.white;
      border = Border.all(color: Colors.transparent);
    } else {
      gradient = const LinearGradient(
        colors: [Colors.white, Color(0xFFF5F7FA)],
        begin: Alignment.topLeft,
        end: Alignment.bottomRight,
      );
      shadows = [
        BoxShadow(
          color: Colors.black.withOpacity(0.04),
          blurRadius: 10,
          offset: const Offset(0, 4),
        ),
      ];
      iconColor = const Color(0xFF1565C0);
      textColor = Colors.black87;
      border = Border.all(
        color: const Color(0xFF1565C0).withOpacity(0.12),
        width: 1.5,
      );
    }

    return GestureDetector(
      onTapDown: (_) => setState(() => _isPressed = true),
      onTapUp: (_) => setState(() => _isPressed = false),
      onTapCancel: () => setState(() => _isPressed = false),
      onTap: widget.onTap,
      child: AnimatedScale(
        scale: scale,
        duration: const Duration(milliseconds: 150),
        curve: Curves.easeOutBack,
        child: AnimatedContainer(
          duration: const Duration(milliseconds: 300),
          curve: Curves.easeInOut,
          padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 16),
          decoration: BoxDecoration(
            gradient: gradient,
            borderRadius: BorderRadius.circular(20),
            border: border,
            boxShadow: shadows,
          ),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              RotationTransition(
                turns: _rotationController,
                child: AnimatedContainer(
                  duration: const Duration(milliseconds: 300),
                  padding: const EdgeInsets.all(10),
                  decoration: BoxDecoration(
                    color: widget.isLoading
                        ? Colors.white.withOpacity(0.25)
                        : (widget.isSelected
                              ? Colors.white.withOpacity(0.15)
                              : const Color(0xFFE3F2FD)),
                    shape: BoxShape.circle,
                  ),
                  child: Icon(widget.icon, size: 28, color: iconColor),
                ),
              ),
              const SizedBox(height: 12),
              AnimatedDefaultTextStyle(
                duration: const Duration(milliseconds: 200),
                style: TextStyle(
                  fontSize: 15,
                  fontWeight: FontWeight.bold,
                  color: textColor,
                  letterSpacing: 0.3,
                ),
                child: Text(widget.isLoading ? "Menguji..." : widget.title),
              ),
              const SizedBox(height: 4),
              AnimatedDefaultTextStyle(
                duration: const Duration(milliseconds: 200),
                style: TextStyle(
                  fontSize: 11,
                  fontWeight: FontWeight.w500,
                  color: widget.isLoading
                      ? Colors.white.withOpacity(0.8)
                      : (widget.isSelected
                            ? Colors.white.withOpacity(0.8)
                            : Colors.grey.shade600),
                ),
                child: Text(
                  widget.isLoading
                      ? "Harap Tunggu"
                      : (widget.isSelected ? "Ketuk utk Batal" : "Uji Sekarang"),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class FanControlCard extends StatefulWidget {
  final bool isFanActive;

  const FanControlCard({
    super.key,
    required this.isFanActive,
  });

  @override
  State<FanControlCard> createState() => _FanControlCardState();
}

class _FanControlCardState extends State<FanControlCard>
    with SingleTickerProviderStateMixin {
  late AnimationController _spinController;

  @override
  void initState() {
    super.initState();
    _spinController = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    );
    if (widget.isFanActive) {
      _spinController.repeat();
    }
  }

  @override
  void didUpdateWidget(covariant FanControlCard oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.isFanActive && !_spinController.isAnimating) {
      _spinController.repeat();
    } else if (!widget.isFanActive && _spinController.isAnimating) {
      _spinController.stop();
    }
  }

  @override
  void dispose() {
    _spinController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    Gradient gradient;
    Border border;

    if (widget.isFanActive) {
      gradient = const LinearGradient(
        colors: [Color(0xFFE0F7FA), Color(0xFFE3F2FD)],
        begin: Alignment.topLeft,
        end: Alignment.bottomRight,
      );
      border = Border.all(
        color: const Color(0xFF00E5FF).withOpacity(0.3),
        width: 1.5,
      );
    } else {
      gradient = const LinearGradient(
        colors: [Colors.white, Color(0xFFF8F9FA)],
        begin: Alignment.topLeft,
        end: Alignment.bottomRight,
      );
      border = Border.all(
        color: const Color(0xFF1565C0).withOpacity(0.12),
        width: 1.5,
      );
    }

    return AnimatedContainer(
      duration: const Duration(milliseconds: 300),
      curve: Curves.easeInOut,
      padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
      decoration: BoxDecoration(
        gradient: gradient,
        borderRadius: BorderRadius.circular(20),
        border: border,
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.04),
            blurRadius: 10,
            offset: const Offset(0, 4),
          ),
        ],
      ),
      child: Column(
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Row(
                children: [
                  RotationTransition(
                    turns: _spinController,
                    child: Container(
                      padding: const EdgeInsets.all(10),
                      decoration: BoxDecoration(
                        color: widget.isFanActive
                            ? const Color(0xFF00E5FF).withOpacity(0.2)
                            : const Color(0xFFE3F2FD),
                        shape: BoxShape.circle,
                      ),
                      child: Icon(
                        Icons.toys_outlined,
                        color: widget.isFanActive
                            ? const Color(0xFF00E5FF)
                            : const Color(0xFF1565C0),
                        size: 24,
                      ),
                    ),
                  ),
                  const SizedBox(width: 12),
                  const Text(
                    "Kipas Sirkulasi Otomatis",
                    style: TextStyle(
                      fontSize: 16,
                      fontWeight: FontWeight.bold,
                      color: Color(0xFF1565C0),
                    ),
                  ),
                ],
              ),
              Container(
                padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
                decoration: BoxDecoration(
                  color: widget.isFanActive
                      ? Colors.green.shade50
                      : Colors.grey.shade100,
                  borderRadius: BorderRadius.circular(8),
                  border: Border.all(
                    color: widget.isFanActive
                        ? Colors.green.shade300
                        : Colors.grey.shade300,
                  ),
                ),
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Container(
                      width: 8,
                      height: 8,
                      decoration: BoxDecoration(
                        color: widget.isFanActive ? Colors.green : Colors.grey,
                        shape: BoxShape.circle,
                      ),
                    ),
                    const SizedBox(width: 6),
                    Text(
                      widget.isFanActive ? "AKTIF" : "MATI",
                      style: TextStyle(
                        fontSize: 10,
                        fontWeight: FontWeight.bold,
                        color: widget.isFanActive
                            ? Colors.green.shade700
                            : Colors.grey.shade700,
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
          const Divider(height: 24, thickness: 1),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      widget.isFanActive ? "Kipas Sedang Menyala" : "Kipas Sedang Mati",
                      style: const TextStyle(
                        fontSize: 14,
                        fontWeight: FontWeight.bold,
                        color: Colors.black87,
                      ),
                    ),
                    const SizedBox(height: 4),
                    Text(
                      widget.isFanActive
                          ? "Terdeteksi formalin, kipas aktif secara otomatis untuk menetralisir udara sekitar."
                          : "Sensor dalam kondisi aman. Kipas akan otomatis menyala jika kadar formalin meningkat.",
                      style: TextStyle(
                        fontSize: 11,
                        color: Colors.grey.shade600,
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}
