/**
 * Blast Radius Limiter — "The Small Bets Rule"
 * 
 * Enforces scoped operations, prevents broad uncontrolled changes,
 * and ensures every task is broken into tiny, verifiable actions.
 * 
 * Reference: Nate B Jones — "5 Management Skills for AI Agent Builders"
 * Skill #4: Small Bets and Blast Radius
 */

export interface BlastRadiusConfig {
  /** Max entities per single autonomous operation */
  maxEntitiesPerOperation: number;
  /** Max file changes per self-mod proposal */
  maxFileChangesPerProposal: number;
  /** Max concurrent agent operations */
  maxConcurrentOps: number;
  /** Require staged rollout for changes affecting > N components */
  stagedRolloutThreshold: number;
  /** Operations affecting > this many records require human approval */
  humanApprovalThreshold: number;
}

const DEFAULT_CONFIG: BlastRadiusConfig = {
  maxEntitiesPerOperation: 10,
  maxFileChangesPerProposal: 3,
  maxConcurrentOps: 3,
  stagedRolloutThreshold: 5,
  humanApprovalThreshold: 100,
};

export interface ScopeCheck {
  allowed: boolean;
  violations: string[];
  recommendations: string[];
  requiresHumanApproval: boolean;
  requiresStagedRollout: boolean;
}

/**
 * Check if a proposed operation fits within blast-radius limits.
 * 
 * Standing Order 3.1: "Maximum 10 entities per single autonomous operation."
 * Standing Order 3.2: "Every task must have a clearly scoped target."
 */
export function checkBlastRadius(
  operation: {
    type: string;
    entityType: string;
    entityCount: number;
    affectedComponents?: string[];
    fileChanges?: number;
    description: string;
  },
  config: BlastRadiusConfig = DEFAULT_CONFIG
): ScopeCheck {
  const violations: string[] = [];
  const recommendations: string[] = [];
  let requiresHumanApproval = false;
  let requiresStagedRollout = false;

  // Check entity count limit
  if (operation.entityCount > config.maxEntitiesPerOperation) {
    violations.push(
      `[3.1] Operation affects ${operation.entityCount} entities ` +
      `(max ${config.maxEntitiesPerOperation}). Split into smaller batches.`
    );
    recommendations.push(
      `Break into ${Math.ceil(operation.entityCount / config.maxEntitiesPerOperation)} ` +
      `batches of ${config.maxEntitiesPerOperation} with verification between each.`
    );
  }

  // Check file changes limit (for self-mod)
  if (operation.fileChanges && operation.fileChanges > config.maxFileChangesPerProposal) {
    violations.push(
      `[8.2] Self-mod proposal changes ${operation.fileChanges} files ` +
      `(max ${config.maxFileChangesPerProposal}). Split into separate proposals.`
    );
  }

  // Check if staged rollout is needed
  const componentCount = operation.affectedComponents?.length || 0;
  if (componentCount > config.stagedRolloutThreshold) {
    requiresStagedRollout = true;
    recommendations.push(
      `Changes affect ${componentCount} components. Staged rollout required.`
    );
  }

  // Check human approval threshold
  if (operation.entityCount > config.humanApprovalThreshold) {
    requiresHumanApproval = true;
    violations.push(
      `[6.3] Operation affects ${operation.entityCount} records ` +
      `(> ${config.humanApprovalThreshold}). Human approval required.`
    );
  }

  // Broad refactor detection
  const broadKeywords = ['refactor', 'migrate', 'overhaul', 'rebuild', 'rewrite'];
  const isBroad = broadKeywords.some(kw =>
    operation.description.toLowerCase().includes(kw)
  );
  if (isBroad) {
    violations.push(
      '[3.2] Broad operation detected ("' +
      operation.description.slice(0, 50) +
      '..."). Break into specific, scoped sub-tasks.'
    );
    recommendations.push(
      'Decompose into discrete tasks: one endpoint, one component, or one table per task.'
    );
  }

  return {
    allowed: violations.length === 0,
    violations,
    recommendations,
    requiresHumanApproval,
    requiresStagedRollout,
  };
}

/**
 * Split a large operation into compliant batches.
 * 
 * Standing Order 3.1: "For larger batches, split into chunks and
 * pause between each for verification."
 */
export function createBatchPlan(
  totalEntities: number,
  config: BlastRadiusConfig = DEFAULT_CONFIG
): { batchSize: number; batchCount: number; pauseBetweenMs: number } {
  const batchSize = Math.min(totalEntities, config.maxEntitiesPerOperation);
  const batchCount = Math.ceil(totalEntities / batchSize);
  const pauseBetweenMs = 2000; // 2 second pause between batches for verification

  return { batchSize, batchCount, pauseBetweenMs };
}
