import type { Database } from '@db/database.ts';

export async function setSettings<K extends SettingKey>(db: Database, settings: { [k in K]: SettingKeyValueType<K> }) {
  const dbSettings = Object.entries(settings).map(([name, value]) => ({ name, value: JSON.stringify(value) }));

  await db.setSettings({ settings: dbSettings });
}

export async function getSetting<K extends SettingKey>(db: Database, key: K): Promise<SettingKeyValueType<K> | null>;
export async function getSetting<K extends SettingKey, D extends SettingKeyValueType<K>>(
  db: Database,
  key: K,
  defaultValue: D
): Promise<SettingKeyValueType<K>>;
export async function getSetting<K extends SettingKey, D extends SettingKeyValueType<K>>(
  db: Database,
  key: K,
  defaultValue?: D
) {
  const setting = await db.getSetting({ name: key });
  return setting != null ? JSON.parse(setting) : defaultValue != undefined ? defaultValue : null;
}

export async function getSettings<K extends SettingKey>(
  db: Database
): Promise<{ [k in K]: SettingKeyValueType<K> | null }>;
export async function getSettings<K extends SettingKey[]>(
  db: Database,
  keys: K
): Promise<{ [k in K[number]]: SettingKeyValueType<k> | null }>;
export async function getSettings<K extends SettingKey[]>(db: Database, keys?: K) {
  const settings = await db.getSettings({ names: keys });

  return settings.reduce(
    (prev, curr) => Object.assign(prev, { [curr.name]: curr.value != null ? JSON.parse(curr.value) : null }),
    {} as { [k in K[number]]: SettingKeyValueType<k> | null }
  );
}

export enum SettingKey {
  SignupEnabled = 'signup.enabled',
  SignupInfoMessage = 'signup.infoMessage',
  SignupDisabledMessage = 'signup.disabledMessage',
  SignupDisabledSubMessage = 'signup.disabledSubMessage',
  LiveStatisticsEnabled = 'liveStatistics.enabled'
}

export type SettingKeyValueType<K extends SettingKey> = {
  [SettingKey.SignupEnabled]: boolean;
  [SettingKey.SignupInfoMessage]: string;
  [SettingKey.SignupDisabledMessage]: string;
  [SettingKey.SignupDisabledSubMessage]: string;
  [SettingKey.LiveStatisticsEnabled]: boolean;
}[K];
