import { connectToDatabase } from './db';
import AuditLog from './models/AuditLog';
import mongoose from 'mongoose';

interface AuditParams {
  actorId: mongoose.Types.ObjectId | string;
  action: string;
  entityType: 'User' | 'Member' | 'Satsang' | 'SatsangSchedule' | 'Attendance' | 'Geography' | 'SystemSettings' | 'Announcement' | 'ImportBatch';
  entityId: mongoose.Types.ObjectId | string;
  changedFields?: Record<string, { old: any; new: any }>;
  ipAddress?: string;
}

export async function logAuditEvent(params: AuditParams) {
  try {
    await connectToDatabase();

    const cleanChangedFields: Record<string, { old: any; new: any }> = {};

    if (params.changedFields) {
      for (const [key, value] of Object.entries(params.changedFields)) {
        // Double check to ensure we never record passwords or secrets in the audit log
        const isSecretField = [
          'password',
          'passwordhash',
          'token',
          'secret',
          'key',
          'passwordHash',
          'jwtSecret'
        ].some((secret) => key.toLowerCase().includes(secret.toLowerCase()));

        if (isSecretField) {
          cleanChangedFields[key] = { old: '[REDACTED]', new: '[REDACTED]' };
        } else {
          cleanChangedFields[key] = value;
        }
      }
    }

    const logEntry = new AuditLog({
      actorId: new mongoose.Types.ObjectId(params.actorId.toString()),
      action: params.action,
      entityType: params.entityType,
      entityId: new mongoose.Types.ObjectId(params.entityId.toString()),
      changedFields: Object.keys(cleanChangedFields).length > 0 ? cleanChangedFields : undefined,
      ipAddress: params.ipAddress || 'unknown',
      timestamp: new Date()
    });

    await logEntry.save();
    return logEntry;
  } catch (error) {
    // Avoid crashing the server action if audit logging fails, but log it for developers
    console.error('Audit Logging Error:', error);
    return null;
  }
}
