import 'package:get/get.dart';
import 'dart:async';
import '../../../models/patient_model.dart';
import '../../../models/device_model.dart';
import '../../../models/realtime_monitoring_model.dart';
import '../../../models/history_model.dart';
import '../../../models/chart_data_point.dart';
import '../../../services/firestore_service.dart';
import '../../../services/realtime_database_service.dart';
import '../../../widgets/app_snackbar.dart';

class DeviceDetailController extends GetxController {
  final FirestoreService _firestoreService = FirestoreService();
  final RealtimeDatabaseService _realtimeService = RealtimeDatabaseService();

  String? deviceId;
  String? roomId;

  final deviceName = ''.obs;
  final patientName = ''.obs;
  final roomName = ''.obs;
  final dropsPerMinute = '0'.obs;
  final lastUpdate = DateTime.now().obs;
  final isServoActive = false.obs;
  final deviceStatus = 'disconnected'.obs;
  final isLoading = true.obs;
  final isBuzzerActive = false.obs;
  final RxList<ChartDataPoint> chartData = <ChartDataPoint>[].obs;

  StreamSubscription? _realtimeSubscription;
  StreamSubscription? _historySubscription;

  PatientModel? patient;
  DeviceModel? device;
  RealtimeMonitoringModel? realtimeData;

  @override
  void onInit() {
    super.onInit();
    _getArguments();
    if (deviceId != null && roomId != null) {
      _initializeDeviceDetail();
    } else {
      Get.back();
      AppSnackbar.error('Device ID tidak ditemukan');
    }
  }

  @override
  void onClose() {
    _realtimeSubscription?.cancel();
    _historySubscription?.cancel();
    super.onClose();
  }

  void _getArguments() {
    final args = Get.arguments as Map<String, dynamic>?;
    if (args != null) {
      deviceId = args['deviceId'];
      roomId = args['roomId'];
    }
  }

  Future<void> _initializeDeviceDetail() async {
    try {
      isLoading.value = true;

      await _loadPatientData();
      await _loadDeviceData();
      _listenToRealtimeData();
      _listenToHistoryData();

      isLoading.value = false;
    } catch (e) {
      isLoading.value = false;
      AppSnackbar.error('Gagal memuat data');
    }
  }

  Future<void> _loadPatientData() async {
    patient = await _firestoreService.getPatientByDeviceId(deviceId!);
    if (patient != null) {
      patientName.value = patient!.namePatient;
    }
  }

  Future<void> _loadDeviceData() async {
    device = await _firestoreService.getDeviceById(deviceId!);
    if (device != null) {
      deviceName.value = device!.devicesName;
      roomName.value = await _getRoomName(device!.roomId);
    }
  }

  Future<String> _getRoomName(String roomId) async {
    try {
      final rooms = await _firestoreService.getRoomsStream().first;
      final room = rooms.firstWhereOrNull(
        (r) =>
            r.id == roomId || r.roomName.toLowerCase() == roomId.toLowerCase(),
      );
      return room?.roomName ?? roomId;
    } catch (e) {
      return roomId;
    }
  }

  void _listenToRealtimeData() {
    final dbRoomId = roomId!.toLowerCase().replaceAll(' ', '_');

    _realtimeSubscription = _realtimeService
        .getDeviceStream(dbRoomId, deviceId!)
        .listen((data) {
          if (data != null) {
            realtimeData = data;
            dropsPerMinute.value = data.dropRate.toStringAsFixed(0);
            lastUpdate.value = data.lastUpdate;
            isServoActive.value = data.servoOpen;
            deviceStatus.value = data.deviceStatus;
            isBuzzerActive.value = data.buzzerActive;
          }
        }, onError: (error) => AppSnackbar.error('Koneksi realtime terputus'));
  }

  void _listenToHistoryData() {
    _historySubscription = _firestoreService
        .getDeviceHistoriesStream(deviceId!)
        .listen(
          (histories) {
            if (histories.isNotEmpty) {
              _processHistoryData(histories);
            } else {
              chartData.value = [];
            }
          },
          onError: (error) {
            chartData.value = [];
            AppSnackbar.error('Gagal memuat data history');
          },
        );
  }

  void _processHistoryData(List<HistoryModel> histories) {
    // Ambil 10 data TERBARU
    histories.sort((a, b) => b.timestamp.compareTo(a.timestamp));
    final latestHistories = histories.take(10).toList();

    // Urutkan lagi dari lama -> baru supaya grafik terbaca kiri ke kanan
    latestHistories.sort((a, b) => a.timestamp.compareTo(b.timestamp));

    final List<ChartDataPoint> points = latestHistories.map((history) {
      return ChartDataPoint(
        timestamp: history.timestamp,
        dropsPerMinute: history.dropPerMinute,
      );
    }).toList();

    chartData.value = points;
  }

  Future<void> toggleServo(bool value) async {
    try {
      final dbRoomId = roomId!.toLowerCase().replaceAll(' ', '_');
      await _realtimeService.controlServo(dbRoomId, deviceId!, value);
      isServoActive.value = value;
      AppSnackbar.success(value ? 'Infus dibuka' : 'Infus ditutup');
    } catch (e) {
      AppSnackbar.error('Gagal mengontrol servo');
    }
  }

  String getLastUpdateText() {
    final difference = DateTime.now().difference(lastUpdate.value);
    if (difference.inMinutes < 1) return 'just now';
    if (difference.inMinutes < 60) return '${difference.inMinutes}m ago';
    if (difference.inHours < 24) return '${difference.inHours}h ago';
    return '${difference.inDays}d ago';
  }

  void navigateToHistory() {
    Get.toNamed(
      '/history',
      arguments: {
        'deviceId': deviceId,
        'deviceName': deviceName.value,
        'patientName': patientName.value,
      },
    );
  }

  Future<void> turnOffBuzzer() async {
    try {
      final dbRoomId = roomId!.toLowerCase().replaceAll(' ', '_');
      await _realtimeService.controlBuzzer(dbRoomId, deviceId!, false);
      isBuzzerActive.value = false;
      AppSnackbar.success('Buzzer dimatikan');
    } catch (e) {
      AppSnackbar.error('Gagal mematikan buzzer');
    }
  }

  Future<void> refreshData() async {
    await _loadDeviceData();
  }
}