import 'package:drift/drift.dart';

part 'chat_database.g.dart';

/// A 1:1 chat message, held locally so a conversation survives leaving the
/// screen and going offline.
///
/// This is deliberately NOT a [SyncColumns] inventory row: chat history is an
/// ephemeral, per-device cache of what the relays delivered — not the user's
/// CRDT-synced inventory. It never enters an inventory snapshot, backup, or the
/// device-to-device sync, so it needs no HLC / tombstone / author metadata. It
/// lives in its own encrypted database ([ChatDatabase]) to keep it fully
/// isolated from the inventory schema, its migrations, and its sync stream.
///
/// [accountScope] namespaces rows per social identity (empty = the original
/// identity), replacing the old per-key keystore prefix. The unique key makes
/// de-duplication a DB invariant: a relay re-delivers the same gift wrap on
/// every (re)subscribe, and an identical (scope, peer, sender, timestamp, text)
/// row is simply not inserted twice.
@TableIndex(
  name: 'messages_by_conversation',
  columns: {#accountScope, #peerPubkey, #sentAt},
)
class Messages extends Table {
  IntColumn get id => integer().autoIncrement()();
  TextColumn get accountScope => text()();
  TextColumn get peerPubkey => text()();
  TextColumn get fromPubkey => text()();
  TextColumn get body => text()();

  /// Milliseconds since epoch — the message's own timestamp (NIP-17), used for
  /// ordering and for the read/unread mark.
  IntColumn get sentAt => integer()();

  @override
  List<Set<Column>> get uniqueKeys => [
    {accountScope, peerPubkey, fromPubkey, sentAt, body},
  ];
}

/// The encrypted local chat cache (SQLCipher via an injected executor, exactly
/// like [AppDatabase]). Separate database on purpose — see [Messages]. There is
/// no historical schema to migrate: version 1, created fresh.
@DriftDatabase(tables: [Messages])
class ChatDatabase extends _$ChatDatabase {
  ChatDatabase(super.e);

  @override
  int get schemaVersion => 1;

  @override
  MigrationStrategy get migration =>
      MigrationStrategy(onCreate: (m) async => m.createAll());
}
