/**
 * SET 45b/c — substrate handoff page + efficacy strip helpers.
 */
import { describe, expect, it } from 'vitest';
import {
  assembleSuperbuffer,
  extractSpecConstants,
  STAGE_PAGE_POLICY,
} from '../src/tier1/superbuffer';
import {
  buildSubstrateHandoff,
  formatSubstrateHandoffPage,
  hasSubstrateHandoffHistory,
} from '../src/tier1/substrateHandoff';
import {
  formatSubstratePageEfficacy,
  formatSubstrateStrip,
  noteSubstratePageEfficacy,
  emptySubstratePageEfficacy,
} from '../src/tier1/statsAggregate';
import type { FeatureNode, FeatureSpec } from '../src/core/types';
import type { IRParts } from '../src/core/irScaffold';

const feature: FeatureNode = {
  id: 'F1',
  name: 'Widget',
  description: 'Widget with status ACTIVE and limit 10',
  parentId: null,
  deps: [],
  files: ['src/a.ts', 'src/b.ts'],
  testFile: 'tests/f1.test.ts',
  edgeCases: [],
  exports: [{ symbol: 'Widget', file: 'src/a.ts' }],
  envVars: [],
  stubs: [
    {
      path: 'src/a.ts',
      content: 'export function Widget(): string { return "ACTIVE"; }\n',
    },
  ],
};

const spec: FeatureSpec = {
  title: 'Widget',
  prompt: 'status ACTIVE limit 10',
  features: [feature],
};

const parts: IRParts = {
  imports: [],
  cases: [{ name: 'renders', kind: 'behavior', body: 'expect(1).toBe(1);' }],
};

function assemble(handoff: ReturnType<typeof buildSubstrateHandoff>, stage: 'fill' | 'repair' = 'repair') {
  return assembleSuperbuffer({
    spec,
    feature,
    parts,
    stubs: feature.stubs,
    lessons: [],
    siblingParts: new Map(),
    target: 'unresolved-import|./mod',
    stage,
    substrateHandoff: handoff,
  });
}

describe('SET 45b substrate handoff page', () => {
  it('exposes substrate early on fill + repair policies', () => {
    expect(STAGE_PAGE_POLICY.fill[0]).toBe('substrate');
    expect(STAGE_PAGE_POLICY.repair[0]).toBe('substrate');
    expect(STAGE_PAGE_POLICY.build).not.toContain('substrate');
  });

  it('refused-import fixture: repair prompt contains both candidate site names', () => {
    const handoff = buildSubstrateHandoff({
      classKey: 'unresolved-import|./mod',
      stratum: 'mechanical',
      attempts: [{
        handler: 'import-rewire',
        status: 'refused',
        reason: 'ambiguous export module (fitness tie among 2 candidates)',
        candidateSites: ['src/a.ts', 'src/b.ts'],
      }],
      constants: extractSpecConstants('status ACTIVE limit 10'),
    });
    expect(handoff).not.toBeNull();
    const page = formatSubstrateHandoffPage(handoff);
    expect(page).toContain('src/a.ts');
    expect(page).toContain('src/b.ts');
    expect(page).toMatch(/import-rewire: refused — 2 candidate sites:/);

    const assembly = assemble(handoff, 'repair');
    expect(assembly.pages.substrate).toBeDefined();
    expect(assembly.promptBlock).toContain('src/a.ts');
    expect(assembly.promptBlock).toContain('src/b.ts');
    expect(assembly.logLine).toMatch(/substrate:\d+/);
  });

  it('no-substrate-history draw omits the page entirely', () => {
    expect(hasSubstrateHandoffHistory(null)).toBe(false);
    expect(formatSubstrateHandoffPage(null)).toBe('');
    const assembly = assemble(null, 'repair');
    expect(assembly.pages.substrate).toBeUndefined();
    expect(assembly.promptBlock).not.toContain('Page substrate');
    expect(assembly.logLine).not.toMatch(/substrate:\d+/);
  });
});

describe('SET 45a/c strip + efficacy', () => {
  it('formats substrate strip', () => {
    expect(formatSubstrateStrip({
      actions: 12, fixes: 4, attempts: 12, refusals: 5, candidates: 3,
    })).toBe('substrate: 12 actions (4 fixes · 12 attempts · 5 refusals · 3 candidates)');
  });

  it('formats WITH vs WITHOUT substrate page efficacy (34d pattern)', () => {
    const buckets = emptySubstratePageEfficacy();
    noteSubstratePageEfficacy(buckets, true, true);
    noteSubstratePageEfficacy(buckets, true, true);
    noteSubstratePageEfficacy(buckets, true, false);
    noteSubstratePageEfficacy(buckets, false, false);
    noteSubstratePageEfficacy(buckets, false, false);
    expect(formatSubstratePageEfficacy(buckets.withPage, buckets.withoutPage)).toBe(
      'substrate page: 3 cases, 2 filled (67%) · no substrate page: 2 cases, 0 filled (0%)',
    );
  });
});
