import 'dart:math';
import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
  final dbRef = FirebaseDatabase.instance.ref("pengering");

  double temperature = 0;
  double humidity = 0;

  String fanIn = "OFF";
  String fanOut = "OFF";
  String heater = "OFF";
  bool stepperLeft = false;
  bool stepperRight = false;
  String mode = "-";
  bool exhaustManual = false;

  // Controller animasi untuk putaran kipas 3D
  late final AnimationController _fanInController;
  late final AnimationController _fanOutController;

  @override
  void initState() {
    super.initState();

    _fanInController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 900),
    );
    _fanOutController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 650),
    );

    dbRef.onValue.listen((event) {
      final data = event.snapshot.value;

      if (data != null) {
        try {
          final map = Map<String, dynamic>.from(data as Map);

          setState(() {
            if (map["suhu"] != null) {
              temperature = (map["suhu"] as num).toDouble();
            }

            if (map["kelembapan"] != null) {
              humidity = (map["kelembapan"] as num).toDouble();
            }

            fanIn = map["fan_in"]?.toString() ?? "OFF";
            fanOut = map["fan_out"]?.toString() ?? "OFF";
            heater = map["heater"]?.toString() ?? "OFF";

            mode = map["status"]?.toString() ?? "-";

            // ===== Sinkron tombol Exhaust =====
            exhaustManual = map["exhaust_manual"] == "ON";

            // ===== Sinkron tombol Stepper =====
            stepperLeft = map["stepper"] == "LEFT";
            stepperRight = map["stepper"] == "RIGHT";
          });

          // ===== Sinkron animasi kipas 3D dengan status ON/OFF =====
          if (isOn(fanIn)) {
            if (!_fanInController.isAnimating) _fanInController.repeat();
          } else {
            _fanInController.stop();
          }

          if (isOn(fanOut)) {
            if (!_fanOutController.isAnimating) _fanOutController.repeat();
          } else {
            _fanOutController.stop();
          }
        } catch (e) {
          debugPrint("ERROR PARSE: $e");
        }
      }
    });
  }

  @override
  void dispose() {
    _fanInController.dispose();
    _fanOutController.dispose();
    super.dispose();
  }

  bool isOn(String value) => value == "ON";

  /// =========================
  /// CONTROL BUTTON
  /// =========================

  Future<void> sendAuto(String value) async {
    await dbRef.update({"auto": value});
  }

  Future<void> sendExhaust(String value) async {
    await dbRef.update({"exhaust_manual": value});
  }

  Future<void> sendStepper(String value) async {
    await dbRef.update({"stepper": value});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFFF6F1EE),
      body: SafeArea(
        child: SingleChildScrollView(
          padding: const EdgeInsets.all(20),
          child: Column(
            children: [
              /// HEADER
              Container(
                padding: const EdgeInsets.all(20),
                decoration: BoxDecoration(
                  gradient: const LinearGradient(
                    colors: [Color(0xFF6F4E37), Color(0xFF8D6E63)],
                    begin: Alignment.topLeft,
                    end: Alignment.bottomRight,
                  ),
                  borderRadius: BorderRadius.circular(30),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.brown.withOpacity(0.2),
                      blurRadius: 15,
                      offset: const Offset(0, 8),
                    ),
                  ],
                ),
                child: Row(
                  children: [
                    Container(
                      padding: const EdgeInsets.all(14),
                      decoration: BoxDecoration(
                        color: Colors.white.withOpacity(0.2),
                        shape: BoxShape.circle,
                      ),
                      child: const Icon(
                        Icons.coffee,
                        color: Colors.white,
                        size: 30,
                      ),
                    ),
                    const SizedBox(width: 15),
                    const Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            "Coffee Dryer",
                            style: TextStyle(
                              color: Colors.white,
                              fontSize: 24,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          SizedBox(height: 5),
                          Text(
                            "Monitoring Pengering Kopi",
                            style: TextStyle(
                              color: Colors.white70,
                              fontSize: 14,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),

              const SizedBox(height: 25),

              /// STATUS MODE
              Container(
                padding: const EdgeInsets.symmetric(
                  horizontal: 20,
                  vertical: 15,
                ),
                decoration: BoxDecoration(
                  color: mode == "AUTO" ? Colors.green : Colors.orange,
                  borderRadius: BorderRadius.circular(20),
                ),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    const Icon(Icons.autorenew, color: Colors.white),
                    const SizedBox(width: 10),
                    Text(
                      "MODE : $mode",
                      style: const TextStyle(
                        color: Colors.white,
                        fontSize: 18,
                        fontWeight: FontWeight.bold,
                        letterSpacing: 1,
                      ),
                    ),
                  ],
                ),
              ),

              const SizedBox(height: 25),

              /// SENSOR CARD
              Row(
                children: [
                  Expanded(
                    child: sensorCard(
                      title: "Suhu",
                      value: "${temperature.toStringAsFixed(1)}°C",
                      icon: Icons.thermostat,
                      color: Colors.redAccent,
                    ),
                  ),
                  const SizedBox(width: 15),
                  Expanded(
                    child: sensorCard(
                      title: "Kelembapan",
                      value: "${humidity.toStringAsFixed(1)}%",
                      icon: Icons.water_drop,
                      color: Colors.blue,
                    ),
                  ),
                ],
              ),

              const SizedBox(height: 30),

              /// CONTROL BUTTON
              Align(
                alignment: Alignment.centerLeft,
                child: Text(
                  "Kontrol Mesin",
                  style: TextStyle(
                    fontSize: 20,
                    fontWeight: FontWeight.bold,
                    color: Colors.brown.shade800,
                  ),
                ),
              ),

              const SizedBox(height: 15),

              Row(
                children: [
                  Expanded(
                    child: controlButton(
                      title: "Mulai",
                      icon: Icons.play_arrow,
                      color: Colors.green,
                      onTap: () => sendAuto("START"),
                    ),
                  ),

                  const SizedBox(width: 12),

                  Expanded(
                    child: controlButton(
                      title: "Berhenti",
                      icon: Icons.stop,
                      color: Colors.red,
                      onTap: () => sendAuto("STOP"),
                    ),
                  ),
                  const SizedBox(width: 12),

                  Expanded(
                    child: controlButton(
                      title: exhaustManual ? "Exhaust ON" : "Exhaust OFF",
                      icon: Icons.wind_power,
                      color: exhaustManual ? Colors.green : Colors.blueGrey,
                      onTap: () async {
                        // Tidak boleh dimatikan saat suhu masih tinggi
                        if (temperature > 55 && exhaustManual) {
                          ScaffoldMessenger.of(context).showSnackBar(
                            const SnackBar(
                              content: Text(
                                "Exhaust tidak bisa dimatikan saat suhu di atas 55°C",
                              ),
                            ),
                          );
                          return;
                        }

                        if (exhaustManual) {
                          await sendExhaust("OFF");
                        } else {
                          await sendExhaust("ON");
                        }
                      },
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 12),

              Row(
                children: [
                  Expanded(
                    child: controlButton(
                      title: stepperLeft ? "Mundur ON" : "Mundur OFF",
                      icon: Icons.rotate_left,
                      color: stepperLeft ? Colors.green : Colors.grey,

                      onTap: () async {
                        if (mode != "STOP") {
                          ScaffoldMessenger.of(context).showSnackBar(
                            const SnackBar(
                              content: Text(
                                "Stepper hanya bisa dijalankan setelah mesin berhenti",
                              ),
                            ),
                          );
                          return;
                        }

                        stepperLeft = !stepperLeft;

                        if (stepperLeft) {
                          stepperRight = false;
                          await sendStepper("LEFT");
                        } else {
                          await sendStepper("STOP");
                        }

                        setState(() {});
                      },
                    ),
                  ),

                  const SizedBox(width: 12),

                  Expanded(
                    child: controlButton(
                      title: stepperRight ? "Maju ON" : "Maju OFF",
                      icon: Icons.rotate_right,
                      color: stepperRight ? Colors.green : Colors.grey,

                      onTap: () async {
                        if (mode != "STOP") {
                          ScaffoldMessenger.of(context).showSnackBar(
                            const SnackBar(
                              content: Text(
                                "Stepper hanya bisa dijalankan setelah mesin berhenti",
                              ),
                            ),
                          );
                          return;
                        }

                        stepperRight = !stepperRight;

                        if (stepperRight) {
                          stepperLeft = false;
                          await sendStepper("RIGHT");
                        } else {
                          await sendStepper("STOP");
                        }

                        setState(() {});
                      },
                    ),
                  ),
                ],
              ),

              const SizedBox(height: 12),

              /// PANDUAN ISTILAH - penjelasan awam soal tombol
              /// Maju & Mundur, gaya sama dengan kartu
              /// Heater/Intake/Exhaust di bawah
              Align(
                alignment: Alignment.centerLeft,
                child: Text(
                  "Keterangan Tombol Maju & Mundur",
                  style: TextStyle(
                    fontSize: 20,
                    fontWeight: FontWeight.bold,
                    color: Colors.brown.shade800,
                  ),
                ),
              ),

              const SizedBox(height: 15),

              stepperGuideCard(),

              const SizedBox(height: 30),

              /// INFORMASI ALAT - VISUALISASI 3D
              Align(
                alignment: Alignment.centerLeft,
                child: Text(
                  "Informasi Alat",
                  style: TextStyle(
                    fontSize: 20,
                    fontWeight: FontWeight.bold,
                    color: Colors.brown.shade800,
                  ),
                ),
              ),

              const SizedBox(height: 15),

              machineVisualization(),

              const SizedBox(height: 20),

              /// PANDUAN ISTILAH - penjelasan awam soal
              /// Heater, Fan Intake, dan Fan Exhaust
              Align(
                alignment: Alignment.centerLeft,
                child: Text(
                  "Apa Arti Status Ini?",
                  style: TextStyle(
                    fontSize: 20,
                    fontWeight: FontWeight.bold,
                    color: Colors.brown.shade800,
                  ),
                ),
              ),

              const SizedBox(height: 15),

              termGuideCard(),

              const SizedBox(height: 20),
            ],
          ),
        ),
      ),
    );
  }

  /// SENSOR CARD
  Widget sensorCard({
    required String title,
    required String value,
    required IconData icon,
    required Color color,
  }) {
    return Container(
      padding: const EdgeInsets.all(20),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(25),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.05),
            blurRadius: 15,
            offset: const Offset(0, 8),
          ),
        ],
      ),
      child: Column(
        children: [
          Container(
            padding: const EdgeInsets.all(15),
            decoration: BoxDecoration(
              color: color.withOpacity(0.1),
              shape: BoxShape.circle,
            ),
            child: Icon(icon, size: 35, color: color),
          ),
          const SizedBox(height: 15),
          Text(
            title,
            style: TextStyle(color: Colors.grey.shade700, fontSize: 16),
          ),
          const SizedBox(height: 10),
          Text(
            value,
            style: TextStyle(
              color: color,
              fontSize: 24,
              fontWeight: FontWeight.bold,
            ),
          ),
        ],
      ),
    );
  }

  /// CONTROL BUTTON
  Widget controlButton({
    required String title,
    required IconData icon,
    required Color color,
    required VoidCallback onTap,
  }) {
    return GestureDetector(
      onTap: onTap,
      child: Container(
        padding: const EdgeInsets.symmetric(vertical: 18),
        decoration: BoxDecoration(
          color: color,
          borderRadius: BorderRadius.circular(20),
          boxShadow: [
            BoxShadow(
              color: color.withOpacity(0.3),
              blurRadius: 10,
              offset: const Offset(0, 5),
            ),
          ],
        ),
        child: Column(
          children: [
            Icon(icon, color: Colors.white, size: 30),
            const SizedBox(height: 8),
            Text(
              title,
              style: const TextStyle(
                color: Colors.white,
                fontWeight: FontWeight.bold,
              ),
            ),
          ],
        ),
      ),
    );
  }

  /// =========================================================
  /// VISUALISASI MESIN PENGERING
  ///
  /// Badan mesin digambar sebagai KUBUS/KOTAK, dibuat dari 2 layer
  /// Container yang saling offset (bukan proyeksi isometrik trig)
  /// supaya kesan "3D"-nya tetap ada tapi bentuknya tidak gampang
  /// berantakan di berbagai ukuran layar.
  ///
  /// - Kipas EXHAUST kiri & kanan menempel PERSIS di sisi kiri/kanan
  ///   kubus lewat bracket kecil.
  /// - Kipas INTAKE disambungkan ke bagian ATAS kubus lewat duct -
  ///   mewakili posisi "belakang" (karena tampilan depan datar tidak
  ///   bisa menunjukkan sisi belakang secara literal).
  /// - HEATER digambar sebagai bola cahaya + ikon api PERSIS DI
  ///   TENGAH kubus, menyala saat status ON.
  /// =========================================================
  Widget machineVisualization() {
    return Container(
      width: double.infinity,
      padding: const EdgeInsets.all(20),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(25),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.05),
            blurRadius: 15,
            offset: const Offset(0, 8),
          ),
        ],
      ),
      child: Column(
        children: [
          Center(
            child: SizedBox(
              width: 300,
              height: 300,
              child: Stack(
                clipBehavior: Clip.none,
                children: [
                  // ===== Duct Intake: dari kubus ke kipas intake =====
                  Positioned(
                    left: 143,
                    top: 69,
                    child: Container(
                      width: 14,
                      height: 50,
                      decoration: BoxDecoration(
                        color: isOn(fanIn)
                            ? Colors.blue.shade200
                            : Colors.grey.shade300,
                        borderRadius: BorderRadius.circular(6),
                      ),
                    ),
                  ),

                  // ===== Lapisan belakang kubus (kesan kedalaman 3D) =====
                  Positioned(
                    left: 80,
                    top: 105,
                    child: Container(
                      width: 160,
                      height: 140,
                      decoration: BoxDecoration(
                        color: isOn(heater)
                            ? Colors.deepOrange.shade700
                            : Colors.brown.shade600,
                        borderRadius: BorderRadius.circular(22),
                      ),
                    ),
                  ),

                  // ===== KUBUS PENGERING (badan mesin, layer depan) =====
                  Positioned(
                    left: 70,
                    top: 115,
                    child: Container(
                      width: 160,
                      height: 140,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(22),
                        gradient: LinearGradient(
                          begin: Alignment.topLeft,
                          end: Alignment.bottomRight,
                          colors: isOn(heater)
                              ? [
                                  Colors.orange.shade100,
                                  Colors.deepOrange.shade200,
                                ]
                              : [Colors.brown.shade100, Colors.brown.shade300],
                        ),
                        border: Border.all(
                          color: Colors.black.withOpacity(0.08),
                        ),
                      ),
                    ),
                  ),

                  // ===== Kilau tipis di sisi atas kubus =====
                  Positioned(
                    left: 82,
                    top: 123,
                    child: Container(
                      width: 136,
                      height: 10,
                      decoration: BoxDecoration(
                        color: Colors.white.withOpacity(0.3),
                        borderRadius: BorderRadius.circular(6),
                      ),
                    ),
                  ),

                  // ===== Bracket KIRI (dudukan kipas exhaust) =====
                  Positioned(
                    left: 62,
                    top: 135,
                    child: Container(
                      width: 16,
                      height: 100,
                      decoration: BoxDecoration(
                        color: isOn(heater)
                            ? Colors.deepOrange.shade400
                            : Colors.brown.shade500,
                        borderRadius: BorderRadius.circular(6),
                      ),
                    ),
                  ),

                  // ===== Bracket KANAN (dudukan kipas exhaust) =====
                  Positioned(
                    left: 222,
                    top: 135,
                    child: Container(
                      width: 16,
                      height: 100,
                      decoration: BoxDecoration(
                        color: isOn(heater)
                            ? Colors.deepOrange.shade400
                            : Colors.brown.shade500,
                        borderRadius: BorderRadius.circular(6),
                      ),
                    ),
                  ),

                  // ===== HEATER - persis di tengah kubus =====
                  Positioned(
                    left: 112,
                    top: 147,
                    child: Container(
                      width: 76,
                      height: 76,
                      decoration: BoxDecoration(
                        shape: BoxShape.circle,
                        gradient: RadialGradient(
                          colors: isOn(heater)
                              ? [Colors.orange.shade300, Colors.red.shade600]
                              : [Colors.grey.shade300, Colors.grey.shade400],
                        ),
                        boxShadow: isOn(heater)
                            ? [
                                BoxShadow(
                                  color: Colors.red.withOpacity(0.5),
                                  blurRadius: 20,
                                  spreadRadius: 4,
                                ),
                              ]
                            : [],
                      ),
                      child: const Icon(
                        Icons.local_fire_department,
                        color: Colors.white,
                        size: 34,
                      ),
                    ),
                  ),

                  // ===== Kipas EXHAUST KIRI (nempel di bracket kiri) =====
                  Positioned(
                    left: 44,
                    top: 159,
                    child: fanCircle(
                      isOnStatus: isOn(fanOut),
                      controller: _fanOutController,
                      color: Colors.green,
                      size: 52,
                    ),
                  ),
                  Positioned(
                    left: 22,
                    top: 215,
                    child: SizedBox(
                      width: 96,
                      child: Text(
                        "Exhaust",
                        textAlign: TextAlign.center,
                        style: TextStyle(
                          fontSize: 11,
                          fontWeight: FontWeight.w600,
                          color: Colors.grey.shade600,
                        ),
                      ),
                    ),
                  ),

                  // ===== Kipas EXHAUST KANAN (nempel di bracket kanan) =====
                  Positioned(
                    left: 204,
                    top: 159,
                    child: fanCircle(
                      isOnStatus: isOn(fanOut),
                      controller: _fanOutController,
                      color: Colors.green,
                      size: 52,
                    ),
                  ),
                  Positioned(
                    left: 182,
                    top: 215,
                    child: SizedBox(
                      width: 96,
                      child: Text(
                        "Exhaust",
                        textAlign: TextAlign.center,
                        style: TextStyle(
                          fontSize: 11,
                          fontWeight: FontWeight.w600,
                          color: Colors.grey.shade600,
                        ),
                      ),
                    ),
                  ),

                  // ===== Kipas INTAKE (belakang, nyambung ke duct atas) =====
                  Positioned(
                    left: 127,
                    top: 23,
                    child: fanCircle(
                      isOnStatus: isOn(fanIn),
                      controller: _fanInController,
                      color: Colors.blue,
                      size: 46,
                    ),
                  ),
                  Positioned(
                    left: 90,
                    top: 5,
                    child: SizedBox(
                      width: 120,
                      child: Text(
                        "Intake (Belakang)",
                        textAlign: TextAlign.center,
                        style: TextStyle(
                          fontSize: 11,
                          fontWeight: FontWeight.w600,
                          color: Colors.grey.shade600,
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),

          const SizedBox(height: 12),

          // ===== Ringkasan status ON/OFF =====
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              statusChip("Heater", isOn(heater), Colors.red),
              statusChip("Fan In", isOn(fanIn), Colors.blue),
              statusChip("Fan Out", isOn(fanOut), Colors.green),
            ],
          ),
        ],
      ),
    );
  }

  /// =========================================================
  /// KARTU PANDUAN TOMBOL MAJU & MUNDUR
  ///
  /// Gaya kartu & tile-nya sengaja dibuat identik dengan
  /// termGuideCard() (Heater/Intake/Exhaust) di bawah, supaya
  /// konsisten secara visual di seluruh halaman - pakai ulang
  /// termGuideTile() yang sudah ada.
  /// =========================================================
  Widget stepperGuideCard() {
    return Container(
      width: double.infinity,
      padding: const EdgeInsets.all(20),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(25),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.05),
            blurRadius: 15,
            offset: const Offset(0, 8),
          ),
        ],
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          termGuideTile(
            icon: Icons.rotate_right,
            color: Colors.green,
            title: "Tombol Maju",
            description:
                "Ketika ditekan hingga muncul ON, tabung akan bergerak ke depan. "
                "Tekan lagi tombolnya agar perputaran berhenti.",
            onMeaning: "Tabung sedang bergerak ke depan.",
            offMeaning: "Perputaran berhenti.",
            onColor: Colors.green,
          ),
          const Padding(
            padding: EdgeInsets.symmetric(vertical: 14),
            child: Divider(height: 1),
          ),
          termGuideTile(
            icon: Icons.rotate_left,
            color: Colors.green,
            title: "Tombol Mundur",
            description:
                "Ketika ditekan hingga muncul ON, tabung akan bergerak ke belakang. "
                "Tekan lagi tombolnya agar perputaran berhenti.",
            onMeaning: "Tabung sedang bergerak ke belakang.",
            offMeaning: "Perputaran berhenti.",
            onColor: Colors.green,
          ),
          const Padding(
            padding: EdgeInsets.symmetric(vertical: 14),
            child: Divider(height: 1),
          ),
          Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Container(
                padding: const EdgeInsets.all(10),
                decoration: BoxDecoration(
                  color: Colors.orange.withOpacity(0.1),
                  shape: BoxShape.circle,
                ),
                child: Icon(
                  Icons.warning_amber_rounded,
                  color: Colors.orange.shade800,
                  size: 22,
                ),
              ),
              const SizedBox(width: 14),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      "Perhatian",
                      style: TextStyle(
                        fontSize: 15,
                        fontWeight: FontWeight.bold,
                        color: Colors.orange.shade800,
                      ),
                    ),
                    const SizedBox(height: 4),
                    Text(
                      "Tombol ini hanya bisa ditekan ketika alat sedang diam "
                      "atau tidak sedang melakukan pengeringan.",
                      style: TextStyle(
                        fontSize: 12.5,
                        color: Colors.grey.shade700,
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }

  /// =========================================================
  /// KARTU PANDUAN ISTILAH
  ///
  /// Menjelaskan dengan bahasa awam apa itu Heater, Fan Intake, dan
  /// Fan Exhaust, serta apa artinya ketika masing-masing ON / OFF.
  /// Diletakkan sebagai kartu statis (bukan dialog) supaya pengguna
  /// baru langsung bisa membaca tanpa perlu tap apa pun.
  /// =========================================================
  Widget termGuideCard() {
    return Container(
      width: double.infinity,
      padding: const EdgeInsets.all(20),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(25),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.05),
            blurRadius: 15,
            offset: const Offset(0, 8),
          ),
        ],
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          termGuideTile(
            icon: Icons.local_fire_department,
            color: Colors.red,
            title: "Heater (Pemanas)",
            description:
                "Elemen pemanas yang menghasilkan panas untuk mengeringkan biji kopi di dalam mesin.",
            onMeaning: "Sedang memanaskan udara di dalam mesin.",
            offMeaning: "Mati, suhu di dalam mesin akan turun perlahan.",
            onColor: Colors.red,
          ),
          const Padding(
            padding: EdgeInsets.symmetric(vertical: 14),
            child: Divider(height: 1),
          ),
          termGuideTile(
            icon: Icons.air,
            color: Colors.blue,
            title: "Fan Intake (Kipas Masuk)",
            description:
                "Kipas yang mengalirkan udara panas dari heater masuk ke ruang pengering, tempat biji kopi berada.",
            onMeaning: "Sedang mengalirkan udara panas masuk ke mesin.",
            offMeaning: "Berhenti, tidak ada udara panas baru yang masuk.",
            onColor: Colors.blue,
          ),
          const Padding(
            padding: EdgeInsets.symmetric(vertical: 14),
            child: Divider(height: 1),
          ),
          termGuideTile(
            icon: Icons.wind_power,
            color: Colors.green,
            title: "Fan Exhaust (Kipas Buang)",
            description:
                "Kipas yang membuang udara lembap sisa proses pengeringan ke luar mesin.",
            onMeaning: "Sedang membuang udara lembap keluar mesin.",
            offMeaning: "Berhenti, udara lembap tidak dikeluarkan.",
            onColor: Colors.green,
          ),
        ],
      ),
    );
  }

  /// Satu baris penjelasan istilah: ikon + judul + deskripsi singkat,
  /// lalu dua baris kecil "Saat ON" dan "Saat OFF" biar orang awam
  /// langsung paham konsekuensi status yang mereka lihat di layar.
  Widget termGuideTile({
    required IconData icon,
    required Color color,
    required String title,
    required String description,
    required String onMeaning,
    required String offMeaning,
    required Color onColor,
  }) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Container(
          padding: const EdgeInsets.all(10),
          decoration: BoxDecoration(
            color: color.withOpacity(0.1),
            shape: BoxShape.circle,
          ),
          child: Icon(icon, color: color, size: 22),
        ),
        const SizedBox(width: 14),
        Expanded(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                title,
                style: TextStyle(
                  fontSize: 15,
                  fontWeight: FontWeight.bold,
                  color: Colors.brown.shade800,
                ),
              ),
              const SizedBox(height: 4),
              Text(
                description,
                style: TextStyle(fontSize: 12.5, color: Colors.grey.shade700),
              ),
              const SizedBox(height: 8),
              Row(
                children: [
                  Container(
                    width: 8,
                    height: 8,
                    decoration: BoxDecoration(
                      shape: BoxShape.circle,
                      color: onColor,
                    ),
                  ),
                  const SizedBox(width: 6),
                  Expanded(
                    child: Text(
                      "ON : $onMeaning",
                      style: TextStyle(
                        fontSize: 12,
                        fontWeight: FontWeight.w600,
                        color: onColor,
                      ),
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 4),
              Row(
                children: [
                  Container(
                    width: 8,
                    height: 8,
                    decoration: BoxDecoration(
                      shape: BoxShape.circle,
                      color: Colors.grey.shade400,
                    ),
                  ),
                  const SizedBox(width: 6),
                  Expanded(
                    child: Text(
                      "OFF : $offMeaning",
                      style: TextStyle(
                        fontSize: 12,
                        fontWeight: FontWeight.w600,
                        color: Colors.grey.shade600,
                      ),
                    ),
                  ),
                ],
              ),
            ],
          ),
        ),
      ],
    );
  }

  /// Housing kipas bulat + baling-baling berputar (RotationTransition).
  /// Murni lingkaran (tanpa label di dalamnya) supaya bisa dipasang
  /// presisi di titik mana pun lewat Positioned dari luar.
  Widget fanCircle({
    required bool isOnStatus,
    required AnimationController controller,
    required Color color,
    double size = 54,
  }) {
    return Container(
      width: size,
      height: size,
      decoration: BoxDecoration(
        shape: BoxShape.circle,
        color: Colors.white,
        border: Border.all(
          color: isOnStatus ? color : Colors.grey.shade400,
          width: 3,
        ),
        boxShadow: isOnStatus
            ? [
                BoxShadow(
                  color: color.withOpacity(0.45),
                  blurRadius: 12,
                  spreadRadius: 1,
                ),
              ]
            : [],
      ),
      padding: EdgeInsets.all(size * 0.14),
      child: RotationTransition(
        turns: controller,
        child: CustomPaint(
          painter: _FanBladesPainter(
            color: isOnStatus ? color : Colors.grey.shade400,
          ),
        ),
      ),
    );
  }

  /// Chip status ON/OFF ringkas
  Widget statusChip(String label, bool status, Color color) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
      decoration: BoxDecoration(
        color: status ? color.withOpacity(0.15) : Colors.grey.withOpacity(0.1),
        borderRadius: BorderRadius.circular(20),
      ),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          Container(
            width: 8,
            height: 8,
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              color: status ? color : Colors.grey,
            ),
          ),
          const SizedBox(width: 6),
          Text(
            "$label ${status ? 'ON' : 'OFF'}",
            style: TextStyle(
              fontSize: 12,
              fontWeight: FontWeight.w600,
              color: status ? color : Colors.grey.shade600,
            ),
          ),
        ],
      ),
    );
  }
}

/// =========================================================
/// PAINTER: baling-baling kipas (4 blade), diputar via
/// RotationTransition dari luar.
/// =========================================================
class _FanBladesPainter extends CustomPainter {
  final Color color;
  _FanBladesPainter({required this.color});

  @override
  void paint(Canvas canvas, Size size) {
    final center = Offset(size.width / 2, size.height / 2);
    final r = size.width / 2;
    final paint = Paint()..color = color;

    for (int i = 0; i < 4; i++) {
      final angle = (pi / 2) * i;
      canvas.save();
      canvas.translate(center.dx, center.dy);
      canvas.rotate(angle);

      final blade = Path()
        ..moveTo(0, 0)
        ..quadraticBezierTo(r * 0.6, -r * 0.35, r * 0.9, 0)
        ..quadraticBezierTo(r * 0.6, r * 0.35, 0, 0)
        ..close();

      canvas.drawPath(blade, paint);
      canvas.restore();
    }

    canvas.drawCircle(center, r * 0.18, Paint()..color = Colors.white);
    canvas.drawCircle(
      center,
      r * 0.18,
      Paint()
        ..color = color
        ..style = PaintingStyle.stroke
        ..strokeWidth = 1.5,
    );
  }

  @override
  bool shouldRepaint(covariant _FanBladesPainter oldDelegate) =>
      oldDelegate.color != color;
}