// ── Error Codes ──────────────────────────────────────────────────

export type ErrorCode =
  | 'payment-required'
  | 'payment-insufficient'
  | 'payment-expired'
  | 'verification-failed'
  | 'method-unsupported'
  | 'malformed-credential'
  | 'invalid-challenge'
  | 'tx-reverted'
  | 'swap-reverted'
  | 'token-uninitialized'
  | 'tip-403'
  | 'policy-violation'
  | 'cascade-failure'
  | 'offramp-failed'
  | 'rate-limited'
  | 'server-error'
  | 'timeout'
  | 'gas-estimation-failed'
  | 'gas-underpriced'
  | 'gas-too-low'
  | 'gas-spike'
  | 'gas-limit-exceeded'
  | 'paymaster-balance-low'
  | 'wallet-locked'
  | 'unknown';

// ── Failure Categories ──────────────────────────────────────────

export type FailureCategory =
  | 'balance'
  | 'session'
  | 'currency'
  | 'signature'
  | 'batch'
  | 'service'
  | 'dex'
  | 'compliance'
  | 'cascade'
  | 'offramp'
  | 'network'
  | 'policy'
  | 'auth'
  | 'gas'
  | 'unknown';

export type Severity = 'low' | 'medium' | 'high' | 'critical';

export type Platform = 'tempo' | 'privy' | 'coinbase' | 'stripe' | 'generic' | 'unknown';

// ── Repair Context ──────────────────────────────────────────────

/**
 * Environmental context at the time of repair.
 * Used by Context-Aware Gene Map to select the best strategy for current conditions.
 */
export interface RepairContext {
  chainId?: number;
  gasPriceGwei?: number;
  hourOfDay?: number;
  agentId?: string;
  [key: string]: unknown;
}

// ── Execution Mode ──────────────────────────────────────────────

export type HelixMode = 'observe' | 'auto' | 'full';

// ── PCEC Types ──────────────────────────────────────────────────

export interface FailureClassification {
  code: ErrorCode;
  category: FailureCategory;
  severity: Severity;
  platform: Platform;
  details: string;
  timestamp: number;
  rootCauseHint?: string;
  llmClassified?: boolean;
  llmReasoning?: string;
  actualBalance?: number;
  requiredAmount?: number;
  chainId?: number;
  walletAddress?: string;
}

/** A single step in a multi-step repair chain */
export interface StrategyStep {
  /** Strategy name to execute */
  strategy: string;
  /** If this step fails, stop the chain (default: true) */
  stopOnFailure?: boolean;
}

export interface RepairCandidate {
  id: string;
  strategy: string;
  /** Multi-step chain. If present, execute steps in order instead of single strategy. */
  steps?: StrategyStep[];
  description: string;
  estimatedCostUsd: number;
  estimatedSpeedMs: number;
  requirements: string[];
  score: number;
  successProbability: number;
  platform: Platform;
  source?: 'adapter' | 'gene' | 'llm';
  reasoning?: string;
}

export interface GeneCapsule {
  id?: number;
  failureCode: ErrorCode;
  category: FailureCategory;
  strategy: string;
  params: Record<string, unknown>;
  successCount: number;
  avgRepairMs: number;
  platforms: Platform[];
  qValue: number;
  qVariance?: number;
  qCount?: number;
  last5Rewards?: number[];
  consecutiveFailures: number;
  lastSuccessAt?: number;
  lastFailedAt?: number;
  createdAt?: string;
  lastUsedAt?: string;
  // OPT-4: ReasoningBank
  reasoning?: string;
  failureAnalysis?: string[];
  successContext?: { chains?: string[]; walletTypes?: string[]; platforms?: string[] };
  failureContext?: { chains?: string[]; walletTypes?: string[]; note?: string };
  /** Multi-dimensional repair scores */
  scores?: Record<string, number>;
  /** Original Q-value before context adjustment (set by context-aware lookup) */
  _originalQValue?: number;
  /** Context similarity score 0.5–1.0 (set by context-aware lookup) */
  _contextSimilarity?: number;
}

export interface RepairResult {
  success: boolean;
  failure: FailureClassification;
  candidates: RepairCandidate[];
  winner: RepairCandidate | null;
  gene: GeneCapsule | null;
  immune: boolean;
  totalMs: number;
  revenueProtected: number;
  mode: HelixMode;
  explanation: string;
  verified: boolean;
  skippedStrategies?: string[];
  costEstimate: number;
  // OPT-10: Failure Attribution
  attribution?: { agentId: string; stepId?: string; workflow?: string; timestamp: number };
  /** Overrides from strategy execution — used by wrap() auto-detect for retry */
  commitOverrides?: Record<string, unknown>;
  /** If strategy chain was used, list of steps executed */
  stepsExecuted?: { strategy: string; success: boolean; ms: number }[];
  /** True if business-level verify() callback returned false */
  verifyFailed?: boolean;
  /** Predicted next failures (from Predictive Failure Graph) */
  predictions?: { code: string; category: string; probability: number; avgDelayMs: number }[];
}

// ── Platform Adapter Interface ──────────────────────────────────

export interface PlatformAdapter {
  name: Platform;
  perceive(error: Error, context?: Record<string, unknown>): FailureClassification | null;
  construct(failure: FailureClassification): RepairCandidate[];
}

// ── Provider Config ─────────────────────────────────────────────

export interface DexConfig {
  routerAddress: `0x${string}`;
  quoterAddress?: `0x${string}`;
  wethAddress: `0x${string}`;
  defaultTokens: { usdc?: `0x${string}`; usdt?: `0x${string}`; dai?: `0x${string}` };
  defaultSlippage: number;
  defaultDeadlineSeconds: number;
}

export interface HelixProviderConfig {
  rpcUrl?: string;
  privateKey?: string;
  privy?: { appId: string; appSecret: string; walletId?: string };
  coinbase?: { apiKeyName: string; apiKeyPrivateKey: string };
  dex?: DexConfig;
}

// ── SSE Event Types ─────────────────────────────────────────────

export type SseEventType =
  | 'perceive'
  | 'construct'
  | 'evaluate'
  | 'commit'
  | 'verify'
  | 'gene'
  | 'immune'
  | 'error'
  | 'stats'
  | 'retry';

export interface SseEvent {
  type: SseEventType;
  agentId: string;
  timestamp: number;
  data: Record<string, unknown>;
}

// ── Config ──────────────────────────────────────────────────────

export interface HelixConfig {
  projectName: string;
  walletAddress: string;
  stablecoins: string[];
  monthlyBudget: number;
  maxRetries: number;
  timeoutMs: number;
  dashboardPort: number;
  verbose: boolean;
  geneMapPath: string;
}

export interface WrapOptions {
  agentId?: string;
  maxRetries?: number;
  verbose?: boolean;
  geneMapPath?: string;
  platforms?: string[];
  config?: Partial<HelixConfig>;
  mode?: HelixMode;
  enabled?: boolean | (() => boolean);
  maxRepairCostUsd?: number;
  maxSlippage?: number;
  approvedTokens?: string[];
  allowCategories?: string[];
  blockStrategies?: string[];
  provider?: HelixProviderConfig;
  onRepair?: (result: RepairResult) => void;
  onFailure?: (result: RepairResult) => void;
  onHelixError?: (error: Error) => void;
  onSystematic?: (warning: string, failure: FailureClassification) => void;
  /** Apply repair overrides to function args for retry. */
  parameterModifier?: (args: unknown[], overrides: Record<string, unknown>, strategy: string) => unknown[];
  /**
   * Pre-execution hook. Called BEFORE every call to the wrapped fn (including retries).
   * Receives the current args; may return modifiedArgs to substitute, and an optional note.
   * Errors thrown by preflight are swallowed (logged at warn level); original args are used.
   * Use this to consult Gene Map / capsule history and proactively reshape args.
   */
  preflight?: (args: unknown[]) => Promise<{ modifiedArgs?: unknown[]; note?: string }>;
  context?: Record<string, unknown>;
  /** LLM fallback for classifying unknown errors. Disabled by default. */
  llm?: { provider?: 'anthropic' | 'openai'; apiKey?: string; fallbackApiKey?: string; model?: string; timeoutMs?: number; enabled?: boolean };
  /** Telemetry: anonymously report discoveries to improve seed genes. Default: disabled. */
  telemetry?: { enabled?: boolean; endpoint?: string; onTelemetry?: (event: unknown) => boolean };
  /** Custom logger (pino, winston, etc). Default: console with colors. */
  logger?: { debug(m: string, d?: Record<string, unknown>): void; info(m: string, d?: Record<string, unknown>): void; warn(m: string, d?: Record<string, unknown>): void; error(m: string, d?: Record<string, unknown>): void };
  /** Log level. Default: 'warn'. Set 'info' for verbose, 'debug' for everything. */
  logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'silent';
  /** Log format. 'pretty' (colored) or 'json' (structured). Default: 'pretty'. */
  logFormat?: 'pretty' | 'json';
  /**
   * Business-level verification after successful repair + retry.
   *
   * Called after the retried function succeeds. If verify returns false,
   * the repair is treated as a failure (Gene q_value decreases).
   *
   * @param result - The return value of the retried function
   * @param originalArgs - The original arguments passed to wrap(fn)
   * @returns true if the result is valid, false to treat as failure
   */
  verify?: (result: unknown, originalArgs: unknown[]) => Promise<boolean> | boolean;
  /** OpenTelemetry configuration. Provide your own tracer/meter for distributed tracing and metrics. */
  otel?: { tracer?: any; meter?: any; serviceName?: string };
  /** Gene Registry configuration for shared learning across instances. */
  registry?: { url?: string; apiKey?: string; agentId?: string; minQualityForPush?: number; minQualityForPull?: number; syncIntervalMs?: number; pushBatchSize?: number; pullBatchSize?: number };
  /** Callback to refresh session/auth token when renew_session strategy fires. */
  sessionRefresher?: () => Promise<Record<string, unknown> | string>;
  /** Config for split_transaction strategy. */
  splitConfig?: { parts?: number; delayMs?: number; minAmount?: number };
}

// ── Revenue estimates per category ──────────────────────────────

export const REVENUE_AT_RISK: Record<string, number> = {
  balance: 150, session: 50, currency: 200, signature: 100,
  batch: 500, service: 300, dex: 175, compliance: 250,
  cascade: 1000, offramp: 400, network: 100, policy: 200,
  auth: 50, unknown: 50,
};

// ── Default Config ──────────────────────────────────────────────

export const DEFAULT_CONFIG: HelixConfig = {
  projectName: 'helix-agent',
  walletAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18',
  stablecoins: ['USDC', 'USDT', 'DAI'],
  monthlyBudget: 10000,
  maxRetries: 3,
  timeoutMs: 30000,
  dashboardPort: 7842,
  verbose: true,
  geneMapPath: './helix-genes.db',
};
