//import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:jago/services/db_helper.dart';
import 'dart:async';

class NotificationService {
  static final NotificationService _instance = NotificationService._internal();
  factory NotificationService() => _instance;

  final DatabaseReference _database = FirebaseDatabase.instance.ref();
  final DatabaseHelper dbHelper = DatabaseHelper();
  int ageInWeeks = 2;
  
  // Inisialisasi notifikasi lokal
  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
  
  
  // Daftar subscription untuk dibersihkan saat dispose
  final List<StreamSubscription> _subscriptions = [];
  
  // Flag untuk mencegah duplikasi notifikasi dalam waktu singkat
  final Map<String, DateTime> _lastNotificationTimes = {};
  
  // Flag untuk menandai apakah service sudah diinisialisasi
  bool _isInitialized = false;

  NotificationService._internal();

  Future<void> initialize() async {
    if (_isInitialized) return;
    
    print("🚀 Menginisialisasi NotificationService...");
    
    // Inisialisasi database
    await dbHelper.checkTables();
    
    // Inisialisasi notifikasi lokal
    const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher');
    final InitializationSettings initializationSettings = InitializationSettings(android: initializationSettingsAndroid);
    await flutterLocalNotificationsPlugin.initialize(initializationSettings);

    // Setup Firebase Messaging
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      _showNotification(message.notification?.title ?? 'Notifikasi', message.notification?.body ?? '');
    });

    FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
    
    // Ambil umur ayam dari Firebase
    _fetchAgeFromFirebase();
    
    // Mulai memantau data
    _startMonitoring();
    
    _isInitialized = true;
    print("✅ NotificationService berhasil diinisialisasi");
  }

  void dispose() {
    for (var subscription in _subscriptions) {
      subscription.cancel();
    }
    _subscriptions.clear();
    _isInitialized = false;
    print("🛑 NotificationService dihentikan");
  }

  static Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
    print("📱 Menerima pesan di background: ${message.notification?.title}");
    await NotificationService().initialize();
    NotificationService()._showNotification(
      message.notification?.title ?? 'Notifikasi',
      message.notification?.body ?? ''
    );
  }

  Future<void> _showNotification(String title, String body) async {
    const AndroidNotificationDetails androidPlatformChannelSpecifics = AndroidNotificationDetails(
      'Jago',
      'Notification',
      channelDescription: 'Cek Notification!!!',
      importance: Importance.max,
      priority: Priority.high,
    );
    const NotificationDetails platformChannelSpecifics = NotificationDetails(android: androidPlatformChannelSpecifics);
    await flutterLocalNotificationsPlugin.show(
      0,
      title,
      body,
      platformChannelSpecifics,
    );
  }

  void _fetchAgeFromFirebase() {
    print("🐔 Memuat umur ayam dari Firebase...");
    final subscription = _database.child("chicken_age").onValue.listen((event) {
      final data = event.snapshot.value;
      if (data != null) {
        ageInWeeks = int.parse(data.toString());
        print("🐔 Umur ayam diperbarui: $ageInWeeks minggu");
      }
    });
    _subscriptions.add(subscription);
  }

  void _startMonitoring() {
    print("👀 Mulai memantau data dari Firebase...");
    
    // Pastikan umur ayam diambil terlebih dahulu
    _fetchAgeFromFirebase();
    
    // Delay sedikit untuk memastikan umur ayam sudah diambil
    Future.delayed(Duration(milliseconds: 500), () {
      _loadEmergencyData();
      _loadFuzzyData();
      _loadStatusData();
      _loadSensorData();
    });
  }

  // Memuat data emergency dari Firebase
  void _loadEmergencyData() {
    try {
      print("🔄 Memuat data emergency...");
      final subscription = _database.child('emergency').onValue.listen((event) {
        if (event.snapshot.value != null) {
          try {
            print("🔥 Data emergency diterima: ${event.snapshot.value}");
            final Map<dynamic, dynamic> emergencyData = event.snapshot.value as Map;
            
            if (emergencyData['low_temperature'] == true) {
              print("🔥 Kondisi emergency: Suhu sangat rendah terdeteksi");
              _addNotification('Suhu sangat rendah! Kondisi darurat terdeteksi.');
            }
            
            if (emergencyData['high_temperature'] == true) {
              print("🔥 Kondisi emergency: Suhu sangat tinggi terdeteksi");
              _addNotification('Suhu sangat tinggi! Kondisi darurat terdeteksi.');
            }
            
            if (emergencyData['low_humidity'] == true) {
              print("🔥 Kondisi emergency: Kelembapan sangat rendah terdeteksi");
              _addNotification('Kelembapan sangat rendah! Kondisi darurat terdeteksi.');
            }
            
            if (emergencyData['high_humidity'] == true) {
              print("🔥 Kondisi emergency: Kelembapan sangat tinggi terdeteksi");
              _addNotification('Kelembapan sangat tinggi! Kondisi darurat terdeteksi.');
            }
          } catch (e) {
            print("❌ Error saat memproses data emergency: $e");
          }
        }
      });
      _subscriptions.add(subscription);
      
      // Juga dengarkan perubahan pada node emergency
      final changeSubscription = _database.child('emergency').onChildChanged.listen((event) {
        if (event.snapshot.value == true) {
          String type = event.snapshot.key ?? "unknown";
          String message = "";
          
          print("🔥 Perubahan emergency terdeteksi: ${event.snapshot.key} = ${event.snapshot.value}");
          
          if (type == "low_temperature") {
            message = "Suhu sangat rendah! Kondisi darurat terdeteksi.";
          } else if (type == "high_temperature") {
            message = "Suhu sangat tinggi! Kondisi darurat terdeteksi.";
          } else if (type == "low_humidity") {
            message = "Kelembapan sangat rendah! Kondisi darurat terdeteksi.";
          } else if (type == "high_humidity") {
            message = "Kelembapan sangat tinggi! Kondisi darurat terdeteksi.";
          }
          
          if (message.isNotEmpty) {
            _addNotification(message);
          }
        }
      });
      _subscriptions.add(changeSubscription);
    } catch (e) {
      print("❌ Error saat setup listener emergency: $e");
    }
  }

  // Memuat data fuzzy dari Firebase
  void _loadFuzzyData() {
    try {
      print("🔄 Memuat data fuzzy...");
      // Memuat data fuzzy suhu
      final tempSubscription = _database.child('fuzzy/temperature').onValue.listen((event) {
        if (event.snapshot.value != null) {
          try {
            print("🧠 Data fuzzy temperature diterima: ${event.snapshot.value}");
            final Map<dynamic, dynamic> fuzzyTemp = event.snapshot.value as Map;
            
            if (fuzzyTemp.containsKey('veryHigh') && (fuzzyTemp['veryHigh'] as num).toDouble() > 0.7) {
              double value = (fuzzyTemp['veryHigh'] as num).toDouble();
              print("🧠 Fuzzy suhu sangat tinggi terdeteksi: $value");
              _addNotification('Fuzzy: Suhu sangat tinggi (${value.toStringAsFixed(2)})');
            }
            
            if (fuzzyTemp.containsKey('veryLow') && (fuzzyTemp['veryLow'] as num).toDouble() > 0.7) {
              double value = (fuzzyTemp['veryLow'] as num).toDouble();
              print("🧠 Fuzzy suhu sangat rendah terdeteksi: $value");
              _addNotification('Fuzzy: Suhu sangat rendah (${value.toStringAsFixed(2)})');
            }
          } catch (e) {
            print("❌ Error saat memproses data fuzzy temperature: $e");
          }
        }
      });
      _subscriptions.add(tempSubscription);
      
      // Memuat data fuzzy kelembapan
      final humSubscription = _database.child('fuzzy/humidity').onValue.listen((event) {
        if (event.snapshot.value != null) {
          try {
            print("🧠 Data fuzzy humidity diterima: ${event.snapshot.value}");
            final Map<dynamic, dynamic> fuzzyHum = event.snapshot.value as Map;
            
            if (fuzzyHum.containsKey('veryHigh') && (fuzzyHum['veryHigh'] as num).toDouble() > 0.7) {
              double value = (fuzzyHum['veryHigh'] as num).toDouble();
              print("🧠 Fuzzy kelembapan sangat tinggi terdeteksi: $value");
              _addNotification('Fuzzy: Kelembapan sangat tinggi (${value.toStringAsFixed(2)})');
            }
            
            if (fuzzyHum.containsKey('veryLow') && (fuzzyHum['veryLow'] as num).toDouble() > 0.7) {
              double value = (fuzzyHum['veryLow'] as num).toDouble();
              print("🧠 Fuzzy kelembapan sangat rendah terdeteksi: $value");
              _addNotification('Fuzzy: Kelembapan sangat rendah (${value.toStringAsFixed(2)})');
            }
          } catch (e) {
            print("❌ Error saat memproses data fuzzy humidity: $e");
          }
        }
      });
      _subscriptions.add(humSubscription);
    } catch (e) {
      print("❌ Error saat setup listener fuzzy: $e");
    }
  }

  // Memuat data status dari Firebase
  void _loadStatusData() {
    try {
      print("🔄 Memuat data status...");
      // Memuat status suhu
      final tempSubscription = _database.child('status/temperature').onValue.listen((event) {
        if (event.snapshot.value != null) {
          try {
            String tempStatus = event.snapshot.value.toString();
            print("📊 Status suhu diterima: $tempStatus");
            
            if (tempStatus.contains("Sangat Tinggi") || tempStatus.contains("Sangat Rendah")) {
              print("📊 Status suhu kritis terdeteksi: $tempStatus");
              _addNotification('Status: $tempStatus');
            }
          } catch (e) {
            print("❌ Error saat memproses data status temperature: $e");
          }
        }
      });
      _subscriptions.add(tempSubscription);
      
      // Memuat status kelembapan
      final humSubscription = _database.child('status/humidity').onValue.listen((event) {
        if (event.snapshot.value != null) {
          try {
            String humStatus = event.snapshot.value.toString();
            print("📊 Status kelembapan diterima: $humStatus");
            
            if (humStatus.contains("Sangat Tinggi") || humStatus.contains("Sangat Rendah")) {
              print("📊 Status kelembapan kritis terdeteksi: $humStatus");
              _addNotification('Status: $humStatus');
            }
          } catch (e) {
            print("❌ Error saat memproses data status humidity: $e");
          }
        }
      });
      _subscriptions.add(humSubscription);
      
      // Mendengarkan perubahan pada node status
      final statusSubscription = _database.child('status').onChildChanged.listen((event) {
        String status = event.snapshot.value.toString();
        String type = event.snapshot.key ?? "unknown";
        print("📊 Perubahan status terdeteksi: $type = $status");
        
        if (status.contains("Sangat Tinggi") || status.contains("Sangat Rendah")) {
          print("📊 Status kritis pada perubahan terdeteksi: $type = $status");
          _addNotification('Status $type: $status');
        }
      });
      _subscriptions.add(statusSubscription);
    } catch (e) {
      print("❌ Error saat setup listener status: $e");
    }
  }

  void _loadSensorData() {
    print("🔄 Memuat data sensor...");
    final subscription = _database.child('sensor').onValue.listen((event) {
      if (event.snapshot.value != null) {
        try {
          final Map<dynamic, dynamic> sensorData = event.snapshot.value as Map;
          double temperature = (sensorData['temperature'] as num).toDouble();
          double humidity = (sensorData['Humidity'] as num).toDouble();
          
          print("🌡️ Data sensor diterima: Suhu=$temperature°C, Kelembapan=$humidity%");

          // Tentukan rentang suhu berdasarkan umur ayam
          double tempMin, tempMax, humMin, humMax;
          switch (ageInWeeks) {
            case 1:
              tempMin = 33.0;
              tempMax = 35.0;
              humMin = 60.0;
              humMax = 70.0;
              break;
            case 2:
              tempMin = 30.0;
              tempMax = 33.0;
              humMin = 60.0;
              humMax = 65.0;
              break;
            case 3:
              tempMin = 28.0;
              tempMax = 30.0;
              humMin = 60.0;
              humMax = 65.0;
              break;
            case 4:
              tempMin = 25.0;
              tempMax = 28.0;
              humMin = 55.0;
              humMax = 60.0;
              break;
            default:
              tempMin = 25.0;
              tempMax = 28.0;
              humMin = 55.0;
              humMax = 60.0;
          }

          // Buat notifikasi berdasarkan kondisi suhu
          if (temperature < tempMin - 2) {
            print("🌡️ Suhu sangat rendah terdeteksi: $temperature°C");
            _addNotification('Suhu sangat rendah: $temperature°C (Kritis)');
          } else if (temperature < tempMin) {
            print("🌡️ Suhu rendah terdeteksi: $temperature°C");
            _addNotification('Suhu rendah: $temperature°C');
          } else if (temperature > tempMax + 2) {
            print("🌡️ Suhu sangat tinggi terdeteksi: $temperature°C");
            _addNotification('Suhu sangat tinggi: $temperature°C (Kritis)');
          } else if (temperature > tempMax) {
            print("🌡️ Suhu tinggi terdeteksi: $temperature°C");
            _addNotification('Suhu tinggi: $temperature°C');
          } else if (temperature >= tempMin && temperature <= tempMax) {
            print("🌡️ Suhu normal terdeteksi: $temperature°C");
            _addNotification('Suhu normal: $temperature°C (Optimal)');
          }

          // Buat notifikasi berdasarkan kondisi kelembapan
          if (humidity < humMin - 5) {
            print("💧 Kelembapan sangat rendah terdeteksi: $humidity%");
            _addNotification('Kelembapan sangat rendah: $humidity% (Kritis)');
          } else if (humidity < humMin) {
            print("💧 Kelembapan rendah terdeteksi: $humidity%");
            _addNotification('Kelembapan rendah: $humidity%');
          } else if (humidity > humMax + 5) {
            print("💧 Kelembapan sangat tinggi terdeteksi: $humidity%");
            _addNotification('Kelembapan sangat tinggi: $humidity% (Kritis)');
          } else if (humidity > humMax) {
            print("💧 Kelembapan tinggi terdeteksi: $humidity%");
            _addNotification('Kelembapan tinggi: $humidity%');
          } else if (humidity >= humMin && humidity <= humMax) {
            print("💧 Kelembapan normal terdeteksi: $humidity%");
            _addNotification('Kelembapan normal: $humidity% (Optimal)');
          }
        } catch (e) {
          print("❌ Error saat memproses data sensor: $e");
        }
      }
    });
    _subscriptions.add(subscription);
  }

  // Fungsi untuk menambahkan notifikasi baru
  void _addNotification(String event) {
    print("🔍 Mencoba menambahkan notifikasi: $event");
    
    // Cek apakah notifikasi serupa sudah ditambahkan dalam 5 menit terakhir
    if (_lastNotificationTimes.containsKey(event)) {
      DateTime lastTime = _lastNotificationTimes[event]!;
      Duration difference = DateTime.now().difference(lastTime);
      
      // Jika notifikasi serupa sudah ditambahkan dalam 5 menit terakhir, abaikan
      if (difference.inMinutes < 5) {
        print("⏱️ Notifikasi serupa sudah ditambahkan ${difference.inSeconds} detik yang lalu, diabaikan: $event");
        return;
      }
    }
    
    // Catat waktu notifikasi ini ditambahkan
    _lastNotificationTimes[event] = DateTime.now();
    
    // Tambahkan informasi umur ayam ke event
    String eventWithAge = "$event [Umur: $ageInWeeks minggu]";
    
    // Simpan ke database lokal
    dbHelper.insertNotification(eventWithAge).then((_) {
      print("✅ Berhasil menyimpan notifikasi: $eventWithAge");
      
      // Tampilkan notifikasi lokal
      _showNotification('Peringatan Kandang Ayam', event);
    }).catchError((error) {
      print("❌ Gagal menyimpan notifikasi: $error");
    });
  }
} 