import prisma from "../config/database";

interface SystemSettings {
  break_threshold_hours: number;
  break_duration_short: number;
  break_duration_long: number;
  clock_rounding_minutes: number;
  invoice_alert_email: string;
  leave_notify_email: string;
  max_login_attempts: number;
  lockout_minutes: number;
  max_requests_per_minute: number;
  default_currency: string;
  default_vat_rate: number;
  available_vat_rates: number[];
  available_currencies: string[];
  smtp_from: string;
  smtp_from_name: string;
}

const DEFAULTS: SystemSettings = {
  break_threshold_hours: 6,
  break_duration_short: 15,
  break_duration_long: 30,
  clock_rounding_minutes: 15,
  invoice_alert_email: "",
  leave_notify_email: "",
  max_login_attempts: 5,
  lockout_minutes: 15,
  max_requests_per_minute: 300,
  default_currency: "CZK",
  default_vat_rate: 21,
  available_vat_rates: [0, 10, 12, 15, 21],
  available_currencies: ["CZK", "EUR", "USD", "GBP"],
  smtp_from: "",
  smtp_from_name: "",
};

let cache: SystemSettings | null = null;
let cacheTime = 0;
const CACHE_TTL = 60_000; // 60 seconds

export async function getSystemSettings(): Promise<SystemSettings> {
  if (cache && Date.now() - cacheTime < CACHE_TTL) return cache;

  const row = await prisma.company_settings.findFirst();
  if (!row) {
    cache = { ...DEFAULTS };
    cacheTime = Date.now();
    return cache;
  }

  let vatRates = DEFAULTS.available_vat_rates;
  let currencies = DEFAULTS.available_currencies;
  try {
    if (row.available_vat_rates) {
      const parsed = JSON.parse(row.available_vat_rates);
      // Shape guard: must be an array of finite numbers, else keep default.
      if (Array.isArray(parsed) && parsed.every((n) => Number.isFinite(n))) {
        vatRates = parsed;
      }
    }
  } catch {
    /* malformed JSON — keep default (expected-condition catch) */
  }
  try {
    if (row.available_currencies) {
      const parsed = JSON.parse(row.available_currencies);
      // Shape guard: must be an array of strings, else keep default.
      if (Array.isArray(parsed) && parsed.every((c) => typeof c === "string")) {
        currencies = parsed;
      }
    }
  } catch {
    /* malformed JSON — keep default (expected-condition catch) */
  }

  cache = {
    break_threshold_hours: Number(
      row.break_threshold_hours ?? DEFAULTS.break_threshold_hours,
    ),
    break_duration_short:
      row.break_duration_short ?? DEFAULTS.break_duration_short,
    break_duration_long:
      row.break_duration_long ?? DEFAULTS.break_duration_long,
    clock_rounding_minutes:
      row.clock_rounding_minutes ?? DEFAULTS.clock_rounding_minutes,
    invoice_alert_email: row.invoice_alert_email || "",
    leave_notify_email: row.leave_notify_email || "",
    max_login_attempts: row.max_login_attempts ?? DEFAULTS.max_login_attempts,
    lockout_minutes: row.lockout_minutes ?? DEFAULTS.lockout_minutes,
    max_requests_per_minute:
      row.max_requests_per_minute ?? DEFAULTS.max_requests_per_minute,
    default_currency: row.default_currency || DEFAULTS.default_currency,
    default_vat_rate: Number(row.default_vat_rate ?? DEFAULTS.default_vat_rate),
    available_vat_rates: vatRates,
    available_currencies: currencies,
    smtp_from: row.smtp_from || "",
    smtp_from_name: row.smtp_from_name || DEFAULTS.smtp_from_name,
  };
  cacheTime = Date.now();
  return cache;
}

export function invalidateSettingsCache(): void {
  cache = null;
  cacheTime = 0;
}
