import 'package:get/get.dart';
import 'dart:async';
import '../../../services/firestore_service.dart';
import '../../../models/schedule_model.dart';
import '../../../widgets/app_snackbar.dart';

class PatientSchedule {
  final String id;
  final String name;
  final String room;
  final String deviceId;
  final String medicineTime;
  final String fluidTime;
  final String timeOfDay;

  PatientSchedule({
    required this.id,
    required this.name,
    required this.room,
    required this.deviceId,
    required this.medicineTime,
    required this.fluidTime,
    required this.timeOfDay,
  });
}

class ScheduleController extends GetxController {
  final FirestoreService _firestoreService = FirestoreService();

  final selectedTab = 0.obs;
  final selectedDate = DateTime.now().obs;
  final allSchedules = <PatientSchedule>[].obs;
  final filteredSchedules = <PatientSchedule>[].obs;
  final isLoading = false.obs;

  StreamSubscription? _schedulesSubscription;

  final Map<int, String> _tabToTimeOfDay = {
    0: 'Pagi',
    1: 'Siang',
    2: 'Sore',
    3: 'Malam',
  };

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

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

  void _loadSchedules() {
    isLoading.value = true;
    _schedulesSubscription?.cancel();

    _schedulesSubscription = _firestoreService
        .getSchedulesStream(date: selectedDate.value)
        .listen(
      (scheduleModels) async {
        try {
          final List<PatientSchedule> items = [];

          for (var scheduleModel in scheduleModels) {
            try {
              final patient = await _firestoreService.getPatientById(scheduleModel.patientId);

              if (patient != null) {
                final roomName = await _getRoomName(patient.roomId);
                items.add(
                  PatientSchedule(
                    id: scheduleModel.id,
                    name: patient.namePatient,
                    room: roomName,
                    deviceId: patient.deviceId,
                    medicineTime: scheduleModel.medicineDetail,
                    fluidTime: scheduleModel.fluidDetail,
                    timeOfDay: scheduleModel.timeOfDay,
                  ),
                );
              }
            } catch (e) {
              continue;
            }
          }

          allSchedules.value = items;
          _applyTimeFilter();
          isLoading.value = false;
        } catch (e) {
          isLoading.value = false;
        }
      },
      onError: (error) {
        isLoading.value = false;
        AppSnackbar.error('Gagal memuat jadwal');
      },
    );
  }

  void _applyTimeFilter() {
    final selectedTime = _tabToTimeOfDay[selectedTab.value];
    filteredSchedules.value = allSchedules
        .where((schedule) => schedule.timeOfDay == selectedTime)
        .toList();
  }

  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 changeTab(int index) {
    selectedTab.value = index;
    _applyTimeFilter();
  }

  void selectDate(DateTime date) {
    selectedDate.value = date;
    _loadSchedules();
  }

  void refreshSchedules() {
    _loadSchedules();
  }

  Future<void> addSchedule(PatientSchedule schedule, DateTime scheduleDate) async {
    try {
      final patients = await _firestoreService.getPatientsStream().first;
      final patient = patients.firstWhereOrNull((p) => p.id == schedule.id);

      if (patient == null) throw Exception('Pasien tidak ditemukan');

      final scheduleModel = ScheduleModel(
        id: '',
        patientId: patient.id,
        medicineDetail: schedule.medicineTime,
        fluidDetail: schedule.fluidTime,
        scheduleDate: scheduleDate,
        timeOfDay: schedule.timeOfDay,
        createdAt: DateTime.now(),
      );

      await _firestoreService.addSchedule(scheduleModel);
      AppSnackbar.success('Jadwal berhasil ditambahkan');
    } catch (e) {
      AppSnackbar.error('Gagal menambahkan jadwal');
    }
  }

  Future<void> updateSchedule(String id, PatientSchedule updatedSchedule, DateTime scheduleDate) async {
    try {
      final patients = await _firestoreService.getPatientsStream().first;
      final patient = patients.firstWhereOrNull((p) => p.id == updatedSchedule.id);

      if (patient == null) throw Exception('Pasien tidak ditemukan');

      final scheduleModel = ScheduleModel(
        id: id,
        patientId: patient.id,
        medicineDetail: updatedSchedule.medicineTime,
        fluidDetail: updatedSchedule.fluidTime,
        scheduleDate: scheduleDate,
        timeOfDay: updatedSchedule.timeOfDay,
        createdAt: DateTime.now(),
      );

      await _firestoreService.updateSchedule(id, scheduleModel);
      AppSnackbar.success('Jadwal berhasil diperbarui');
    } catch (e) {
      AppSnackbar.error('Gagal memperbarui jadwal');
    }
  }

  Future<void> deleteSchedule(String id) async {
    try {
      await _firestoreService.deleteSchedule(id);
      AppSnackbar.success('Jadwal berhasil dihapus');
    } catch (e) {
      AppSnackbar.error('Gagal menghapus jadwal');
    }
  }

  Future<List<Map<String, String>>> getPatientsList() async {
    try {
      final patients = await _firestoreService.getPatientsStream().first;
      final List<Map<String, String>> result = [];

      for (var patient in patients) {
        try {
          final roomName = await _getRoomName(patient.roomId);
          result.add({
            'id': patient.id,
            'name': patient.namePatient,
            'room': roomName,
            'device': patient.deviceId,
          });
        } catch (e) {
          continue;
        }
      }

      return result;
    } catch (e) {
      return [];
    }
  }
}