import { createAdminClient } from '@/shared/db/supabase-client';

// --- ASA GENERATED START ---
// Immutable audit log — append-only, actor/subject aware.
// All admin actions must be logged via logAuditEvent().
// No update/delete operations on audit_log table.
// --- ASA GENERATED END ---

// --- USER CODE START ---

export interface AuditEvent {
  actor_id: string;
  actor_email?: string;
  actor_role?: string;
  subject_id?: string;
  subject_email?: string;
  action: string;
  resource_type?: string;
  resource_id?: string;
  details?: Record<string, unknown>;
  reason?: string;
  ip_address?: string;
  user_agent?: string;
  impersonation_session_id?: string;
}

/**
 * Log an audit event. Append-only — entries cannot be modified or deleted.
 */
export async function logAuditEvent(event: AuditEvent): Promise<void> {
  const supabase = createAdminClient();

  const { error } = await supabase.from('audit_log').insert({
    actor_id: event.actor_id,
    actor_email: event.actor_email,
    actor_role: event.actor_role,
    subject_id: event.subject_id,
    subject_email: event.subject_email,
    action: event.action,
    resource_type: event.resource_type,
    resource_id: event.resource_id,
    details: event.details ?? {},
    reason: event.reason,
    ip_address: event.ip_address,
    user_agent: event.user_agent,
    impersonation_session_id: event.impersonation_session_id,
  });

  if (error) {
    // Never throw on audit failure — log to console as fallback
    console.error('[audit] Failed to write audit log:', error.message, event);
  }
}

/**
 * Query audit log entries with filters.
 */
export async function queryAuditLog(options: {
  actor_id?: string;
  subject_id?: string;
  action?: string;
  resource_type?: string;
  from_date?: string;
  to_date?: string;
  limit?: number;
  offset?: number;
}) {
  const supabase = createAdminClient();

  let query = supabase
    .from('audit_log')
    .select('*', { count: 'exact' })
    .order('created_at', { ascending: false });

  if (options.actor_id) query = query.eq('actor_id', options.actor_id);
  if (options.subject_id) query = query.eq('subject_id', options.subject_id);
  if (options.action) query = query.eq('action', options.action);
  if (options.resource_type) query = query.eq('resource_type', options.resource_type);
  if (options.from_date) query = query.gte('created_at', options.from_date);
  if (options.to_date) query = query.lte('created_at', options.to_date);

  query = query.range(
    options.offset ?? 0,
    (options.offset ?? 0) + (options.limit ?? 50) - 1,
  );

  const { data, count, error } = await query;

  if (error) {
    console.error('[audit] Query failed:', error.message);
    return { entries: [], total: 0 };
  }

  return { entries: data ?? [], total: count ?? 0 };
}

// --- USER CODE END ---
