export const DEFAULT_SYSTEM_SETTINGS = {
  application_name: "Compta Control",
  default_language: "fr",
  date_format: "DD/MM/YYYY",
  decimal_separator: ",",
  thousands_separator: " ",
  session_expiration_minutes: 480,
  max_failed_logins_before_lockout: 5,
  password_minimum_length: 8,
  last_backup_at: null,
  last_backup_size_bytes: null,
};

const SYSTEM_SETTINGS_SELECT = `
  SELECT
    id,
    application_name,
    default_language,
    date_format,
    decimal_separator,
    thousands_separator,
    session_expiration_minutes,
    max_failed_logins_before_lockout,
    password_minimum_length,
    last_backup_at,
    last_backup_size_bytes,
    updated_by,
    updated_at
  FROM system_settings
  WHERE id = 1
  LIMIT 1
`;

export const normalizeSystemSettings = (row) => ({
  id: Number(row?.id || 1),
  application_name: row?.application_name || DEFAULT_SYSTEM_SETTINGS.application_name,
  default_language: row?.default_language || DEFAULT_SYSTEM_SETTINGS.default_language,
  date_format: row?.date_format || DEFAULT_SYSTEM_SETTINGS.date_format,
  decimal_separator: row?.decimal_separator || DEFAULT_SYSTEM_SETTINGS.decimal_separator,
  thousands_separator:
    row?.thousands_separator || DEFAULT_SYSTEM_SETTINGS.thousands_separator,
  session_expiration_minutes: Number(
    row?.session_expiration_minutes ||
      DEFAULT_SYSTEM_SETTINGS.session_expiration_minutes,
  ),
  max_failed_logins_before_lockout: Number(
    row?.max_failed_logins_before_lockout ||
      DEFAULT_SYSTEM_SETTINGS.max_failed_logins_before_lockout,
  ),
  password_minimum_length: Number(
    row?.password_minimum_length || DEFAULT_SYSTEM_SETTINGS.password_minimum_length,
  ),
  last_backup_at: row?.last_backup_at ? new Date(row.last_backup_at).toISOString() : null,
  last_backup_size_bytes:
    row?.last_backup_size_bytes === null || row?.last_backup_size_bytes === undefined
      ? null
      : Number(row.last_backup_size_bytes),
  updated_by:
    row?.updated_by === null || row?.updated_by === undefined
      ? null
      : Number(row.updated_by),
  updated_at: row?.updated_at ? new Date(row.updated_at).toISOString() : null,
});

export const ensureSystemSettings = async (db) => {
  await db.query(
    `
      INSERT INTO system_settings (
        id,
        application_name,
        default_language,
        date_format,
        decimal_separator,
        thousands_separator,
        session_expiration_minutes,
        max_failed_logins_before_lockout,
        password_minimum_length
      )
      VALUES (1, $1, $2, $3, $4, $5, $6, $7, $8)
      ON CONFLICT (id) DO NOTHING
    `,
    [
      DEFAULT_SYSTEM_SETTINGS.application_name,
      DEFAULT_SYSTEM_SETTINGS.default_language,
      DEFAULT_SYSTEM_SETTINGS.date_format,
      DEFAULT_SYSTEM_SETTINGS.decimal_separator,
      DEFAULT_SYSTEM_SETTINGS.thousands_separator,
      DEFAULT_SYSTEM_SETTINGS.session_expiration_minutes,
      DEFAULT_SYSTEM_SETTINGS.max_failed_logins_before_lockout,
      DEFAULT_SYSTEM_SETTINGS.password_minimum_length,
    ],
  );

  const { rows } = await db.query(SYSTEM_SETTINGS_SELECT);
  return normalizeSystemSettings(rows[0]);
};

export const updateSystemBackupMetadata = async (db, { sizeBytes, updatedBy = null }) => {
  const { rows } = await db.query(
    `
      UPDATE system_settings
      SET
        last_backup_at = CURRENT_TIMESTAMP,
        last_backup_size_bytes = $1,
        updated_by = $2,
        updated_at = CURRENT_TIMESTAMP
      WHERE id = 1
      RETURNING *
    `,
    [sizeBytes, updatedBy],
  );

  return normalizeSystemSettings(rows[0]);
};
