import { readFile, writeFile, mkdir } from 'node:fs/promises';
import { join } from 'node:path';
import { expect } from 'e2e';
import { APP_DIR, T3_HOME } from '../e2e.config.ts';
import { test, WEB } from './t3.ts';

test('MCP app save prompt preserves whole characters at the filename limit', WEB, async ({t3, app, screen, browser}) => {
  const fixture = join(APP_DIR, 'apps/server/scripts/dev-replay/showcase_transcript.ndjson');
  const original = await readFile(fixture, 'utf8');
  const attachmentId = 'download-demo-00000000-0000-4000-8000-000000000001-html';
  const reference = {attachmentId, server:'Download demo', tool:'export', resourceUri:'ui://download/export'};
  const update = (u: unknown) => ({type:'emit_inbound', frame:{kind:'notification', method:'session/update',params:{sessionId:'dev-replay-session',update:u}}});
  const transcript = [
    {type:'expect_outbound',frame:{kind:'request',method:'session/prompt',params:'<any>'}},
    update({sessionUpdate:'tool_call',toolCallId:'download-export',kind:'other',title:'Download demo.export',status:'pending',rawInput:{}}),
    update({sessionUpdate:'tool_call_update',toolCallId:'download-export',status:'completed',rawOutput:{t3McpApp:reference}}),
    update({sessionUpdate:'agent_message_chunk',content:{type:'text',text:'The export app is ready. Try the short control, then the long filename.'}}),
    {type:'emit_inbound',frame:{kind:'response',method:'session/prompt',result:{stopReason:'end_turn'}}}
  ].map(x=>JSON.stringify(x)).join('\n')+'\n';
  const html = `<!doctype html><meta charset="utf-8"><style>body{font:16px system-ui;padding:20px;color:#eee;background:#18181b}button{padding:10px;margin:8px;font:inherit}p{line-height:1.6}</style><h2>CSV export · Unicode filename</h2><p>Control: short😀.csv<br>Boundary case: 199 × “a” + 😀.csv</p><button id="short" disabled>Download short filename</button><button id="long" disabled>Download long filename</button><script>
  const send=(method,params,id)=>parent.postMessage({jsonrpc:'2.0',method,params,...(id?{id}:{})},'*');
  addEventListener('message',e=>{if(e.data.id==='init'){send('ui/notifications/initialized');document.querySelectorAll('button').forEach(b=>b.disabled=false)}});
  send('ui/initialize',{appCapabilities:{}},'init');
  for(const kind of ['short','long'])document.getElementById(kind).onclick=()=>send('ui/download-file',{contents:[{type:'resource_link',uri:'file:///synthetic.csv',name:kind==='short'?'short😀.csv':'a'.repeat(199)+'😀.csv',mimeType:'text/csv'}]},kind);
  </script>`;
  try {
    await writeFile(fixture, transcript);
    await mkdir(join(T3_HOME,'userdata/attachments'),{recursive:true});
    await writeFile(join(T3_HOME,'userdata/attachments',attachmentId+'.html'),html);
    const project=await t3.project('Unicode download');
    await t3.thread({project,title:'MCP export filenames',model:'showcase',messages:['Show the CSV export app']});
    await t3.open();
    await screen.getByRole('button','MCP export filenames, Done, Unicode download',{exact:true}).tap();
    const frame=browser.frameLocator('iframe');
    await frame.getByRole('button','Download short filename').tap();
    await screen.getByText('Save short😀.csv from Download demo?',{exact:true}).waitFor({state:'visible'});
    await app.screenshot('short-control');
    await screen.getByRole('button','Cancel',{exact:true}).tap();
    await frame.getByRole('button','Download long filename').tap();
    await screen.getByRole('alertdialog').waitFor({state:'visible'});
    await app.screenshot('long-save-prompt');
    const message = await browser.evaluate(()=>document.querySelector('[role="alertdialog"]')?.textContent ?? '');
    expect(message.isWellFormed()).toBe(true);
  } finally { await writeFile(fixture,original); }
});
