'use strict';
// Baanschema-editor: teken de baan op een raster, koppel wissels/blokken aan een nummer,
// en bekijk live de bezetmelding + wisselstand. Werkt bovenop window.BB (uit app.js).
(function () {
  const $ = (s) => document.querySelector(s);
  const TRK = '#6b7585', DIM = '#39414f', ACT = '#4c8bf5';
  let layout = { cols: 14, rows: 8, tiles: {} };
  let mode = 'view';          // 'view' | 'edit'
  let palType = 'h';          // actief palet-type
  let palRef = null;          // gekoppeld nummer voor wissel/blok
  let roster = { turnouts: [], blocks: [] };

  // ---- tile-tekeningen (40x40) ----------------------------------------
  function path(d, color, w) { return '<path d="' + d + '" fill="none" stroke="' + color + '" stroke-width="' + (w || 4) + '" stroke-linecap="round"/>'; }
  function tileSVG(type, o) {
    o = o || {};
    let s = '';
    switch (type) {
      case 'h': s = path('M0,20 H40', TRK); break;
      case 'v': s = path('M20,0 V40', TRK); break;
      case 'ne': s = path('M40,20 Q20,20 20,0', TRK); break;
      case 'nw': s = path('M0,20 Q20,20 20,0', TRK); break;
      case 'se': s = path('M40,20 Q20,20 20,40', TRK); break;
      case 'sw': s = path('M0,20 Q20,20 20,40', TRK); break;
      case 'x': s = path('M0,20 H40', TRK) + path('M20,0 V40', TRK); break;
      case 'th': {
        const thrown = !!o.thrown;
        s = path('M0,20 H40', thrown ? DIM : ACT) + path('M20,20 L40,3', thrown ? ACT : DIM);
        break;
      }
      case 'bh':
        s = '<rect class="blkfill" x="0" y="13" width="40" height="14" rx="3" fill="transparent"/>' + path('M0,20 H40', TRK) +
            (o.ref != null ? '<text x="20" y="13" text-anchor="middle" font-size="9" fill="#8b97a8">' + o.ref + '</text>' : '');
        break;
      case 'bv':
        s = '<rect class="blkfill" x="13" y="0" width="14" height="40" rx="3" fill="transparent"/>' + path('M20,0 V40', TRK) +
            (o.ref != null ? '<text x="27" y="12" text-anchor="middle" font-size="9" fill="#8b97a8">' + o.ref + '</text>' : '');
        break;
      default: s = '';
    }
    return '<svg viewBox="0 0 40 40">' + s + '</svg>';
  }
  const TYPES = ['h', 'v', 'ne', 'nw', 'se', 'sw', 'x', 'th', 'bh', 'bv'];
  const isTurnout = (t) => t === 'th';
  const isBlock = (t) => t === 'bh' || t === 'bv';

  // ---- palet -----------------------------------------------------------
  function renderPalette() {
    const p = $('#sch-palette'); p.innerHTML = '';
    TYPES.forEach((t) => {
      const b = document.createElement('button');
      b.className = 'pal' + (palType === t ? ' on' : '');
      b.innerHTML = tileSVG(t, { thrown: false });
      b.title = t;
      b.onclick = () => { palType = t; palRef = null; renderPalette(); renderRefRow(); };
      p.appendChild(b);
    });
    // gum
    const e = document.createElement('button');
    e.className = 'pal' + (palType === 'erase' ? ' on' : '');
    e.innerHTML = '<svg viewBox="0 0 40 40"><text x="20" y="27" text-anchor="middle" font-size="20">🧽</text></svg>';
    e.title = 'gum';
    e.onclick = () => { palType = 'erase'; renderPalette(); renderRefRow(); };
    p.appendChild(e);
  }

  function renderRefRow() {
    const r = $('#sch-refrow');
    let html = '';
    // raster-grootte
    html += 'Raster: <select id="sch-cols"></select>×<select id="sch-rows"></select>';
    if (isTurnout(palType) || isBlock(palType)) {
      const list = isTurnout(palType) ? roster.turnouts : roster.blocks;
      html += ' &nbsp;|&nbsp; ' + (isTurnout(palType) ? 'wissel' : 'blok') + ': <select id="sch-ref"><option value="">— kies —</option>' +
        list.map((x) => '<option value="' + x.id + '"' + (String(palRef) === String(x.id) ? ' selected' : '') + '>' + x.id + ' · ' + x.name + '</option>').join('') + '</select>';
    }
    r.innerHTML = html;
    const cs = $('#sch-cols'), rs = $('#sch-rows');
    for (let i = 6; i <= 60; i++) { cs.add(new Option(i, i, false, i === layout.cols)); }
    for (let i = 4; i <= 40; i++) { rs.add(new Option(i, i, false, i === layout.rows)); }
    cs.onchange = () => { layout.cols = parseInt(cs.value, 10); render(); };
    rs.onchange = () => { layout.rows = parseInt(rs.value, 10); render(); };
    const ref = $('#sch-ref'); if (ref) ref.onchange = () => { palRef = ref.value ? parseInt(ref.value, 10) : null; };
  }

  // ---- raster ----------------------------------------------------------
  function render() {
    const c = $('#sch-canvas');
    c.style.gridTemplateColumns = 'repeat(' + layout.cols + ', var(--cell,40px))';
    c.classList.toggle('editing', mode === 'edit');
    c.innerHTML = '';
    const st = window.BB ? window.BB.state() : { turnouts: {}, sensors: {} };
    for (let r = 0; r < layout.rows; r++) {
      for (let col = 0; col < layout.cols; col++) {
        const key = col + ',' + r;
        const tile = layout.tiles[key];
        const cell = document.createElement('div');
        cell.className = 'cell';
        if (tile) {
          const thrown = isTurnout(tile.t) ? !!st.turnouts[tile.ref] : false;
          cell.innerHTML = tileSVG(tile.t, { thrown: thrown, ref: tile.ref });
          if (mode === 'view' && isBlock(tile.t) && st.sensors[tile.ref]) cell.classList.add('bezet');
          if (mode === 'view' && isTurnout(tile.t) && tile.ref != null) {
            cell.classList.add('clickable');
            cell.onclick = () => window.BB.send({ type: 'turnout', id: tile.ref, thrown: !thrown });
          }
        }
        if (mode === 'edit') {
          cell.classList.add('clickable');
          cell.onclick = () => editCell(key);
        }
        c.appendChild(cell);
      }
    }
  }

  function editCell(key) {
    if (palType === 'erase') { delete layout.tiles[key]; }
    else {
      const tile = { t: palType };
      if (isTurnout(palType) || isBlock(palType)) { if (palRef == null) { alert('Kies eerst een ' + (isTurnout(palType) ? 'wissel' : 'blok') + '-nummer rechtsboven.'); return; } tile.ref = palRef; }
      layout.tiles[key] = tile;
    }
    render();
  }

  // ---- opslaan / laden -------------------------------------------------
  async function loadLayout() {
    try { const r = await fetch('api/layout'); if (r.ok) layout = await r.json(); } catch (e) {}
    render();
  }
  async function save() {
    try {
      const r = await fetch('api/layout', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(layout) });
      const j = await r.json();
      $('#sch-save').textContent = j.ok ? '✓ Opgeslagen' : '✗ Mislukt';
      setTimeout(() => { $('#sch-save').textContent = '💾 Opslaan'; }, 1500);
    } catch (e) { $('#sch-save').textContent = '✗ Mislukt'; }
  }

  // ---- modus -----------------------------------------------------------
  function setMode(m) {
    mode = m;
    $('#sch-view').classList.toggle('on', m === 'view');
    $('#sch-edit').classList.toggle('on', m === 'edit');
    $('#sch-palette').hidden = (m !== 'edit');
    $('#sch-refrow').hidden = (m !== 'edit');
    $('#sch-save').hidden = (m !== 'edit');
    render();
  }
  $('#sch-view').onclick = () => setMode('view');
  $('#sch-edit').onclick = () => { renderPalette(); renderRefRow(); setMode('edit'); };
  $('#sch-save').onclick = save;

  // ---- zoom (cel-grootte via CSS-variabele, werkt voor beide weergaven) -
  function curCell() { return parseInt(getComputedStyle(document.documentElement).getPropertyValue('--cell')) || 40; }
  function setCell(px) {
    px = Math.max(10, Math.min(64, Math.round(px)));
    document.documentElement.style.setProperty('--cell', px + 'px');
    try { localStorage.setItem('bb-cell', String(px)); } catch (e) {}
  }
  (function initZoom() { let z; try { z = parseInt(localStorage.getItem('bb-cell'), 10); } catch (e) {} if (z) setCell(z); })();
  const zi = $('#zoom-in'), zo = $('#zoom-out'), zf = $('#zoom-fit');
  if (zi) zi.onclick = () => setCell(curCell() + 4);
  if (zo) zo.onclick = () => setCell(curCell() - 4);
  if (zf) zf.onclick = () => {
    const wrap = document.querySelector('#tab-schema .sch-canvas-wrap');
    if (!wrap || !wrap.clientWidth) return;
    setCell(Math.floor((wrap.clientWidth - 24) / Math.max(1, layout.cols)));
  };

  // ---- live spoorplan (read-only) voor de Baan-tab ---------------------
  function renderLive() {
    const c = $('#live-schema'); const wrap = $('#live-schema-wrap'); if (!c || !wrap) return;
    const hasLayout = Object.keys(layout.tiles || {}).length > 0;
    wrap.hidden = !hasLayout;
    if (!hasLayout) return;
    c.style.gridTemplateColumns = 'repeat(' + layout.cols + ', var(--cell,40px))';
    c.innerHTML = '';
    const st = window.BB ? window.BB.state() : { turnouts: {}, sensors: {} };
    for (let r = 0; r < layout.rows; r++) {
      for (let col = 0; col < layout.cols; col++) {
        const tile = layout.tiles[col + ',' + r];
        const cell = document.createElement('div'); cell.className = 'cell';
        if (tile) {
          const thrown = isTurnout(tile.t) ? !!st.turnouts[tile.ref] : false;
          cell.innerHTML = tileSVG(tile.t, { thrown: thrown, ref: tile.ref });
          if (isBlock(tile.t) && st.sensors && st.sensors[tile.ref]) cell.classList.add('bezet');
          if (isTurnout(tile.t) && tile.ref != null) { cell.classList.add('clickable'); cell.onclick = () => window.BB.send({ type: 'turnout', id: tile.ref, thrown: !thrown }); }
        }
        c.appendChild(cell);
      }
    }
  }
  window.BBSchema = { renderLive, reload: () => loadLayout().then(() => { render(); renderLive(); }) };

  // live status verversen
  if (window.BB) window.BB.onState((s, ros) => {
    if (ros && (ros.turnouts || ros.blocks)) roster = { turnouts: ros.turnouts || [], blocks: ros.blocks || [] };
    if (mode === 'view' && !$('#tab-schema').hidden) render();
    if (!$('#tab-baan').hidden) renderLive();
  });

  loadLayout().then(renderLive);
})();
