/**
 * Test Error Formatting Utility
 * 
 * Provides robust error formatting for test results to avoid "[object Object]" messages
 * Includes pattern matching for common Supabase/Postgres constraint violations
 */

/**
 * Error pattern matchers for common database constraint violations
 */
const ERROR_PATTERNS = [
  {
    // RLS policy violations
    pattern: /new row violates row-level security policy for table "(\w+)"/i,
    format: (match: RegExpMatchArray) => 
      `RLS Policy Violation: Cannot insert into table "${match[1]}". Check that RLS policies allow this operation and user has proper authentication.`
  },
  {
    // NOT NULL constraint violations
    pattern: /null value in column "(\w+)" of relation "(\w+)" violates not-null constraint/i,
    format: (match: RegExpMatchArray) => 
      `NOT NULL Constraint: Column "${match[1]}" in table "${match[2]}" cannot be null. Provide a value for this required field.`
  },
  {
    // UNIQUE constraint violations
    pattern: /duplicate key value violates unique constraint "(\w+)"/i,
    format: (match: RegExpMatchArray) => 
      `UNIQUE Constraint: Duplicate value violates constraint "${match[1]}". This value already exists in the database.`
  },
  {
    // Foreign key violations
    pattern: /insert or update on table "(\w+)" violates foreign key constraint "(\w+)"/i,
    format: (match: RegExpMatchArray) => 
      `Foreign Key Violation: Table "${match[1]}" references non-existent record (constraint: "${match[2]}"). Ensure the referenced entity exists first.`
  },
  {
    // Foreign key violations (alternative format)
    pattern: /violates foreign key constraint/i,
    format: () => 
      `Foreign Key Violation: Referenced record does not exist. Create the parent entity before creating this dependent entity.`
  },
  {
    // Check constraint violations
    pattern: /new row for relation "(\w+)" violates check constraint "(\w+)"/i,
    format: (match: RegExpMatchArray) => 
      `Check Constraint: Validation failed for table "${match[1]}" (constraint: "${match[2]}"). The provided value does not meet validation requirements.`
  },
  {
    // Column does not exist
    pattern: /column "(\w+)" of relation "(\w+)" does not exist/i,
    format: (match: RegExpMatchArray) => 
      `Schema Error: Column "${match[1]}" does not exist in table "${match[2]}". Check database schema or migration status.`
  },
  {
    // Could not find column in schema cache
    pattern: /Could not find the '(\w+)' column of '(\w+)' in the schema cache/i,
    format: (match: RegExpMatchArray) => 
      `Schema Cache Error: Column "${match[1]}" not found in table "${match[2]}". The schema may have changed - try refreshing the database connection.`
  },
  {
    // Table does not exist
    pattern: /relation "(\w+)" does not exist/i,
    format: (match: RegExpMatchArray) => 
      `Schema Error: Table "${match[1]}" does not exist. Run migrations or check database schema.`
  },
  {
    // Permission denied
    pattern: /permission denied for (?:table|relation) "?(\w+)"?/i,
    format: (match: RegExpMatchArray) => 
      `Permission Denied: Insufficient permissions to access table "${match[1]}". Check RLS policies and user roles.`
  },
  {
    // Rate limit errors
    pattern: /Rate limit exceeded\. Please wait (\d+) seconds?/i,
    format: (match: RegExpMatchArray) => 
      `Rate Limited: Too many requests. Wait ${match[1]} seconds before retrying.`
  },
  {
    // Rate limit errors (alternative format)
    pattern: /Too many submissions in a short time\. Please wait (\d+) seconds?/i,
    format: (match: RegExpMatchArray) => 
      `Rate Limited: Submission throttled. Wait ${match[1]} seconds before submitting again.`
  }
];

/**
 * Format error for test result display
 * Handles Error objects, PostgresError objects, and plain objects
 * 
 * @param error - Any error value thrown in a test
 * @returns Formatted, human-readable error string
 */
export function formatTestError(error: unknown): string {
  let errorMessage = '';
  
  // Extract base error message
  if (error instanceof Error) {
    errorMessage = error.message;
  } else if (typeof error === 'object' && error !== null) {
    const err = error as any;
    
    // Try common error message properties
    if (err.message && typeof err.message === 'string') {
      errorMessage = err.message;
      
      // Include additional Supabase error details if present
      if (err.details && typeof err.details === 'string') {
        errorMessage += ` | Details: ${err.details}`;
      }
      if (err.hint && typeof err.hint === 'string') {
        errorMessage += ` | Hint: ${err.hint}`;
      }
      if (err.code && typeof err.code === 'string') {
        errorMessage += ` | Code: ${err.code}`;
      }
    } 
    // Some errors nest the actual error in an 'error' property
    else if (err.error) {
      return formatTestError(err.error);
    }
    // Some APIs use 'msg' instead of 'message'
    else if (err.msg && typeof err.msg === 'string') {
      errorMessage = err.msg;
    }
    // Last resort: stringify the entire object
    else {
      try {
        const stringified = JSON.stringify(error, null, 2);
        errorMessage = stringified.length > 500 
          ? stringified.substring(0, 500) + '... (truncated)'
          : stringified;
      } catch {
        // JSON.stringify can fail on circular references
        errorMessage = String(error);
      }
    }
  } else {
    // Primitive values (strings, numbers, etc.)
    errorMessage = String(error);
  }
  
  // Apply pattern matching to format known constraint violations
  for (const { pattern, format } of ERROR_PATTERNS) {
    const match = errorMessage.match(pattern);
    if (match) {
      return format(match);
    }
  }
  
  // Return original message if no patterns matched
  return errorMessage;
}
