/**
 * Helper functions for relational audit logging
 * Replaces JSONB storage with proper relational tables
 */

import { supabase } from '@/lib/supabaseClient';
import { handleNonCriticalError } from './errorHandler';

/**
 * Write admin audit details to relational table
 * Replaces JSONB admin_audit_log.details column
 */
export async function writeAdminAuditDetails(
  auditLogId: string,
  details: Record<string, unknown>
): Promise<void> {
  if (!details || Object.keys(details).length === 0) return;

  const entries = Object.entries(details).map(([key, value]) => ({
    audit_log_id: auditLogId,
    detail_key: key,
    detail_value: typeof value === 'object' ? JSON.stringify(value) : String(value),
  }));

  const { error } = await supabase
    .from('admin_audit_details')
    .insert(entries);

  if (error) {
    handleNonCriticalError(error, {
      action: 'Write admin audit details',
      metadata: { auditLogId },
    });
    throw error;
  }
}

/**
 * Write moderation audit metadata to relational table
 * Replaces JSONB moderation_audit_log.metadata column
 */
export async function writeModerationAuditMetadata(
  auditLogId: string,
  metadata: Record<string, unknown>
): Promise<void> {
  if (!metadata || Object.keys(metadata).length === 0) return;

  const entries = Object.entries(metadata).map(([key, value]) => ({
    audit_log_id: auditLogId,
    metadata_key: key,
    metadata_value: typeof value === 'object' ? JSON.stringify(value) : String(value),
  }));

  const { error } = await supabase
    .from('moderation_audit_metadata')
    .insert(entries);

  if (error) {
    handleNonCriticalError(error, {
      action: 'Write moderation audit metadata',
      metadata: { auditLogId },
    });
    throw error;
  }
}

/**
 * Write item change fields to relational table
 * Replaces JSONB item_edit_history.changes column
 */
export async function writeItemChangeFields(
  editHistoryId: string,
  changes: Record<string, { old_value?: unknown; new_value?: unknown }>
): Promise<void> {
  if (!changes || Object.keys(changes).length === 0) return;

  const entries = Object.entries(changes).map(([fieldName, change]) => ({
    edit_history_id: editHistoryId,
    field_name: fieldName,
    old_value: change.old_value !== undefined 
      ? (typeof change.old_value === 'object' ? JSON.stringify(change.old_value) : String(change.old_value))
      : null,
    new_value: change.new_value !== undefined
      ? (typeof change.new_value === 'object' ? JSON.stringify(change.new_value) : String(change.new_value))
      : null,
  }));

  const { error } = await supabase
    .from('item_change_fields')
    .insert(entries);

  if (error) {
    handleNonCriticalError(error, {
      action: 'Write item change fields',
      metadata: { editHistoryId },
    });
    throw error;
  }
}

/**
 * Write request breadcrumbs to relational table
 * Replaces JSONB request_metadata.breadcrumbs column
 */
export async function writeRequestBreadcrumbs(
  requestId: string,
  breadcrumbs: Array<{
    timestamp: string;
    category: string;
    message: string;
    level?: 'debug' | 'info' | 'warn' | 'error';
  }>
): Promise<void> {
  if (!breadcrumbs || breadcrumbs.length === 0) return;

  const entries = breadcrumbs.map((breadcrumb, index) => ({
    request_id: requestId,
    timestamp: breadcrumb.timestamp,
    category: breadcrumb.category,
    message: breadcrumb.message,
    level: breadcrumb.level || 'info',
    sequence_order: index,
  }));

  const { error } = await supabase
    .from('request_breadcrumbs')
    .insert(entries);

  if (error) {
    handleNonCriticalError(error, {
      action: 'Write request breadcrumbs',
      metadata: { requestId },
    });
    throw error;
  }
}

/**
 * Read admin audit details from relational table
 */
export async function readAdminAuditDetails(
  auditLogId: string
): Promise<Record<string, string>> {
  const { data, error } = await supabase
    .from('admin_audit_details')
    .select('detail_key, detail_value')
    .eq('audit_log_id', auditLogId);

  if (error) {
    handleNonCriticalError(error, {
      action: 'Read admin audit details',
      metadata: { auditLogId },
    });
    return {};
  }

  return data.reduce((acc, row) => {
    acc[row.detail_key] = row.detail_value;
    return acc;
  }, {} as Record<string, string>);
}

/**
 * Read moderation audit metadata from relational table
 */
export async function readModerationAuditMetadata(
  auditLogId: string
): Promise<Record<string, string>> {
  const { data, error } = await supabase
    .from('moderation_audit_metadata')
    .select('metadata_key, metadata_value')
    .eq('audit_log_id', auditLogId);

  if (error) {
    handleNonCriticalError(error, {
      action: 'Read moderation audit metadata',
      metadata: { auditLogId },
    });
    return {};
  }

  return data.reduce((acc, row) => {
    acc[row.metadata_key] = row.metadata_value;
    return acc;
  }, {} as Record<string, string>);
}

/**
 * Read item change fields from relational table
 */
export async function readItemChangeFields(
  editHistoryId: string
): Promise<Record<string, { old_value: string | null; new_value: string | null }>> {
  const { data, error } = await supabase
    .from('item_change_fields')
    .select('field_name, old_value, new_value')
    .eq('edit_history_id', editHistoryId);

  if (error) {
    handleNonCriticalError(error, {
      action: 'Read item change fields',
      metadata: { editHistoryId },
    });
    return {};
  }

  return data.reduce((acc, row) => {
    acc[row.field_name] = {
      old_value: row.old_value,
      new_value: row.new_value,
    };
    return acc;
  }, {} as Record<string, { old_value: string | null; new_value: string | null }>);
}

/**
 * Write profile change fields to relational table
 * Replaces JSONB profile_audit_log.changes column
 */
export async function writeProfileChangeFields(
  auditLogId: string,
  changes: Record<string, { old_value?: unknown; new_value?: unknown }>
): Promise<void> {
  if (!changes || Object.keys(changes).length === 0) return;

  const entries = Object.entries(changes).map(([fieldName, change]) => ({
    audit_log_id: auditLogId,
    field_name: fieldName,
    old_value: change.old_value !== undefined 
      ? (typeof change.old_value === 'object' ? JSON.stringify(change.old_value) : String(change.old_value))
      : null,
    new_value: change.new_value !== undefined
      ? (typeof change.new_value === 'object' ? JSON.stringify(change.new_value) : String(change.new_value))
      : null,
  }));

  const { error } = await supabase
    .from('profile_change_fields')
    .insert(entries);

  if (error) {
    handleNonCriticalError(error, {
      action: 'Write profile change fields',
      metadata: { auditLogId },
    });
    throw error;
  }
}

/**
 * Write conflict detail fields to relational table
 * Replaces JSONB conflict_resolutions.conflict_details column
 */
export async function writeConflictDetailFields(
  conflictResolutionId: string,
  conflictData: Record<string, unknown>
): Promise<void> {
  if (!conflictData || Object.keys(conflictData).length === 0) return;

  const entries = Object.entries(conflictData).map(([fieldName, value]) => ({
    conflict_resolution_id: conflictResolutionId,
    field_name: fieldName,
    conflicting_value_1: typeof value === 'object' && value !== null && 'v1' in value 
      ? String((value as any).v1)
      : null,
    conflicting_value_2: typeof value === 'object' && value !== null && 'v2' in value 
      ? String((value as any).v2)
      : null,
    resolved_value: typeof value === 'object' && value !== null && 'resolved' in value 
      ? String((value as any).resolved)
      : null,
  }));

  const { error } = await supabase
    .from('conflict_detail_fields')
    .insert(entries);

  if (error) {
    handleNonCriticalError(error, {
      action: 'Write conflict detail fields',
      metadata: { conflictResolutionId },
    });
    throw error;
  }
}
