/** IndexedDB schema version - bump when adding/changing object stores. */
export const BROWSER_DATABASE_VERSION = 4;

const STORE_MESSAGES = 'messages';
const STORE_USERS = 'users';
const STORE_ROOMS = 'rooms';
const STORE_REACTIONS = 'reactions';
const STORE_BANS = 'bans';
const STORE_META = 'meta';
const STORE_ATTACHMENTS = 'attachments';
const STORE_CUSTOM_EMOJIS = 'customEmojis';
const STORE_MESSAGE_REVISIONS = 'messageRevisions';

export function ensureObjectStoreDuringUpgrade(
  database: IDBDatabase,
  upgradeTransaction: IDBTransaction,
  name: string,
  options?: IDBObjectStoreParameters
): IDBObjectStore {
  if (database.objectStoreNames.contains(name)) {
    return upgradeTransaction.objectStore(name);
  }

  return database.createObjectStore(name, options);
}

export function ensureStoreIndex(store: IDBObjectStore, name: string, keyPath: string): void {
  if (!store.indexNames.contains(name)) {
    store.createIndex(name, keyPath, { unique: false });
  }
}

export function applyBrowserDatabaseSchema(
  database: IDBDatabase,
  upgradeTransaction: IDBTransaction
): void {
  const messagesStore = ensureObjectStoreDuringUpgrade(database, upgradeTransaction, STORE_MESSAGES, { keyPath: 'id' });

  ensureStoreIndex(messagesStore, 'roomId', 'roomId');
  ensureStoreIndex(messagesStore, 'timestamp', 'timestamp');

  ensureObjectStoreDuringUpgrade(database, upgradeTransaction, STORE_USERS, { keyPath: 'id' });

  const roomsStore = ensureObjectStoreDuringUpgrade(database, upgradeTransaction, STORE_ROOMS, { keyPath: 'id' });

  ensureStoreIndex(roomsStore, 'timestamp', 'timestamp');

  const reactionsStore = ensureObjectStoreDuringUpgrade(database, upgradeTransaction, STORE_REACTIONS, { keyPath: 'id' });

  ensureStoreIndex(reactionsStore, 'messageId', 'messageId');
  ensureStoreIndex(reactionsStore, 'userId', 'userId');

  const bansStore = ensureObjectStoreDuringUpgrade(database, upgradeTransaction, STORE_BANS, { keyPath: 'oderId' });

  ensureStoreIndex(bansStore, 'roomId', 'roomId');
  ensureStoreIndex(bansStore, 'expiresAt', 'expiresAt');

  ensureObjectStoreDuringUpgrade(database, upgradeTransaction, STORE_META, { keyPath: 'id' });

  const attachmentsStore = ensureObjectStoreDuringUpgrade(database, upgradeTransaction, STORE_ATTACHMENTS, { keyPath: 'id' });

  ensureStoreIndex(attachmentsStore, 'messageId', 'messageId');

  const customEmojisStore = ensureObjectStoreDuringUpgrade(database, upgradeTransaction, STORE_CUSTOM_EMOJIS, { keyPath: 'id' });

  ensureStoreIndex(customEmojisStore, 'updatedAt', 'updatedAt');
  ensureStoreIndex(customEmojisStore, 'creatorUserId', 'creatorUserId');

  const revisionsStore = ensureObjectStoreDuringUpgrade(database, upgradeTransaction, STORE_MESSAGE_REVISIONS, { keyPath: 'id' });

  ensureStoreIndex(revisionsStore, 'messageId', 'messageId');
}
