'use strict';

import type { Db } from '../types/db';

const { getDb, getSetting } = require('../db/database.cts');

const USER_SETTING_KEYS = [
  'currency',
  'date_format',
  'week_start',
  'default_landing_page',
  'grace_period_days',
  'due_soon_days',
  'notify_days_before',
  'drift_threshold_pct',
  'bank_tracking_enabled',
  'bank_tracking_account_id',
  'bank_tracking_pending_days',
  'bank_late_attribution_days',
  'search_bars_collapsed',
  'tracker_show_bank_projection_banner',
  'tracker_bank_projection_banner_snoozed_until',
  'tracker_show_search_sort',
  'tracker_show_summary_cards',
  'tracker_show_safe_to_spend',
  'tracker_show_overdue_command_center',
  'tracker_show_drift_insights',
  'tracker_overdue_collapsed',
  'tracker_drift_collapsed',
  'tracker_table_columns',
  'bank_auto_categorize_merchants',
  'spending_show_ready_to_assign',
  'spending_show_avg',
  'spending_show_cover_overspend',
  'spending_group_categories',
];

const USER_SETTING_DEFAULTS: Record<string, string> = {
  week_start: '0',
  default_landing_page: 'tracker',
  due_soon_days: '3',
  search_bars_collapsed: 'false',
  bank_auto_categorize_merchants: 'true',
  tracker_show_bank_projection_banner: 'true',
  tracker_bank_projection_banner_snoozed_until: '',
  tracker_show_search_sort: 'true',
  tracker_show_summary_cards: 'true',
  tracker_show_safe_to_spend: 'true',
  tracker_show_overdue_command_center: 'true',
  tracker_show_drift_insights: 'true',
  tracker_overdue_collapsed: 'false',
  tracker_drift_collapsed: 'false',
  tracker_table_columns:
    '["due","expected","previous","paid","paid_date","status","action","notes"]',
  spending_show_ready_to_assign: 'true',
  spending_show_avg: 'true',
  spending_show_cover_overspend: 'true',
  spending_group_categories: 'false',
};

function defaultUserSettings(): Record<string, any> {
  const defaults: Record<string, any> = {};
  for (const key of USER_SETTING_KEYS) {
    defaults[key] = USER_SETTING_DEFAULTS[key] ?? getSetting(key);
  }
  return defaults;
}

function getUserSettings(userId: number): Record<string, any> {
  const db: Db = getDb();
  const settings = defaultUserSettings();
  const rows = db
    .prepare(
      `
    SELECT key, value
    FROM user_settings
    WHERE user_id = ?
  `,
    )
    .all(userId);

  for (const row of rows) {
    if (USER_SETTING_KEYS.includes(row.key)) settings[row.key] = row.value;
  }

  return settings;
}

function setUserSettings(userId: number, data: Record<string, any>): Record<string, any> {
  const db: Db = getDb();
  const upsert = db.prepare(`
    INSERT INTO user_settings (user_id, key, value, updated_at)
    VALUES (?, ?, ?, datetime('now'))
    ON CONFLICT(user_id, key) DO UPDATE SET
      value = excluded.value,
      updated_at = datetime('now')
  `);

  const save = db.transaction(() => {
    for (const [key, value] of Object.entries(data || {})) {
      if (USER_SETTING_KEYS.includes(key)) {
        upsert.run(userId, key, String(value));
      }
    }
  });

  save();
  return getUserSettings(userId);
}

module.exports = {
  USER_SETTING_KEYS,
  getUserSettings,
  setUserSettings,
};
