import BaseDexie, { Table } from "dexie";
import { encrypted, Encryption } from "@pvermeer/dexie-encrypted-addon";
import { Account, AccountsSchema } from "./tables/accounts";
import { Contact, ContactSchema } from "./tables/contacts";
import { Log, LogSchema } from "./tables/logs";
import {
  MASTER_SETTINGS_KEY,
  Settings,
  SettingsSchema,
} from "./tables/settings";
import { DEFAULT_ENDORSER_API_SERVER } from "@/constants/app";

// Define types for tables that hold sensitive and non-sensitive data
type SensitiveTables = { accounts: Table<Account> };
type NonsensitiveTables = {
  contacts: Table<Contact>;
  logs: Table<Log>;
  settings: Table<Settings>;
};

// Using 'unknown' instead of 'any' for stricter typing and to avoid TypeScript warnings
export type SensitiveDexie<T extends unknown = SensitiveTables> = BaseDexie & T;
export type NonsensitiveDexie<T extends unknown = NonsensitiveTables> =
  BaseDexie & T;

// Initialize Dexie databases for sensitive and non-sensitive data
export const accountsDB = new BaseDexie("TimeSafariAccounts") as SensitiveDexie;
const SensitiveSchemas = { ...AccountsSchema };

export const db = new BaseDexie("TimeSafari") as NonsensitiveDexie;
const NonsensitiveSchemas = {
  ...ContactSchema,
  ...LogSchema,
  ...SettingsSchema,
};

// Manage the encryption key. If not present in localStorage, create and store it.
const secret =
  localStorage.getItem("secret") || Encryption.createRandomEncryptionKey();
if (!localStorage.getItem("secret")) localStorage.setItem("secret", secret);

// Apply encryption to the sensitive database using the secret key
encrypted(accountsDB, { secretKey: secret });

// Define the schema for our databases
accountsDB.version(1).stores(SensitiveSchemas);
// v1 was contacts & settings
// v2 added logs
db.version(2).stores(NonsensitiveSchemas);

// Event handler to initialize the non-sensitive database with default settings
db.on("populate", () => {
  db.settings.add({
    id: MASTER_SETTINGS_KEY,
    apiServer: DEFAULT_ENDORSER_API_SERVER,
  });
});
