// End-to-end confirmation of the diashow SSE fix, reproducing the ORIGINAL failure:
// kiosk opens /diashow directly BEFORE any photos exist, then a guest uploads.
// Pre-fix: stream never opens, display stuck on "Noch keine Beiträge" forever.
// Post-fix: stream opens on mount, the uploaded photo appears live.
import { chromium } from '@playwright/test';
import { readFileSync } from 'node:fs';

const BASE = 'http://localhost:3101';
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const j = (r) => r.json();

const adminLogin = () =>
  fetch(`${BASE}/api/v1/admin/login`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ password: 'admin-test-pw' }),
  })
    .then(j)
    .then((b) => b.jwt);
const join = (name) =>
  fetch(`${BASE}/api/v1/join`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ display_name: name }),
  }).then(j);
async function truncate(admin) {
  await fetch(`${BASE}/api/v1/admin/__truncate`, {
    method: 'POST',
    headers: { Authorization: `Bearer ${admin}` },
  });
}
async function upload(jwt) {
  const form = new FormData();
  form.append(
    'file',
    new Blob([readFileSync('/tmp/eventsnap-loadtest/photos/photo_000.jpg')], {
      type: 'image/jpeg',
    }),
    'live.jpg'
  );
  form.append('caption', 'LIVE-PROBE');
  const r = await fetch(`${BASE}/api/v1/upload`, {
    method: 'POST',
    headers: { Authorization: `Bearer ${jwt}` },
    body: form,
  });
  return (await r.json()).id;
}

// Reproduce the failing scenario: empty event, then open /diashow directly.
let admin = await adminLogin();
await truncate(admin);
admin = await adminLogin();
const showcase = await join('Showcase Display');
const guest = await join('Uploading Guest');

const browser = await chromium.launch();
const ctx = await browser.newContext({ viewport: { width: 1280, height: 800 } });
const page = await ctx.newPage();
const streamReqs = [];
page.on('request', (req) => {
  if (req.url().includes('/stream')) streamReqs.push(req.url().replace(BASE, ''));
});

await page.goto(`${BASE}/join`, { waitUntil: 'domcontentloaded' });
await page.evaluate((g) => {
  localStorage.setItem('eventsnap_jwt', g.jwt);
  localStorage.setItem('eventsnap_pin', g.pin);
  localStorage.setItem('eventsnap_user_id', g.user_id);
  localStorage.setItem('eventsnap_display_name', 'Showcase');
  localStorage.setItem('eventsnap_guide_seen', '1');
}, showcase);

// Open /diashow DIRECTLY (never via /feed) on an EMPTY event.
await page.goto(`${BASE}/diashow`, { waitUntil: 'domcontentloaded' });
await sleep(2500);
const emptyBefore = (await page.locator('text=Noch keine Beiträge').count()) > 0;
const streamOpened = streamReqs.length > 0;
console.log(`\n1) direct /diashow on empty event:`);
console.log(`   "Noch keine Beiträge" shown: ${emptyBefore}  (expected: true)`);
console.log(
  `   SSE stream opened: ${streamOpened}  ${streamOpened ? '(' + streamReqs.join(', ') + ')' : ''}  (expected: true — this is the fix)`
);

// Now a guest uploads a photo while the display is open.
console.log(`\n2) guest uploads a photo (display already open)…`);
await upload(guest.jwt);

// Wait for compression → upload-processed SSE → debounced refresh → slide appears.
let appeared = false;
for (let i = 0; i < 15; i++) {
  await sleep(1000);
  const stillEmpty = (await page.locator('text=Noch keine Beiträge').count()) > 0;
  const imgs = await page.locator('img').count();
  if (!stillEmpty && imgs > 0) {
    appeared = true;
    console.log(`   photo appeared live after ~${i + 1}s (img rendered, placeholder gone)`);
    break;
  }
}
if (!appeared) console.log(`   ✗ photo did NOT appear within 15s`);

await page.screenshot({ path: 'results/diashow-fix-confirm.png' });
await browser.close();

console.log(`\n════ VERDICT ════`);
console.log(`SSE opens on direct /diashow: ${streamOpened ? 'YES ✓' : 'NO ✗'}`);
console.log(`Live photo appears on showcase: ${appeared ? 'YES ✓' : 'NO ✗'}`);
console.log(streamOpened && appeared ? 'FIX CONFIRMED' : 'FIX NOT confirmed');
