/**
 * @file    plc_debug.js
 * @brief   PLC 调试页 — 指示灯/按键绑定 out 信号 + 增量刷新
 */
var PlcDebugLeds = [];
var PlcDebugButtons = [];

Router.register('#plc_debug', function(c) { PlcDebugPage.render(c); });

var PlcDebugPage = (function() {
	var outSignals = [];
	var ledChecked = {}, btnChecked = {}, sigChecked = {};

	function getOut() {
		var out = SignalStore.get('out');
		return (Array.isArray(out) && out.length) ? out : outSignals;
	}

	function showPicker(cb) {
		var sigs = getOut();
		if (!sigs.length) { toast(I18n.t('plc_debug.no_sig'), 'error'); return; }
		var rows = '';
		sigs.forEach(function(s) {
			rows += '<div class="plc-pick-row" data-saddr="' + esc(s.saddr) + '" data-desc="' + esc(s.desc || '') + '">'
				+ '<strong>' + esc(s.saddr) + '</strong>'
				+ (s.desc ? ' <span style="color:var(--text-muted)">' + esc(s.desc) + '</span>' : '')
				+ '<span style="float:right;color:var(--accent);font-weight:700">' + fmtVal(s.val) + '</span></div>';
		});
		var ov = document.createElement('div');
		ov.className = 'modal-overlay';
		ov.innerHTML = '<div class="modal-box" style="max-width:550px"><h3>' + I18n.t('plc_debug.bind_title') + '</h3>'
			+ '<div style="max-height:300px;overflow-y:auto;margin:12px 0">' + rows + '</div>'
			+ '<button class="btn btn-sm" id="plc-pick-cancel">' + I18n.t('toast.cancel') + '</button></div>';
		document.body.appendChild(ov);
		document.getElementById('plc-pick-cancel').onclick = function() { ov.remove(); };
		ov.addEventListener('click', function(e) { if (e.target === ov) ov.remove(); });
		ov.querySelectorAll('.plc-pick-row').forEach(function(r) {
			r.onclick = function() {
				var sa = this.getAttribute('data-saddr'), de = this.getAttribute('data-desc');
				ov.remove();
				if (confirm(I18n.t('plc_debug.confirm_bind') + ' ' + sa + ' ?')) cb(sa, de);
			};
		});
	}

	function findSig(sa) {
		for (var i = 0; i < outSignals.length; i++) if (outSignals[i].saddr === sa) return outSignals[i];
		return null;
	}

	function refreshData() {
		var o = getOut(); if (Array.isArray(o)) outSignals = o;
		PlcDebugLeds.forEach(function(l) { var f = findSig(l.saddr); l.val = f ? f.val : 0; });
		PlcDebugButtons.forEach(function(b) { var f = findSig(b.saddr); b.val = f ? f.val : 0; });
	}

	function incrRefresh() {
		refreshData();
		PlcDebugLeds.forEach(function(l, i) {
			var on = parseFloat(l.val) > 0;
			var ve = document.getElementById('led-val-' + i), ie = document.getElementById('led-icon-' + i);
			if (ve) { ve.textContent = '(' + l.val + ')'; ve.style.color = on ? 'var(--accent)' : 'var(--text-muted)'; }
			if (ie) ie.className = 'plc-led' + (on ? ' plc-led-on' : '');
		});
		PlcDebugButtons.forEach(function(b, j) {
			var ve = document.getElementById('btn-val-' + j);
			if (ve) { ve.textContent = '(' + b.val + ')'; ve.style.color = parseFloat(b.val) > 0 ? 'var(--accent)' : 'var(--text-muted)'; }
		});
	}

	function countChecked(obj) { var n = 0; for (var k in obj) if (obj.hasOwnProperty(k)) n++; return n; }

	function delChecked() {
		var todel = [];
		for (var k in ledChecked) if (ledChecked.hasOwnProperty(k)) todel.push({ type: 'led', idx: parseInt(k) });
		for (var k in btnChecked) if (btnChecked.hasOwnProperty(k)) todel.push({ type: 'btn', idx: parseInt(k) });
		if (!todel.length) { toast(I18n.t('toast.no_selected'), 'error'); return; }
		if (!confirm(I18n.t('plc_debug.confirm_del') + ' ' + todel.length + ' ?')) return;
		todel.sort(function(a, b) { return b.idx - a.idx; }).forEach(function(t) {
			if (t.type === 'led') PlcDebugLeds.splice(t.idx, 1);
			else PlcDebugButtons.splice(t.idx, 1);
		});
		ledChecked = {}; btnChecked = {};
		renderAll();
	}

	function renderAll() {
		var c = document.getElementById('plc-content');
		if (!c) return;
		refreshData();

		/* 指示灯列 */
		var ledHtml = '';
		if (!PlcDebugLeds.length) {
			ledHtml = '<div style="color:var(--text-muted);padding:20px;text-align:center">' + I18n.t('plc_debug.no_led') + '</div>';
		} else {
			PlcDebugLeds.forEach(function(l, i) {
				var on = parseFloat(l.val) > 0, chk = !!ledChecked[i];
				ledHtml += '<div class="plc-item">'
					+ '<div class="plc-led' + (on ? ' plc-led-on' : '') + '" id="led-icon-' + i + '" onclick="PlcDebugPage._bindLed(' + i + ')" title="' + I18n.t('plc_debug.click_to_bind') + '"></div>'
					+ '<div class="plc-info">'
					+ (l.saddr ? '<span class="plc-saddr">' + esc(l.saddr) + ' <span id="led-val-' + i + '" style="color:' + (on ? 'var(--accent)' : 'var(--text-muted)') + '">(' + fmtVal(l.val) + ')</span></span>'
						+ (l.desc ? '<span style="color:var(--text-muted);font-size:11px">' + esc(l.desc) + '</span>' : '')
						: '<span style="color:var(--text-muted)">' + I18n.t('plc_debug.unbound') + '</span>')
					+ '</div>'
					+ '<input type="checkbox" ' + (chk ? 'checked' : '') + ' onchange="PlcDebugPage._toggleLed(' + i + ',this.checked)">'
					+ '</div>';
			});
		}

		/* 按键列 */
		var btnHtml = '';
		if (!PlcDebugButtons.length) {
			btnHtml = '<div style="color:var(--text-muted);padding:20px;text-align:center">' + I18n.t('plc_debug.no_btn') + '</div>';
		} else {
			PlcDebugButtons.forEach(function(b, j) {
				var chk = !!btnChecked[j];
				btnHtml += '<div class="plc-item">'
					+ '<button class="plc-btn-icon" id="btn-icon-' + j + '" onclick="PlcDebugPage._toggleBtn(' + j + ')" title="' + I18n.t('plc_debug.toggle') + '">🔘</button>'
					+ '<div class="plc-info">'
					+ (b.saddr ? '<span class="plc-saddr">' + esc(b.saddr) + ' <span id="btn-val-' + j + '" style="color:var(--text-muted)">(' + fmtVal(b.val) + ')</span></span>'
						+ (b.desc ? '<span style="color:var(--text-muted);font-size:11px">' + esc(b.desc) + '</span>' : '')
						: '<span style="color:var(--text-muted)">' + I18n.t('plc_debug.unbound') + '</span>')
					+ '</div>'
					+ '<input type="checkbox" ' + (chk ? 'checked' : '') + ' onchange="PlcDebugPage._toggleBtnChk(' + j + ',this.checked)">'
					+ '</div>';
			});
		}

		/* 信号列 */
		var o = getOut();
		var sigHtml = '';
		if (!o.length) {
			sigHtml = '<div style="color:var(--text-muted);padding:20px;text-align:center">' + I18n.t('plc_debug.no_sig') + '</div>';
		} else {
			o.forEach(function(s, i) {
				var chk = !!sigChecked[i];
				sigHtml += '<div class="plc-item">'
					+ '<input type="checkbox" ' + (chk ? 'checked' : '') + ' onchange="PlcDebugPage._toggleSig(' + i + ',this.checked)">'
					+ '<span class="plc-saddr">' + esc(s.saddr) + '</span>'
					+ '<span style="color:var(--text-muted);font-size:11px">' + esc(s.desc || '') + '</span>'
					+ '<span style="margin-left:auto;color:var(--accent);font-weight:700;font-family:var(--font-mono)">' + fmtVal(s.val) + '</span>'
					+ '</div>';
			});
		}

		c.innerHTML = '<div class="plc-debug-grid">'
			+ '<div class="plc-col"><div class="card-header" style="margin-bottom:8px"><span>💡 ' + I18n.t('plc_debug.led_col') + '</span>'
			+ '<div class="btn-group">'
			+ '<button class="btn btn-sm" onclick="PlcDebugPage._addLed()">' + I18n.t('plc_debug.add_led') + '</button>'
			+ '</div></div><div class="plc-sig-list">' + ledHtml + '</div></div>'
			+ '<div class="plc-col plc-sig-col"><div class="card-header" style="margin-bottom:8px"><span>📋 ' + I18n.t('plc_debug.sig_col') + '</span>'
			+ '<div class="plc-arrow-row">'
			+ '<button class="btn btn-sm" onclick="PlcDebugPage._moveSel(\'led\')" title="' + I18n.t('plc_debug.to_led') + '">← LED</button>'
			+ '<button class="btn btn-sm" onclick="PlcDebugPage._moveSel(\'btn\')" title="' + I18n.t('plc_debug.to_btn') + '">→ BTN</button>'
			+ '</div></div><div class="plc-sig-list">' + sigHtml + '</div></div>'
			+ '<div class="plc-col"><div class="card-header" style="margin-bottom:8px"><span>🔘 ' + I18n.t('plc_debug.btn_col') + '</span>'
			+ '<div class="btn-group">'
			+ '<button class="btn btn-sm" onclick="PlcDebugPage._addBtn()">' + I18n.t('plc_debug.add_btn') + '</button>'
			+ '</div></div><div class="plc-sig-list">' + btnHtml + '</div></div>'
			+ '</div>';

		updateDelBtn();
	}

	function updateDelBtn() {
		var el = document.getElementById('plc-del-btn');
		if (!el) return;
		var n = countChecked(ledChecked) + countChecked(btnChecked);
		el.textContent = I18n.t('plc_debug.del_sel') + (n ? ' (' + n + ')' : '');
		el.disabled = !n;
	}

	return {
		render: function(c) {
			ledChecked = {}; btnChecked = {}; sigChecked = {};
			refreshData();
			c.innerHTML = '<div class="card">'
				+ '<div class="card-header"><span>' + I18n.t('plc_debug.title') + '</span>'
				+ '<div class="btn-group">'
				+ '<button class="btn btn-sm" onclick="PlcDebugPage._refresh()">🔄 ' + I18n.t('plc_debug.refresh_btn') + '</button>'
				+ '<button class="btn btn-danger btn-sm" id="plc-del-btn" disabled onclick="PlcDebugPage._delChecked()">🗑 ' + I18n.t('plc_debug.del_sel') + '</button>'
				+ '</div></div>'
				+ '<div id="plc-content"></div></div>';
			renderAll();
		},
		_addLed: function() { PlcDebugLeds.push({ saddr: '', desc: '', val: 0 }); renderAll(); },
		_addBtn: function() { PlcDebugButtons.push({ saddr: '', desc: '', val: 0 }); renderAll(); },
		_bindLed: function(i) { showPicker(function(sa, de) { PlcDebugLeds[i].saddr = sa; PlcDebugLeds[i].desc = de; var f = findSig(sa); if (f) PlcDebugLeds[i].val = f.val; renderAll(); }); },
		_toggleBtn: function(j) {
			var b = PlcDebugButtons[j];
			if (!b.saddr) { showPicker(function(sa, de) { b.saddr = sa; b.desc = de; var f = findSig(sa); if (f) b.val = f.val; renderAll(); }); return; }
			var nv = parseFloat(b.val) > 0 ? 0 : 1;
			WsClient.send({ curd: 'set', signal_type: 'out', saddr: b.saddr, signal_data: String(nv), setting_zone: '0' });
			b.val = nv; renderAll();
		},
		_toggleLed: function(i, v) { ledChecked[i] = v; updateDelBtn(); },
		_toggleBtnChk: function(j, v) { btnChecked[j] = v; updateDelBtn(); },
		_toggleSig: function(i, v) { sigChecked[i] = v; },
		_moveSel: function(target) {
			var picked = [];
			for (var k in sigChecked) if (sigChecked.hasOwnProperty(k)) picked.push(parseInt(k));
			if (!picked.length) { toast(I18n.t('toast.no_selected'), 'error'); return; }
			picked.sort(function(a, b) { return a - b; }).forEach(function(i) {
				var s = outSignals[i];
				if (!s) return;
				if (target === 'led') PlcDebugLeds.push({ saddr: s.saddr, desc: s.desc || '', val: s.val || 0 });
				else PlcDebugButtons.push({ saddr: s.saddr, desc: s.desc || '', val: s.val || 0 });
			});
			sigChecked = {}; renderAll();
		},
		_refresh: function() { refreshData(); incrRefresh(); },
		_delChecked: delChecked,
	};
})();
