'use strict';

// import required so Node type-strips this .cts (it has no other import).
import type { Db } from '../types/db';

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

const SYNC_DAYS_MAX = 45; // SimpleFIN Bridge hard limit — requests beyond this return an error
const SYNC_DAYS_EFFECTIVE = 44; // 1-day buffer so request latency never tips over the hard limit
const SYNC_DAYS_DEFAULT = 30; // routine sync window (initial seed always uses SYNC_DAYS_EFFECTIVE)
const SYNC_INTERVAL_DEFAULT = 4; // hours

interface BankSyncConfig {
  enabled: boolean;
  sync_days: number;
  seed_days: number;
  sync_days_max: number;
  sync_interval_hours: number;
  debug_logging: boolean;
}

function getBankSyncConfig(): BankSyncConfig {
  const dbValue = getSetting('bank_sync_enabled');
  const envValue = process.env.BANK_SYNC_ENABLED;

  let enabled: boolean;
  if (dbValue !== null && dbValue !== undefined && dbValue !== '') {
    enabled = dbValue === 'true';
  } else if (envValue !== undefined && envValue !== '') {
    enabled = envValue === 'true';
  } else {
    enabled = false;
  }

  const syncDaysDb = parseInt(getSetting('simplefin_sync_days') || '', 10);
  const syncDaysEnv = parseInt(process.env.SIMPLEFIN_SYNC_DAYS || '', 10);
  const rawSyncDays =
    Number.isFinite(syncDaysDb) && syncDaysDb > 0
      ? syncDaysDb
      : Number.isFinite(syncDaysEnv) && syncDaysEnv > 0
        ? syncDaysEnv
        : SYNC_DAYS_DEFAULT;
  const syncDays = Math.min(rawSyncDays, SYNC_DAYS_EFFECTIVE);

  const intervalDb = parseFloat(getSetting('simplefin_sync_interval_hours') || '');
  const intervalEnv = parseFloat(process.env.SIMPLEFIN_SYNC_INTERVAL_HOURS || '');
  const syncIntervalHours =
    Number.isFinite(intervalDb) && intervalDb >= 0.5
      ? intervalDb
      : Number.isFinite(intervalEnv) && intervalEnv >= 0.5
        ? intervalEnv
        : SYNC_INTERVAL_DEFAULT;

  const debugDb = getSetting('simplefin_debug_logging');
  const debugEnv = process.env.SIMPLEFIN_DEBUG_LOGGING;
  const debugLogging = debugDb === 'true' || (!debugDb && debugEnv === 'true');

  return {
    enabled,
    sync_days: syncDays,
    seed_days: SYNC_DAYS_EFFECTIVE,
    sync_days_max: SYNC_DAYS_MAX,
    sync_interval_hours: syncIntervalHours,
    debug_logging: debugLogging,
  };
}

function setBankSyncEnabled(enabled: boolean): BankSyncConfig {
  setSetting('bank_sync_enabled', enabled ? 'true' : 'false');
  return getBankSyncConfig();
}

function setSyncIntervalHours(hours: number | string): BankSyncConfig {
  const n = parseFloat(hours as string);
  if (!Number.isFinite(n) || n < 0.5 || n > 168) {
    throw Object.assign(new Error('sync_interval_hours must be between 0.5 and 168'), {
      status: 400,
    });
  }
  setSetting('simplefin_sync_interval_hours', String(Math.round(n * 10) / 10));
  return getBankSyncConfig();
}

function setSyncDays(days: number | string): BankSyncConfig {
  const n = parseInt(days as string, 10);
  if (!Number.isFinite(n) || n < 1 || n > SYNC_DAYS_MAX) {
    throw Object.assign(
      new Error(`sync_days must be between 1 and ${SYNC_DAYS_MAX} (SimpleFIN Bridge hard limit)`),
      { status: 400 },
    );
  }
  setSetting('simplefin_sync_days', String(n));
  return getBankSyncConfig();
}

function setDebugLogging(enabled: boolean): BankSyncConfig {
  setSetting('simplefin_debug_logging', enabled ? 'true' : 'false');
  return getBankSyncConfig();
}

module.exports = {
  getBankSyncConfig,
  setBankSyncEnabled,
  setSyncIntervalHours,
  setSyncDays,
  setDebugLogging,
  SYNC_DAYS_MAX,
  SYNC_DAYS_EFFECTIVE,
  SYNC_DAYS_DEFAULT,
};
