import 'package:localstore/localstore.dart';

/// A rendered notification's bookkeeping, keyed by the Nextcloud notification
/// id (`nid`). Lets a later delete-push (which only carries the `nid`) find and
/// cancel the exact tray notification that was shown.
class NidEntry {
  final int nid;
  final int notificationId;
  final String tag;
  final String? chatToken;

  const NidEntry({
    required this.nid,
    required this.notificationId,
    required this.tag,
    this.chatToken,
  });

  Map<String, dynamic> toJson() => {
    'nid': nid,
    'notificationId': notificationId,
    'tag': tag,
    if (chatToken != null) 'chatToken': chatToken,
  };

  factory NidEntry.fromJson(Map<String, dynamic> json) => NidEntry(
    nid: (json['nid'] as num).toInt(),
    notificationId: (json['notificationId'] as num).toInt(),
    tag: json['tag'] as String,
    chatToken: json['chatToken'] as String?,
  );
}

/// Persists the `nid → tray notification` mapping via [Localstore] so both the
/// foreground and background isolates can resolve delete-pushes.
class NidStore {
  static const _collection = 'push_nids';

  final Localstore _db;

  NidStore({Localstore? db}) : _db = db ?? Localstore.instance;

  Future<void> put(NidEntry entry) =>
      _db.collection(_collection).doc('${entry.nid}').set(entry.toJson());

  Future<NidEntry?> get(int nid) async {
    final data = await _db.collection(_collection).doc('$nid').get();
    if (data == null) return null;
    return NidEntry.fromJson(data);
  }

  Future<void> delete(int nid) =>
      _db.collection(_collection).doc('$nid').delete();

  Future<List<NidEntry>> all() async {
    final docs = await _db.collection(_collection).get();
    if (docs == null) return const [];
    return docs.values
        .map((e) => NidEntry.fromJson(e as Map<String, dynamic>))
        .toList();
  }

  Future<void> clear() async {
    final docs = await _db.collection(_collection).get();
    if (docs == null) return;
    for (final id in docs.keys) {
      // Localstore keys are the full document paths (/push_nids/<nid>).
      final nid = int.tryParse(id.split('/').last);
      if (nid != null) await delete(nid);
    }
  }
}
