// Ревью R2-3: климат комнат считался отдельным обходом реестра на каждую
// комнату и каждую величину — 60 комнат × 2000 сущностей съедали кадр на
// перечитывании метаданных, которые не менялись. Карта строится один раз на
// снимок hass; при этом новые состояния датчиков обязаны попадать в неё сразу.
import { launch, checkAll, finish } from './serve.mjs';
const { page, browser } = await launch();
const res = await page.evaluate(async () => {
  const out = {};
  const c = window.__card;
  const sr = () => c.shadowRoot || c.renderRoot;

  // считаем обходы реестра через ownKeys — именно его дёргает Object.entries
  let scans = 0;
  const wrap = (h) => {
    const ents = h.entities;
    const traced = new Proxy(ents, { ownKeys(t) { scans++; return Reflect.ownKeys(t); } });
    return { ...h, entities: traced };
  };
  const fresh = () => wrap(window.__mkHass());

  // включаем и заливку по температуре, и подписи — два потребителя климата
  c._serverCfg = { ...c._serverCfg, spaces: c._serverCfg.spaces.map((s) => s.id !== 'f1' ? s : {
    ...s, settings: { ...(s.settings || {}), show_names: true, fill_mode: 'temp', label_temp: true, label_hum: true },
  })};
  c._cfgEpoch++;
  c.hass = fresh(); await c.updateComplete;

  scans = 0;
  c.hass = fresh(); await c.updateComplete;
  const fewRooms = scans;

  // повторные рендеры на том же снимке hass реестр не трогают
  scans = 0;
  c.requestUpdate(); await c.updateComplete;
  c.requestUpdate(); await c.updateComplete;
  out.scansOnRerender = scans;

  // главный инвариант: обходов НЕ становится больше от числа комнат
  const f1 = c._serverCfg.spaces.find((s) => s.id === 'f1');
  const extra = [];
  for (let i = 0; i < 40; i++) {
    extra.push({ id: 'gen' + i, name: 'R' + i, area: 'living_room',
      poly: [[0.01, 0.01], [0.02, 0.01], [0.02, 0.02], [0.01, 0.02]] });
  }
  c._serverCfg = { ...c._serverCfg, spaces: c._serverCfg.spaces.map((s) =>
    s.id !== 'f1' ? s : { ...s, rooms: [...s.rooms, ...extra] }) };
  c._cfgEpoch++;
  c.hass = fresh(); await c.updateComplete;
  scans = 0;
  c.hass = fresh(); await c.updateComplete;
  out.roomCount = c._spaceModel('f1').rooms.length;
  out.scansSameWith44Rooms = scans === fewRooms;
  out.scansPerUpdate = scans;

  // при этом новое состояние датчика обязано быть видно, а не взято из кэша
  out.tempBefore = c._climate().get('living_room')?.temp;
  const h = fresh();
  h.states = { ...h.states, 'sensor.living_temp': { ...h.states['sensor.living_temp'], state: '33.3' } };
  c.hass = h; await c.updateComplete;
  out.tempAfter = c._climate().get('living_room')?.temp;
  out.climateIsMap = c._climate() instanceof Map;
  return out;
});
// зафиксировано прогоном на v1.45.0 и сверено с кодом.
// scansPerUpdate = 2: один обход у areaClimateMap, один у buildDevices. Важно
// не само число, а что оно не растёт вместе с числом комнат.
checkAll(res, {
  scansOnRerender: 0,
  roomCount: 44,
  scansSameWith44Rooms: true,
  scansPerUpdate: 2,
  tempBefore: 22.4,
  tempAfter: 33.3,
  climateIsMap: true,
});
await finish(browser);
