import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';

/// Represents the reminder status for a single prescription item,
/// identified by AppointmentNo, ItemDescription, ItemID & ProjectID.
class PrescriptionReminderEntry {
  final num appointmentNo;
  final String itemDescription;
  final num itemID;
  final num projectID;
  bool hasReminder;

  PrescriptionReminderEntry({
    required this.appointmentNo,
    required this.itemDescription,
    required this.itemID,
    required this.projectID,
    required this.hasReminder,
  });

  factory PrescriptionReminderEntry.fromJson(Map<String, dynamic> json) {
    return PrescriptionReminderEntry(
      appointmentNo: json['appointmentNo'] ?? 0,
      itemDescription: json['itemDescription'] ?? '',
      itemID: json['itemID'] ?? 0,
      projectID: json['projectID'] ?? 0,
      hasReminder: json['hasReminder'] ?? false,
    );
  }

  Map<String, dynamic> toJson() => {
        'appointmentNo': appointmentNo,
        'itemDescription': itemDescription,
        'itemID': itemID,
        'projectID': projectID,
        'hasReminder': hasReminder,
      };

  /// Unique key to identify this prescription item.
  String get uniqueKey => '${appointmentNo}_${itemID}_${projectID}';
}

/// Service to manage prescription reminder statuses in SharedPreferences.
/// All entries are stored under the single key [prescriptionRemindersKey].
class PrescriptionReminderPrefsService {
  static const String prescriptionRemindersKey = 'PrescriptionReminders';

  static PrescriptionReminderPrefsService? _instance;
  static PrescriptionReminderPrefsService get instance {
    _instance ??= PrescriptionReminderPrefsService._();
    return _instance!;
  }

  PrescriptionReminderPrefsService._();

  /// Reads all reminder entries from SharedPreferences.
  Future<List<PrescriptionReminderEntry>> getAllReminders() async {
    final prefs = await SharedPreferences.getInstance();
    final jsonString = prefs.getString(prescriptionRemindersKey);
    if (jsonString == null || jsonString.isEmpty) return [];
    try {
      final List<dynamic> jsonList = json.decode(jsonString);
      return jsonList
          .map((e) => PrescriptionReminderEntry.fromJson(e as Map<String, dynamic>))
          .toList();
    } catch (_) {
      return [];
    }
  }

  /// Saves the full list of reminder entries to SharedPreferences.
  Future<void> _saveAllReminders(List<PrescriptionReminderEntry> entries) async {
    final prefs = await SharedPreferences.getInstance();
    final jsonString = json.encode(entries.map((e) => e.toJson()).toList());
    await prefs.setString(prescriptionRemindersKey, jsonString);
  }

  /// Returns the reminder status for a specific item.
  /// Returns null if no entry exists for this item.
  Future<bool?> getReminderStatus({
    required num appointmentNo,
    required num itemID,
    required num projectID,
  }) async {
    final entries = await getAllReminders();
    final key = '${appointmentNo}_${itemID}_${projectID}';
    try {
      final entry = entries.firstWhere((e) => e.uniqueKey == key);
      return entry.hasReminder;
    } catch (_) {
      return null;
    }
  }

  /// Saves or updates the reminder status for a specific prescription item.
  Future<void> setReminderStatus({
    required num appointmentNo,
    required String itemDescription,
    required num itemID,
    required num projectID,
    required bool hasReminder,
  }) async {
    final entries = await getAllReminders();
    final key = '${appointmentNo}_${itemID}_${projectID}';
    final existingIndex = entries.indexWhere((e) => e.uniqueKey == key);

    if (existingIndex != -1) {
      // Update existing entry
      entries[existingIndex].hasReminder = hasReminder;
    } else {
      // Add new entry
      entries.add(PrescriptionReminderEntry(
        appointmentNo: appointmentNo,
        itemDescription: itemDescription,
        itemID: itemID,
        projectID: projectID,
        hasReminder: hasReminder,
      ));
    }

    await _saveAllReminders(entries);
  }

  /// Removes a specific reminder entry from SharedPreferences.
  Future<void> removeReminderEntry({
    required num appointmentNo,
    required num itemID,
    required num projectID,
  }) async {
    final entries = await getAllReminders();
    final key = '${appointmentNo}_${itemID}_${projectID}';
    entries.removeWhere((e) => e.uniqueKey == key);
    await _saveAllReminders(entries);
  }

  /// Clears all prescription reminder entries from SharedPreferences.
  Future<void> clearAllReminders() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove(prescriptionRemindersKey);
  }
}

