'use strict';
// Beheer-tab: loc's, wissels, blokken en rijwegen bewerken — zonder JSON.
// Werkt op een lokale kopie van het roster en POST't die naar /api/roster (Opslaan).
(function () {
  const $ = (s) => document.querySelector(s);
  const T = (k) => (window.t ? window.t(k) : k);
  let data = { locos: [], turnouts: [], blocks: [], routes: [] };
  let conf = null;
  const CENTRALS = [
    ['sim', 'Simulator (geen baan)'], ['dccex', 'DCC-EX (WiFi)'], ['z21', 'Roco/Fleischmann Z21 (LAN)'],
    ['dr5000', 'Digikeijs DR5000 (LAN)'], ['ecos', 'ESU ECoS (LAN)'], ['marklin', 'Märklin CS2/CS3 (LAN)'],
    ['twincenter', 'Fleischmann Twin Center (serieel)'], ['xpressnet', 'Lenz/multiMaus (serieel)'], ['loconet', 'Uhlenbrock/LoDi (serieel)'],
  ];
  const SERIAL = ['twincenter', 'xpressnet', 'loconet'];

  function input(val, ph, cls) {
    const i = document.createElement('input');
    i.value = (val === undefined || val === null) ? '' : val;
    if (ph) i.placeholder = ph;
    if (cls) i.className = cls;
    return i;
  }
  function delBtn(onDel) { const b = document.createElement('button'); b.className = 'mng-del'; b.textContent = '✕'; b.onclick = onDel; return b; }

  function section(titleKey, rowsFn, addFn) {
    const sec = document.createElement('div'); sec.className = 'mng-sec';
    const h = document.createElement('h2'); h.textContent = T(titleKey); sec.appendChild(h);
    rowsFn(sec);
    const add = document.createElement('button'); add.className = 'mng-add'; add.textContent = T('mng_add');
    add.onclick = () => { addFn(); render(); };
    sec.appendChild(add);
    return sec;
  }

  function renderConnSection(root) {
    const sec = document.createElement('div'); sec.className = 'mng-sec';
    const h = document.createElement('h2'); h.textContent = T('conn_title'); sec.appendChild(h);
    if (!conf) { const p = document.createElement('p'); p.className = 'muted small'; p.textContent = '…'; sec.appendChild(p); root.appendChild(sec); return; }

    const row1 = document.createElement('div'); row1.className = 'mng-row';
    const lbl = document.createElement('span'); lbl.className = 'muted small'; lbl.textContent = T('conn_central'); lbl.style.minWidth = '90px';
    const modeSel = document.createElement('select'); modeSel.className = 'grow';
    modeSel.style.cssText = 'background:var(--panel2);color:var(--ink);border:1px solid var(--line);border-radius:8px;padding:9px';
    CENTRALS.forEach(([v, label]) => { const o = new Option(label, v, false, conf.mode === v); modeSel.add(o); });
    row1.append(lbl, modeSel); sec.appendChild(row1);

    // netwerk: host  /  serieel: poort + baud
    const row2 = document.createElement('div'); row2.className = 'mng-row';
    const host = input(conf.host, T('conn_host'), 'grow');
    const sport = input(conf.serialPort, T('conn_serial'), 'grow');
    const baud = input(conf.baud, 'baud'); baud.type = 'number'; baud.style.maxWidth = '90px';
    function syncFields() {
      const serial = SERIAL.includes(modeSel.value);
      const net = !serial && modeSel.value !== 'sim';
      host.style.display = net ? '' : 'none';
      sport.style.display = serial ? '' : 'none';
      baud.style.display = serial ? '' : 'none';
    }
    modeSel.onchange = syncFields;
    row2.append(host, sport, baud); sec.appendChild(row2); syncFields();

    // Cloud-koppeling (relay): code om de baan van overal via p33k.nl/baanbrein/app te bedienen
    const row3 = document.createElement('div'); row3.className = 'mng-row';
    const rlbl = document.createElement('span'); rlbl.className = 'muted small'; rlbl.textContent = T('conn_relay'); rlbl.style.minWidth = '90px';
    const relay = input(conf.relayCode, T('conn_relay_ph'), 'grow');
    const gen = document.createElement('button'); gen.className = 'mng-del'; gen.style.cssText = 'background:var(--panel2);color:var(--accent);border-color:var(--line)'; gen.textContent = T('conn_relay_gen');
    gen.onclick = () => { const a = 'abcdefghjkmnpqrstuvwxyz23456789'; let c = ''; for (let i = 0; i < 10; i++) c += a[Math.floor(Math.random() * a.length)]; relay.value = c; };
    row3.append(rlbl, relay, gen); sec.appendChild(row3);
    const rhint = document.createElement('p'); rhint.className = 'muted small';
    rhint.innerHTML = conf.relayCode
      ? (T('conn_relay_on') + ' <a href="https://p33k.nl/baanbrein/app" target="_blank" rel="noopener">p33k.nl/baanbrein/app</a>')
      : T('conn_relay_off');
    sec.appendChild(rhint);

    const save = document.createElement('button'); save.className = 'mng-save'; save.style.marginTop = '4px'; save.textContent = T('conn_save');
    const msg = document.createElement('div'); msg.className = 'mng-saved';
    save.onclick = async () => {
      const rc = relay.value.trim();
      if (rc && rc.length < 6) { msg.className = 'mng-saved'; msg.style.color = 'var(--neg)'; msg.textContent = '✗ ' + T('conn_relay_short'); return; }
      msg.style.color = '';
      const payload = { mode: modeSel.value, host: host.value.trim(), serialPort: sport.value.trim(), baud: parseInt(baud.value, 10) || 19200, relayCode: rc };
      try {
        const r = await (await fetch('api/config', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) })).json();
        if (!r.ok) { msg.textContent = '✗'; return; }
        conf.relayCode = rc;
        msg.innerHTML = '✓ ' + (r.restartNeeded ? T('conn_saved_restart') : (rc ? T('conn_relay_live') : T('conn_saved')));
        setTimeout(() => { window.BBManage && window.BBManage.refresh(); }, 600);
      } catch (e) { msg.textContent = '✗'; }
    };
    sec.append(save, msg);
    const note = document.createElement('p'); note.className = 'muted small'; note.textContent = T('conn_active') + ': ' + (conf.active || '—') + (conf.connected ? ' ✓' : '');
    sec.appendChild(note);
    root.appendChild(sec);
  }

  function render() {
    const root = $('#beheer'); if (!root) return;
    root.innerHTML = '';

    renderConnSection(root);

    // LOC'S
    root.appendChild(section('mng_locos', (sec) => {
      data.locos.forEach((l, idx) => {
        const row = document.createElement('div'); row.className = 'mng-row';
        const addr = input(l.addr, T('mng_addr')); addr.type = 'number'; addr.style.maxWidth = '80px';
        addr.oninput = () => l.addr = parseInt(addr.value, 10) || 0;
        const name = input(l.name, T('mng_name'), 'grow'); name.oninput = () => l.name = name.value;
        const color = input(l.color || '#4c8bf5'); color.type = 'color'; color.className = 'w-color'; color.oninput = () => l.color = color.value;
        const funcs = input((l.functions || []).map((f) => f.fn + ':' + f.label).join(','), T('mng_funcs'), 'grow');
        funcs.oninput = () => l.functions = funcs.value.split(',').map((p) => p.trim()).filter(Boolean).map((p) => { const [fn, ...lbl] = p.split(':'); return { fn: parseInt(fn, 10) || 0, label: (lbl.join(':') || ('F' + fn)).trim(), momentary: false }; });
        const photo = input(l.photo, T('mng_photo'), 'grow'); photo.oninput = () => l.photo = photo.value.trim() || undefined;
        row.append(addr, name, color, funcs, photo, delBtn(() => { data.locos.splice(idx, 1); render(); }));
        sec.appendChild(row);
      });
    }, () => data.locos.push({ addr: 3, name: '', color: '#4c8bf5', functions: [{ fn: 0, label: 'Licht' }] })));

    // WISSELS
    root.appendChild(section('mng_turnouts', (sec) => {
      data.turnouts.forEach((t, idx) => {
        const row = document.createElement('div'); row.className = 'mng-row';
        const id = input(t.id, T('mng_id')); id.type = 'number'; id.style.maxWidth = '70px'; id.oninput = () => t.id = parseInt(id.value, 10) || 0;
        const name = input(t.name, T('mng_name'), 'grow'); name.oninput = () => t.name = name.value;
        row.append(id, name, delBtn(() => { data.turnouts.splice(idx, 1); render(); }));
        sec.appendChild(row);
      });
    }, () => data.turnouts.push({ id: (data.turnouts.length + 1), name: '' })));

    // BLOKKEN
    root.appendChild(section('mng_blocks', (sec) => {
      data.blocks.forEach((b, idx) => {
        const row = document.createElement('div'); row.className = 'mng-row';
        const id = input(b.id, T('mng_id')); id.type = 'number'; id.style.maxWidth = '70px'; id.oninput = () => b.id = parseInt(id.value, 10) || 0;
        const name = input(b.name, T('mng_name'), 'grow'); name.oninput = () => b.name = name.value;
        const sensor = input(b.sensor, T('mng_sensor')); sensor.type = 'number'; sensor.style.maxWidth = '90px'; sensor.oninput = () => b.sensor = parseInt(sensor.value, 10) || undefined;
        row.append(id, name, sensor, delBtn(() => { data.blocks.splice(idx, 1); render(); }));
        sec.appendChild(row);
      });
    }, () => data.blocks.push({ id: (data.blocks.length + 1), name: '' })));

    // RIJWEGEN
    root.appendChild(section('mng_routes', (sec) => {
      (data.routes = data.routes || []).forEach((r, idx) => {
        const row = document.createElement('div'); row.className = 'mng-row';
        const id = input(r.id, T('mng_id')); id.style.maxWidth = '70px'; id.oninput = () => r.id = id.value;
        const name = input(r.name, T('mng_name'), 'grow'); name.oninput = () => r.name = name.value;
        // wissels als "1:r,2:a"  (r=rechtdoor/false, a=afbuigend/true)
        const tn = input((r.turnouts || []).map((x) => x.id + ':' + (x.thrown ? 'a' : 'r')).join(','), T('mng_route_turnouts'), 'grow');
        tn.oninput = () => r.turnouts = tn.value.split(',').map((p) => p.trim()).filter(Boolean).map((p) => { const [id2, st] = p.split(':'); return { id: parseInt(id2, 10) || 0, thrown: /^(a|1|t)/i.test(st || '') }; });
        const bl = input((r.blocks || []).join(','), T('mng_route_blocks'));
        bl.oninput = () => r.blocks = bl.value.split(',').map((x) => parseInt(x.trim(), 10)).filter((n) => !isNaN(n));
        row.append(id, name, tn, bl, delBtn(() => { data.routes.splice(idx, 1); render(); }));
        sec.appendChild(row);
      });
    }, () => (data.routes = data.routes || []).push({ id: String((data.routes.length + 1)), name: '', turnouts: [], blocks: [] })));

    // RITTEN (automatisch)
    root.appendChild(section('mng_runs', (sec) => {
      (data.runs = data.runs || []).forEach((r, idx) => {
        const row = document.createElement('div'); row.className = 'mng-row';
        const id = input(r.id, T('mng_id')); id.style.maxWidth = '60px'; id.oninput = () => r.id = id.value;
        const name = input(r.name, T('mng_name'), 'grow'); name.oninput = () => r.name = name.value;
        const addr = input(r.addr, T('mng_run_loco')); addr.type = 'number'; addr.style.maxWidth = '80px'; addr.oninput = () => r.addr = parseInt(addr.value, 10) || 0;
        const loopL = document.createElement('label'); loopL.style.cssText = 'display:flex;align-items:center;gap:5px;font-size:13px;color:var(--muted)';
        const loop = document.createElement('input'); loop.type = 'checkbox'; loop.checked = !!r.loop; loop.style.minWidth = '18px'; loop.onchange = () => r.loop = loop.checked;
        loopL.append(loop, document.createTextNode(T('mng_run_loop')));
        // stappen als "route:speed:wait,route:speed:wait"
        const steps = input((r.steps || []).map((x) => x.route + ':' + (x.speed || 50) + ':' + (x.wait || 2)).join(','), T('mng_run_steps'), 'grow');
        steps.oninput = () => r.steps = steps.value.split(',').map((p) => p.trim()).filter(Boolean).map((p) => { const [route, sp, w] = p.split(':'); return { route: (route || '').trim(), speed: parseInt(sp, 10) || 50, wait: parseInt(w, 10) || 2 }; });
        row.append(id, name, addr, loopL, steps, delBtn(() => { data.runs.splice(idx, 1); render(); }));
        sec.appendChild(row);
      });
    }, () => (data.runs = data.runs || []).push({ id: String((data.runs.length + 1)), name: '', addr: 3, loop: true, steps: [] })));

    // TRACTIE (consists) — leden als "3,7r" (r = omgekeerd ingezet)
    root.appendChild(section('mng_consists', (sec) => {
      (data.consists = data.consists || []).forEach((cs, idx) => {
        const row = document.createElement('div'); row.className = 'mng-row';
        const id = input(cs.id, T('mng_id')); id.style.maxWidth = '60px'; id.oninput = () => cs.id = id.value;
        const name = input(cs.name, T('mng_name'), 'grow'); name.oninput = () => cs.name = name.value;
        const mem = input((cs.members || []).map((m) => m.addr + (m.reverse ? 'r' : '')).join(','), T('mng_consist_members'), 'grow');
        mem.oninput = () => cs.members = mem.value.split(',').map((p) => p.trim()).filter(Boolean).map((p) => ({ addr: parseInt(p, 10) || 0, reverse: /r$/i.test(p) }));
        row.append(id, name, mem, delBtn(() => { data.consists.splice(idx, 1); render(); }));
        sec.appendChild(row);
      });
    }, () => (data.consists = data.consists || []).push({ id: String((data.consists.length + 1)), name: '', color: '#f0b53a', members: [] })));

    // OPSLAAN
    const save = document.createElement('button'); save.className = 'mng-save'; save.textContent = T('mng_save');
    const msg = document.createElement('div'); msg.className = 'mng-saved';
    save.onclick = async () => {
      try {
        const r = await fetch('api/roster', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) });
        const j = await r.json();
        msg.textContent = j.ok ? T('saved') : '✗';
        setTimeout(() => { msg.textContent = ''; }, 1800);
      } catch (e) { msg.textContent = '✗'; }
    };
    root.append(save, msg);
  }

  // koppel aan het live roster uit app.js
  window.BBManage = {
    refresh() {
      if (window.BB) {
        const r = window.BB.roster();
        data = JSON.parse(JSON.stringify({ locos: r.locos || [], turnouts: r.turnouts || [], blocks: r.blocks || [], routes: r.routes || [], runs: r.runs || [], consists: r.consists || [] }));
        render();
      }
      fetch('api/config').then((r) => r.json()).then((c) => { conf = c; render(); }).catch(() => {});
    },
  };
  document.addEventListener('langchange', render);
  // eerste vulling zodra roster binnen is (app.js roept BBManage.refresh aan)
})();
