import { HONEYPOT_KEYS, MIN_FORM_DURATION_MS } from '@/lib/validation/limits';

export function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}

export function unknownFieldErrors(
  body: Record<string, unknown>,
  allowed: readonly string[]
): string[] {
  const allow = new Set<string>([...allowed, ...HONEYPOT_KEYS]);
  const extra = Object.keys(body).filter((key) => !allow.has(key));
  if (extra.length === 0) return [];
  return ['Ungültige Felder in der Anfrage.'];
}

function honeypotFilled(value: unknown): boolean {
  return typeof value === 'string' && value.trim() !== '';
}

/**
 * Honeypot filled, or submitted faster than a human can click → treat as a bot.
 * Missing timestamps are not treated as bots (that silently dropped real mail).
 * Callers should return a generic success with no side effects.
 */
export function isBotSubmission(body: Record<string, unknown>): boolean {
  if (honeypotFilled(body.website) || honeypotFilled(body.hp_field)) {
    return true;
  }
  const started = Number(body.form_started_at);
  if (!Number.isFinite(started)) return false;
  if (Date.now() - started < MIN_FORM_DURATION_MS) return true;
  return false;
}

export function optionalString(
  value: unknown,
  max: number
): { ok: true; value: string | undefined } | { ok: false } {
  if (value === undefined || value === null || value === '') {
    return { ok: true, value: undefined };
  }
  if (typeof value !== 'string') return { ok: false };
  const trimmed = value.trim();
  if (trimmed.length > max) return { ok: false };
  return { ok: true, value: trimmed };
}

export function requiredString(
  value: unknown,
  max: number
): { ok: true; value: string } | { ok: false } {
  if (typeof value !== 'string') return { ok: false };
  const trimmed = value.trim();
  if (!trimmed || trimmed.length > max) return { ok: false };
  return { ok: true, value: trimmed };
}

export function optionalInt(
  value: unknown,
  min: number,
  max: number
): { ok: true; value: number | undefined } | { ok: false } {
  if (value === undefined || value === null || value === '') {
    return { ok: true, value: undefined };
  }
  const n = typeof value === 'number' ? value : Number(value);
  if (!Number.isInteger(n) || n < min || n > max) return { ok: false };
  return { ok: true, value: n };
}

export function requiredInt(
  value: unknown,
  min: number,
  max: number
): { ok: true; value: number } | { ok: false } {
  const n = typeof value === 'number' ? value : Number(value);
  if (!Number.isInteger(n) || n < min || n > max) return { ok: false };
  return { ok: true, value: n };
}

export function requiredPositiveNumber(
  value: unknown
): { ok: true; value: number } | { ok: false } {
  const n = typeof value === 'number' ? value : Number(value);
  if (!Number.isFinite(n) || n <= 0) return { ok: false };
  return { ok: true, value: n };
}
