/**
 * The Hearth Validator — Accounting Guardrails
 * 
 * Validates that DF-generated code complies with Standing Orders §13.
 * Any generated code that attempts hard-delete of guarded entities,
 * modifies posted transactions, or creates orphaned records will be REJECTED.
 */

export interface ValidationResult {
  valid: boolean;
  violations: string[];
  warnings: string[];
  suggestions: string[];
}

/** Guarded entity types that require referential integrity checks */
const GUARDED_ENTITIES = [
  'customer', 'vendor', 'product', 'account',
  'invoice', 'salesOrder', 'transaction', 'vendorInvoice',
  'salesOrderItem', 'payment', 'creditMemo',
];

/** Dangerous patterns that violate accounting guardrails */
const VIOLATION_PATTERNS = [
  {
    pattern: /prisma\.(customer|vendor|product|account|invoice|salesOrder|transaction|vendorInvoice)\.delete\(/gi,
    violation: '§13.1 VIOLATION: Hard delete of guarded financial entity. Use checkDeleteAllowed() + markInactive() instead.',
    suggestion: 'Import { checkDeleteAllowed, markInactive } from "@/lib/gfs/guardrails" and check referential integrity before any deletion.',
  },
  {
    pattern: /prisma\.(customer|vendor|product|account|invoice|salesOrder|transaction|vendorInvoice)\.deleteMany\(/gi,
    violation: '§13.1 VIOLATION: Bulk delete of guarded financial entities is strictly forbidden.',
    suggestion: 'Use markInactive() for each entity individually, with audit trail logging.',
  },
  {
    pattern: /DROP\s+TABLE|TRUNCATE\s+TABLE/gi,
    violation: '§12.3 + §13 VIOLATION: DROP/TRUNCATE TABLE on financial data is forbidden.',
    suggestion: 'Financial tables can never be dropped or truncated. Use soft-delete (status/isActive fields) instead.',
  },
  {
    pattern: /status\s*[:=]\s*['"]deleted['"]/gi,
    violation: '§13.2 WARNING: Setting status to "deleted" may bypass soft-delete guardrails.',
    suggestion: 'Use status "inactive" for soft-delete. "deleted" status is only for non-financial documents.',
  },
];

/** Required patterns for financial entity management code */
const REQUIRED_PATTERNS = [
  {
    condition: /\.(customer|vendor|product|account)\.(update|create|delete)/i,
    required: /logAuditEvent|auditLog|audit/i,
    warning: '§13.4 WARNING: Financial entity modification without audit trail logging.',
    suggestion: 'Import logAuditEvent from "@/lib/gfs/guardrails" and log all create/edit/delete operations.',
  },
  {
    condition: /\.(invoice|salesOrder|transaction)\.(update|delete)/i,
    required: /checkVoidAllowed|checkEditAllowed|guardrail/i,
    warning: '§13.3 WARNING: Posted transaction modification without immutability check.',
    suggestion: 'Import checkVoidAllowed/checkEditAllowed from "@/lib/gfs/guardrails" to enforce posted-transaction immutability.',
  },
];

/**
 * Validate DF-generated code against accounting guardrails.
 * Called by The Hearth before applying any generated artifact.
 */
export function validateAccountingGuardrails(generatedCode: string): ValidationResult {
  const violations: string[] = [];
  const warnings: string[] = [];
  const suggestions: string[] = [];

  // Check for forbidden patterns
  for (const rule of VIOLATION_PATTERNS) {
    if (rule.pattern.test(generatedCode)) {
      violations.push(rule.violation);
      suggestions.push(rule.suggestion);
    }
    // Reset regex lastIndex for global patterns
    rule.pattern.lastIndex = 0;
  }

  // Check for missing required patterns
  for (const rule of REQUIRED_PATTERNS) {
    if (rule.condition.test(generatedCode) && !rule.required.test(generatedCode)) {
      warnings.push(rule.warning);
      suggestions.push(rule.suggestion);
    }
    rule.condition.lastIndex = 0;
    rule.required.lastIndex = 0;
  }

  // Check for orphaned record creation
  const createInvoiceWithoutCustomer = /prisma\.invoice\.create/.test(generatedCode) &&
    !/customerId/.test(generatedCode);
  if (createInvoiceWithoutCustomer) {
    warnings.push('§13.5.4 WARNING: Invoice creation without customerId — potential orphaned record.');
    suggestions.push('Always include customerId when creating invoices to prevent orphaned records.');
  }

  const createOrderWithoutCustomer = /prisma\.salesOrder\.create/.test(generatedCode) &&
    !/customerId/.test(generatedCode);
  if (createOrderWithoutCustomer) {
    warnings.push('§13.5.4 WARNING: Sales Order creation without customerId — potential orphaned record.');
    suggestions.push('Always include customerId when creating sales orders to prevent orphaned records.');
  }

  return {
    valid: violations.length === 0,
    violations,
    warnings,
    suggestions,
  };
}

/**
 * Summary of accounting guardrail rules for DF prompt injection.
 * Include this in the system prompt when generating financial entity code.
 */
export const GUARDRAIL_PROMPT_INJECTION = `
ACCOUNTING GUARDRAILS (Standing Orders §13 — MANDATORY):
1. NEVER use prisma.customer.delete(), prisma.vendor.delete(), prisma.product.delete(),
   prisma.account.delete(), prisma.invoice.delete(), prisma.salesOrder.delete(), or
   prisma.transaction.delete(). Use checkDeleteAllowed() + markInactive() instead.
2. ALWAYS import { checkDeleteAllowed, markInactive, logAuditEvent, checkVoidAllowed,
   voidTransaction } from '@/lib/gfs/guardrails'.
3. ALWAYS log audit events for create/edit/void/inactivate operations.
4. NEVER modify posted transactions directly — use voidTransaction() with a reason code.
5. ALWAYS include customerId when creating invoices or sales orders (no orphaned records).
6. ALWAYS include referential integrity checks before any deletion.
`.trim();
