const fs=require('fs'),vm=require('vm'),assert=require('assert');
const src=fs.readFileSync('static/app.js','utf8');
const start=src.indexOf('function lines('),end=src.indexOf('function scenarioSlug(');
assert(start>=0&&end>start,'scenario helper block missing');
const ids=['creatorSummary','creatorCardHook','creatorPremise','creatorScenarioSetup','creatorHistory','creatorRelationshipHistory','creatorSideCharacters','creatorLocations','creatorGroups','creatorObjects','creatorSecrets','creatorWorldRules','creatorCurrentState','creatorPhysicalContinuity','creatorTimeline','creatorHooks','creatorHardRules','creatorSceneLocation','creatorSceneDate','creatorSceneTime','creatorPresentCast','creatorSceneSituation','creatorGenre','creatorTone'];
const elements=Object.fromEntries(ids.map(id=>[id,{value:'',dispatchEvent(){}}]));
const context={
  console,Date,state:{creatorCharacters:[]},Event:function(){},csv:v=>String(v||'').split(',').map(x=>x.trim()).filter(Boolean),
  $:s=>elements[String(s).replace(/^#/,'')]||null,escapeHtml:String,toast(){},scenarioParticipantWinImportAutofill(){},
};
vm.createContext(context);vm.runInContext(src.slice(start,end),context);
const fields={
  premise:'Premise',scenario_setup:'Start',history:['History'],relationship_history:['Rivals'],characters:['A — lead'],locations:['Citadel'],
  organisations:['Wardens'],artefacts:['Key'],secrets:['Hidden door'],rules:['Magic costs'],present_state:['At war'],physical_state:['A has a broken arm'],
  timeline:['Year 1'],hooks:['Survive'],hard_rules:['No resurrection'],scene:{location:'Gate',era:'Modern',time:'Night',present_cast:['A','B'],situation:'Attack'},
  genre:'Fantasy',tone:'Dark'
};
context.applyScenarioAutofill({description:'Summary only',card_hook:'Hook',fields},false);
assert.strictEqual(elements.creatorSummary.value,'Summary only');
assert.strictEqual(elements.creatorPhysicalContinuity.value,'A has a broken arm');
assert.strictEqual(elements.creatorGroups.value,'Wardens');
assert.strictEqual(elements.creatorObjects.value,'Key');
assert.strictEqual(elements.creatorSceneDate.value,'Modern');
assert.strictEqual(elements.creatorGenre.value,'Fantasy');
elements.creatorPhysicalContinuity.value='User authored';
context.applyScenarioAutofill({fields:{physical_continuity:['Replacement']}},false);
assert.strictEqual(elements.creatorPhysicalContinuity.value,'User authored');
context.applyScenarioAutofill({fields:{physical_continuity:['Replacement']}},true);
assert.strictEqual(elements.creatorPhysicalContinuity.value,'Replacement');
for(const id of ids)assert(elements[id],`visible field missing: ${id}`);
console.log(`scenario autofill contract: ${ids.length} visible fields mapped; aliases and Replace policy passed`);
