import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'dart:async';
import '../../../services/firestore_service.dart';
import '../../../services/realtime_database_service.dart';
import '../../../models/patient_model.dart';
import '../../../models/room_model.dart';
import '../../../models/realtime_monitoring_model.dart';
import '../../../widgets/app_snackbar.dart';

class InfusMonitoring {
  final String id;
  final String patientName;
  final String deviceId;
  final String room;
  final String roomId;
  final String dropsPerMinute;
  final DateTime lastUpdate;
  final String deviceStatus;

  InfusMonitoring({
    required this.id,
    required this.patientName,
    required this.deviceId,
    required this.room,
    required this.roomId,
    required this.dropsPerMinute,
    required this.lastUpdate,
    required this.deviceStatus,
  });
}

class HomeController extends GetxController {
  final searchController = TextEditingController();
  final FirestoreService _firestoreService = FirestoreService();
  final RealtimeDatabaseService _realtimeService = RealtimeDatabaseService();

  final currentCarouselIndex = 0.obs;
  final bannerImages = [
    'assets/images/banner-slider1.png',
    'assets/images/banner-slider2.png',
  ];

  final monitoringList = <InfusMonitoring>[].obs;
  final isLoading = true.obs;

  StreamSubscription? _patientsSubscription;
  StreamSubscription? _realtimeSubscription;

  @override
  void onInit() {
    super.onInit();
    _initializeMonitoring();
  }

  @override
  void onClose() {
    searchController.dispose();
    _patientsSubscription?.cancel();
    _realtimeSubscription?.cancel();
    super.onClose();
  }

  void _initializeMonitoring() {
    isLoading.value = true;

    _patientsSubscription = _firestoreService.getPatientsStream().listen(
      (patients) async {
        _realtimeSubscription = _realtimeService.getAllDevicesStream().listen((
          realtimeDevices,
        ) {
          _combineMonitoringData(patients, realtimeDevices);
        });
      },
      onError: (error) {
        isLoading.value = false;
        AppSnackbar.error('Gagal memuat data');
      },
    );
  }

  void _combineMonitoringData(
    List<PatientModel> patients,
    List<RealtimeMonitoringModel> realtimeDevices,
  ) async {
    final List<InfusMonitoring> combinedData = [];

    for (var patient in patients) {
      final realtimeDevice = realtimeDevices.firstWhereOrNull(
        (device) => device.deviceId == patient.deviceId,
      );

      final roomName = await _getRoomName(patient.roomId);
      final dropRate = realtimeDevice?.dropRate ?? 0.0;
      final lastUpdate = realtimeDevice?.lastUpdate ?? DateTime.now();
      final deviceStatus = realtimeDevice?.deviceStatus ?? 'disconnected';

      combinedData.add(
        InfusMonitoring(
          id: patient.id,
          patientName: patient.namePatient,
          deviceId: patient.deviceId,
          room: roomName,
          roomId: patient.roomId,
          dropsPerMinute: '${dropRate.toStringAsFixed(0)} tpm',
          lastUpdate: lastUpdate,
          deviceStatus: deviceStatus,
        ),
      );
    }

    monitoringList.value = combinedData;
    isLoading.value = false;
  }

  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;
    }
  }

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

  void updateCarouselIndex(int index) {
    currentCarouselIndex.value = index;
  }

  void showLogoutDialog(BuildContext context) {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          backgroundColor: Colors.white,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(15),
          ),
          title: const Text(
            'Konfirmasi Logout',
            style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
          ),
          content: const Text(
            'Yakin ingin keluar?',
            style: TextStyle(fontSize: 16),
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.of(context).pop(),
              style: TextButton.styleFrom(
                foregroundColor: Colors.grey[600],
                padding: const EdgeInsets.symmetric(
                  vertical: 12,
                  horizontal: 20,
                ),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(8),
                ),
              ),
              child: const Text('Batal'),
            ),
            ElevatedButton(
              onPressed: () async {
                Navigator.of(context).pop();
                await FirebaseAuth.instance.signOut();
                Get.offAllNamed('/login');
              },
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.red,
                foregroundColor: Colors.white,
                padding: const EdgeInsets.symmetric(
                  vertical: 12,
                  horizontal: 20,
                ),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(8),
                ),
              ),
              child: const Text(
                'Logout',
                style: TextStyle(fontWeight: FontWeight.bold),
              ),
            ),
          ],
        );
      },
    );
  }

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