// This file is automatically generated, so please do not edit it.
// @generated by `flutter_rust_bridge`@ 2.12.0.

// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import

import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
import 'package:freezed_annotation/freezed_annotation.dart' hide protected;

import '../frb_generated.dart';
import 'chat_summary.dart';
import 'error.dart';
import 'groups.dart';
import 'messages.dart';

part 'chat_list.freezed.dart';

// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `assert_fields_are_eq`, `assert_fields_are_eq`, `clone`, `clone`, `clone`, `clone`, `eq`, `eq`, `fmt`, `fmt`, `fmt`, `fmt`, `from`, `from`, `from`

/// Sets the pin order for a chat.
///
/// Pinned chats appear before unpinned chats in the chat list.
/// Lower pin_order values appear first among pinned chats.
///
/// - `pin_order = None` = unpin the chat
/// - `pin_order = Some(n)` = pin the chat with order n
Future<void> setChatPinOrder({
  required String accountPubkey,
  required String mlsGroupId,
  PlatformInt64? pinOrder,
}) => RustLib.instance.api.crateApiChatListSetChatPinOrder(
  accountPubkey: accountPubkey,
  mlsGroupId: mlsGroupId,
  pinOrder: pinOrder,
);

/// Mutes a chat for the specified duration.
///
/// Notifications for this chat will be suppressed until the duration expires.
/// Use [`ChatMuteDuration::Forever`] to mute indefinitely.
Future<void> muteChat({
  required String accountPubkey,
  required String mlsGroupId,
  required ChatMuteDuration duration,
}) => RustLib.instance.api.crateApiChatListMuteChat(
  accountPubkey: accountPubkey,
  mlsGroupId: mlsGroupId,
  duration: duration,
);

/// Unmutes a previously muted chat.
///
/// Notifications for this chat will resume immediately.
Future<void> unmuteChat({
  required String accountPubkey,
  required String mlsGroupId,
}) => RustLib.instance.api.crateApiChatListUnmuteChat(
  accountPubkey: accountPubkey,
  mlsGroupId: mlsGroupId,
);

/// Retrieves the chat list for an account.
///
/// Returns a list of chat summaries sorted by:
/// 1. Pinned chats first (sorted by pin_order, lower values first)
/// 2. Unpinned chats sorted by last activity (most recent first)
/// 3. Groups without messages are sorted by creation date
Future<List<ChatSummary>> getChatList({required String accountPubkey}) =>
    RustLib.instance.api.crateApiChatListGetChatList(
      accountPubkey: accountPubkey,
    );

Future<List<ChatSummary>> fetchChatListSnapshot({
  required String accountPubkey,
}) => RustLib.instance.api.crateApiChatListFetchChatListSnapshot(
  accountPubkey: accountPubkey,
);

Future<List<ChatSummary>> fetchArchivedChatListSnapshot({
  required String accountPubkey,
}) => RustLib.instance.api.crateApiChatListFetchArchivedChatListSnapshot(
  accountPubkey: accountPubkey,
);

/// Subscribe to real-time chat list updates for an account.
///
/// The stream first emits an `InitialSnapshot` containing all current chats,
/// then emits `Update` items as chats are created, receive new messages, or have messages deleted.
///
/// The initial snapshot is race-condition free: any updates that arrive between
/// subscribing and fetching are merged into the snapshot.
Stream<ChatListStreamItem> subscribeToChatList({
  required String accountPubkey,
}) => RustLib.instance.api.crateApiChatListSubscribeToChatList(
  accountPubkey: accountPubkey,
);

Stream<ChatListStreamItem> subscribeToArchivedChatList({
  required String accountPubkey,
}) => RustLib.instance.api.crateApiChatListSubscribeToArchivedChatList(
  accountPubkey: accountPubkey,
);

@freezed
sealed class ChatListStreamItem with _$ChatListStreamItem {
  const ChatListStreamItem._();

  /// Initial snapshot of all chats at subscription time
  const factory ChatListStreamItem.initialSnapshot({
    required List<ChatSummary> items,
  }) = ChatListStreamItem_InitialSnapshot;

  /// Real-time update for a single chat
  const factory ChatListStreamItem.update({
    required ChatListUpdate update,
  }) = ChatListStreamItem_Update;
}

/// A real-time update for the chat list.
///
/// Contains the trigger indicating what changed and the complete,
/// current state of the affected chat item.
class ChatListUpdate {
  final ChatListUpdateTrigger trigger;
  final ChatSummary item;

  const ChatListUpdate({
    required this.trigger,
    required this.item,
  });

  @override
  int get hashCode => trigger.hashCode ^ item.hashCode;

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is ChatListUpdate &&
          runtimeType == other.runtimeType &&
          trigger == other.trigger &&
          item == other.item;
}

/// What triggered a chat list update in the stream.
enum ChatListUpdateTrigger {
  /// A new group was created or joined
  newGroup,

  /// A new message updated the chat's last message preview
  newLastMessage,

  /// The last message in a chat was deleted
  lastMessageDeleted,

  /// A chat's archive status changed
  chatArchiveChanged,

  /// This account was removed from the group by an admin.
  removedFromGroup,

  /// The chat's mute status changed.
  chatMuteChanged,

  /// This account left the group.
  leftGroup,

  /// All messages in the chat were cleared.
  chatCleared,

  /// The chat was deleted.
  chatDeleted,

  /// A user was blocked or unblocked.
  userBlockChanged,

  /// A foreground catch-up replay refreshed this chat from the local snapshot.
  snapshotRefresh,
}

@freezed
sealed class ChatMuteDuration with _$ChatMuteDuration {
  const ChatMuteDuration._();

  /// Mute for 1 hour
  const factory ChatMuteDuration.oneHour() = ChatMuteDuration_OneHour;

  /// Mute for 8 hours
  const factory ChatMuteDuration.eightHours() = ChatMuteDuration_EightHours;

  /// Mute for 1 day
  const factory ChatMuteDuration.oneDay() = ChatMuteDuration_OneDay;

  /// Mute for 1 week
  const factory ChatMuteDuration.oneWeek() = ChatMuteDuration_OneWeek;

  /// Mute until manually unmuted
  const factory ChatMuteDuration.forever() = ChatMuteDuration_Forever;

  /// Mute until a specific timestamp (must be in the future)
  const factory ChatMuteDuration.custom({
    required DateTime until,
  }) = ChatMuteDuration_Custom;
}
