{{define "workflow.html"}}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{.Data.ChannelTitle}} — {{.InstanceName}}</title>
    <link rel="icon" type="image/svg+xml" href="{{.BasePath}}/favicon.svg?v={{.Version}}">
    <link rel="icon" type="image/x-icon" href="{{.BasePath}}/favicon.ico?v={{.Version}}">
    <link rel="stylesheet" href="{{.BasePath}}/css/variables.css?v={{.Version}}">
    <link rel="stylesheet" href="{{.BasePath}}/css/primitives.css?v={{.Version}}">
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: var(--font); background: var(--bg); color: var(--text); }

        .wf-shell { display: flex; flex-direction: column; height: 100vh; }

        .wf-header {
            padding: 16px 24px;
            border-bottom: 1px solid var(--border);
            background: var(--bg-surface);
        }
        .wf-header h1 { font-size: 18px; font-weight: 600; }
        .wf-header p { font-size: 13px; color: var(--text-2); margin-top: 4px; }

        .wf-stage-info {
            padding: 8px 24px; font-size: 12px; color: var(--text-2);
            background: var(--bg-surface); border-bottom: 1px solid var(--border);
            display: flex; justify-content: space-between; align-items: center;
        }
        .wf-progress {
            display: flex; gap: 4px;
        }
        .wf-progress-dot {
            width: 8px; height: 8px; border-radius: 50%;
            background: var(--border);
        }
        .wf-progress-dot.active { background: var(--accent); }
        .wf-progress-dot.done { background: var(--text-3); }

        /* ── Form ───────────────────────── */
        .wf-form {
            flex: 1; overflow-y: auto; padding: 24px;
            max-width: 640px; margin: 0 auto; width: 100%;
        }
        .wf-form-field { margin-bottom: 16px; }
        .wf-form-field label {
            display: block; font-size: 13px; font-weight: 600;
            margin-bottom: 4px; color: var(--text);
        }
        .wf-form-field label .required { color: var(--danger, #e74c3c); margin-left: 2px; }
        .wf-form-field input, .wf-form-field select, .wf-form-field textarea {
            width: 100%; padding: 8px 12px; font-size: 14px;
            background: var(--input-bg); color: var(--text);
            border: 1px solid var(--border); border-radius: 6px;
            font-family: var(--font);
        }
        .wf-form-field input:focus, .wf-form-field select:focus, .wf-form-field textarea:focus {
            outline: none; border-color: var(--accent);
        }
        .wf-form-field textarea { resize: vertical; min-height: 80px; }
        .wf-form-field .field-error {
            font-size: 12px; color: var(--danger, #e74c3c); margin-top: 4px;
        }
        .wf-form-field.has-error input,
        .wf-form-field.has-error select,
        .wf-form-field.has-error textarea {
            border-color: var(--danger, #e74c3c);
        }
        .wf-form-field .field-hint {
            font-size: 12px; color: var(--text-3); margin-top: 2px;
        }
        .wf-form-check {
            display: flex; align-items: center; gap: 8px;
        }
        .wf-form-check input[type="checkbox"] {
            width: auto; margin: 0;
        }

        .wf-form-submit {
            margin-top: 24px;
        }
        .wf-form-submit button {
            background: var(--accent); color: #fff; border: none; border-radius: 8px;
            padding: 10px 24px; font-weight: 600; cursor: pointer; font-size: 14px;
        }
        .wf-form-submit button:hover { background: var(--accent-hover); }
        .wf-form-submit button:disabled { opacity: 0.5; cursor: default; }

        .wf-form-success {
            text-align: center; padding: 40px 24px;
        }
        .wf-form-success h3 { font-size: 18px; margin-bottom: 8px; }
        .wf-form-success p { color: var(--text-2); }

        /* ── Chat ───────────────────────── */
        .wf-chat {
            flex: 1; overflow-y: auto; padding: 16px 24px;
        }
        .wf-chat .message {
            margin-bottom: 12px; padding: 10px 14px;
            border-radius: 8px; max-width: 80%;
        }
        .wf-chat .message.user { background: var(--accent-dim); margin-left: auto; }
        .wf-chat .message.assistant { background: var(--bg-raised); }
        .wf-chat .message .meta { font-size: 11px; color: var(--text-3); margin-bottom: 4px; }
        .wf-chat .message .content { font-size: 14px; line-height: 1.5; white-space: pre-wrap; }

        .wf-input {
            padding: 12px 24px; border-top: 1px solid var(--border);
            background: var(--bg-surface); display: flex; gap: 8px;
        }
        .wf-input textarea {
            flex: 1; resize: none; background: var(--input-bg); color: var(--text);
            border: 1px solid var(--border); border-radius: 8px; padding: 10px 14px;
            font-family: var(--font); font-size: 14px; min-height: 42px; max-height: 160px;
        }
        .wf-input textarea:focus { outline: none; border-color: var(--accent); }
        .wf-input button {
            background: var(--accent); color: #fff; border: none; border-radius: 8px;
            padding: 0 20px; font-weight: 600; cursor: pointer; font-size: 14px;
        }
        .wf-input button:hover { background: var(--accent-hover); }
        .wf-input button:disabled { opacity: 0.5; cursor: default; }

        .wf-session-info {
            padding: 8px 24px; font-size: 12px; color: var(--text-3);
            border-top: 1px solid var(--border); background: var(--bg);
        }

        /* ── Form+Chat layout ───────────── */
        .wf-body-split { display: flex; flex: 1; overflow: hidden; }
        .wf-body-split .wf-form { flex: 1; border-right: 1px solid var(--border); overflow-y: auto; }
        .wf-body-split .wf-chat-col { flex: 1; display: flex; flex-direction: column; }
        .wf-body-split .wf-chat { flex: 1; }

        /* ── Branding (v0.35.0) ────────── */
        .wf-branding-logo { max-height: 32px; margin-bottom: 4px; }
        .wf-branding-tagline { font-size: 13px; color: var(--text-2); margin-top: 2px; }

        /* ── Progressive Forms (v0.35.0) ── */
        .wf-fieldset-nav {
            display: flex; justify-content: space-between; align-items: center;
            margin-bottom: 16px; padding-bottom: 12px;
            border-bottom: 1px solid var(--border);
        }
        .wf-fieldset-nav .step-label { font-size: 14px; font-weight: 600; }
        .wf-fieldset-nav .step-counter { font-size: 12px; color: var(--text-3); }
        .wf-fieldset-buttons { display: flex; gap: 8px; margin-top: 16px; }
        .wf-fieldset-buttons button {
            padding: 8px 20px; border-radius: 8px; font-size: 14px; cursor: pointer;
            font-weight: 600; border: 1px solid var(--border);
            background: var(--bg-surface); color: var(--text);
        }
        .wf-fieldset-buttons button.primary {
            background: var(--accent); color: #fff; border-color: var(--accent);
        }
        .wf-fieldset-buttons button.primary:hover { background: var(--accent-hover); }

        /* ── Conditional field (hidden) ── */
        .wf-form-field.cond-hidden { display: none; }
    </style>
    <script>
        (function() {
            try {
                var p = JSON.parse(localStorage.getItem('sb-appearance') || '{}');
                var mode = p.theme || 'system';
                var resolved = mode;
                if (mode === 'system') resolved = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
                document.documentElement.setAttribute('data-theme', resolved);
            } catch(e) {}
        })();
    </script>
</head>
<body>
<div class="wf-shell">
    <div class="wf-header" id="wfHeader">
        <h1>{{.Data.ChannelTitle}}</h1>
        {{if .Data.ChannelDescription}}<p>{{.Data.ChannelDescription}}</p>{{end}}
    </div>

    {{if .Data.StageName}}
    <div class="wf-stage-info">
        <span>{{.Data.StageName}}</span>
        {{if gt .Data.TotalStages 1}}
        <div class="wf-progress" id="progressDots"></div>
        {{end}}
    </div>
    {{end}}

    <!-- Stage surface mount point (v0.30.2) -->
    <!-- Modes: form_only, form_chat, chat_only, review, or custom surface via SurfacePkgID -->

    {{if .Data.SurfacePkgID}}
    <div id="customSurfaceMount" style="flex:1;overflow-y:auto"></div>
    {{else if eq .Data.StageMode "form_only"}}
    <div class="wf-form" id="formArea"></div>
    {{else if eq .Data.StageMode "form_chat"}}
    <div class="wf-body-split">
        <div class="wf-form" id="formArea"></div>
        <div class="wf-chat-col">
            <div class="wf-chat" id="chatMessages"></div>
            <div class="wf-input">
                <textarea id="chatInput" placeholder="Type a message…" rows="1"
                          onkeydown="if(event.key==='Enter'&&!event.shiftKey){event.preventDefault();sendMessage()}"></textarea>
                <button id="sendBtn" onclick="sendMessage()">Send</button>
            </div>
        </div>
    </div>
    {{else if eq .Data.StageMode "review"}}
    <div id="reviewArea" style="flex:1;overflow-y:auto;display:flex">
        <div id="reviewDataPanel" style="flex:1;overflow-y:auto;border-right:1px solid var(--border)"></div>
        <div id="reviewActionPanel" style="flex:1;overflow-y:auto;display:flex;flex-direction:column"></div>
    </div>
    {{else}}
    <div class="wf-chat" id="chatMessages"></div>
    <div class="wf-input">
        <textarea id="chatInput" placeholder="Type a message…" rows="1"
                  onkeydown="if(event.key==='Enter'&&!event.shiftKey){event.preventDefault();sendMessage()}"></textarea>
        <button id="sendBtn" onclick="sendMessage()">Send</button>
    </div>
    {{end}}

    <div class="wf-session-info">
        {{if .Data.SurfacePkgID}}Session:{{else if eq .Data.StageMode "form_only"}}Submitting as{{else if eq .Data.StageMode "review"}}Reviewing as{{else}}Chatting as{{end}} <strong>{{.Data.SessionName}}</strong>
    </div>
</div>

<script>
(function() {
    const BASE       = '{{.BasePath}}';
    const CHAN_ID     = '{{.Data.ChannelID}}';
    const SESSION_ID = '{{.Data.SessionID}}';
    const STAGE_MODE = '{{.Data.StageMode}}';
    const TOTAL_STAGES = {{.Data.TotalStages}};
    const CURRENT_STAGE = {{.Data.CurrentStage}};
    const SURFACE_PKG_ID = '{{.Data.SurfacePkgID}}';

    var FORM_TPL = null;
    try { FORM_TPL = JSON.parse('{{.Data.FormTemplateJSON}}' || 'null'); } catch(e) {}

    // v0.35.0: Branding
    var BRANDING = null;
    try { BRANDING = JSON.parse('{{.Data.BrandingJSON}}' || 'null'); } catch(e) {}

    // v0.35.0: Apply branding
    (function() {
        if (!BRANDING) return;
        var header = document.getElementById('wfHeader');
        if (!header) return;
        if (BRANDING.accent_color) {
            document.documentElement.style.setProperty('--accent', BRANDING.accent_color);
        }
        if (BRANDING.logo_url) {
            var img = document.createElement('img');
            img.src = BRANDING.logo_url;
            img.className = 'wf-branding-logo';
            img.alt = '';
            header.insertBefore(img, header.firstChild);
        }
        if (BRANDING.tagline) {
            var tag = document.createElement('div');
            tag.className = 'wf-branding-tagline';
            tag.textContent = BRANDING.tagline;
            header.appendChild(tag);
        }
    })();

    // ── Progress dots ──────────────────
    (function() {
        var dotsEl = document.getElementById('progressDots');
        if (!dotsEl || TOTAL_STAGES <= 1) return;
        for (var i = 0; i < TOTAL_STAGES; i++) {
            var dot = document.createElement('div');
            dot.className = 'wf-progress-dot';
            if (i < CURRENT_STAGE) dot.className += ' done';
            if (i === CURRENT_STAGE) dot.className += ' active';
            dotsEl.appendChild(dot);
        }
    })();

    // ── Form rendering (v0.35.0: progressive forms + conditional fields) ──
    var _fieldsetIndex = 0;
    var _fieldsetCount = 0;

    if ((STAGE_MODE === 'form_only' || STAGE_MODE === 'form_chat') && FORM_TPL) {
        var formArea = document.getElementById('formArea');
        if (FORM_TPL.fieldsets && FORM_TPL.fieldsets.length > 0) {
            renderProgressiveForm(formArea, FORM_TPL);
        } else if (FORM_TPL.fields && FORM_TPL.fields.length > 0) {
            renderForm(formArea, FORM_TPL);
        }
    }

    function renderForm(container, tpl) {
        var html = '';
        for (var i = 0; i < tpl.fields.length; i++) {
            var f = tpl.fields[i];
            html += renderField(f);
        }
        html += '<div class="wf-form-submit"><button id="formSubmitBtn" onclick="submitForm()">Submit</button></div>';
        container.innerHTML = html;
        applyConditionalFields(tpl.fields);
    }

    function renderProgressiveForm(container, tpl) {
        _fieldsetCount = tpl.fieldsets.length;
        _fieldsetIndex = 0;
        var html = '';
        for (var s = 0; s < tpl.fieldsets.length; s++) {
            var fs = tpl.fieldsets[s];
            var display = s === 0 ? '' : ' style="display:none"';
            html += '<div class="wf-fieldset" id="fieldset_' + s + '"' + display + '>';
            html += '<div class="wf-fieldset-nav"><span class="step-label">' + escHtml(fs.label) + '</span>';
            html += '<span class="step-counter">Step ' + (s + 1) + ' of ' + _fieldsetCount + '</span></div>';
            for (var i = 0; i < fs.fields.length; i++) {
                html += renderField(fs.fields[i]);
            }
            html += '<div class="wf-fieldset-buttons">';
            if (s > 0) html += '<button onclick="showFieldset(' + (s - 1) + ')">Back</button>';
            if (s < tpl.fieldsets.length - 1) {
                html += '<button class="primary" onclick="showFieldset(' + (s + 1) + ')">Next</button>';
            } else {
                html += '<button class="primary" id="formSubmitBtn" onclick="submitForm()">Submit</button>';
            }
            html += '</div></div>';
        }
        container.innerHTML = html;
        // Apply conditional fields for all fieldsets
        for (var s = 0; s < tpl.fieldsets.length; s++) {
            applyConditionalFields(tpl.fieldsets[s].fields);
        }
    }

    window.showFieldset = function(idx) {
        if (idx < 0 || idx >= _fieldsetCount) return;
        document.getElementById('fieldset_' + _fieldsetIndex).style.display = 'none';
        document.getElementById('fieldset_' + idx).style.display = '';
        _fieldsetIndex = idx;
    };

    function applyConditionalFields(fields) {
        for (var i = 0; i < fields.length; i++) {
            var f = fields[i];
            if (!f.condition) continue;
            var when = f.condition.when;
            var srcEl = document.getElementById('ff_' + when);
            if (!srcEl) continue;
            (function(field) {
                var handler = function() { evaluateCondition(field); };
                srcEl.addEventListener('change', handler);
                srcEl.addEventListener('input', handler);
                handler(); // initial evaluation
            })(f);
        }
    }

    function evaluateCondition(f) {
        var cond = f.condition;
        var srcEl = document.getElementById('ff_' + cond.when);
        var tgtEl = document.querySelector('.wf-form-field[data-key="' + f.key + '"]');
        if (!srcEl || !tgtEl) return;

        var val = srcEl.type === 'checkbox' ? srcEl.checked : srcEl.value;
        var op = cond.op || 'eq';
        var visible = false;

        switch (op) {
            case 'exists': visible = val !== '' && val !== false; break;
            case 'eq': visible = String(val) === String(cond.value); break;
            case 'neq': visible = String(val) !== String(cond.value); break;
            case 'in': visible = Array.isArray(cond.value) && cond.value.map(String).indexOf(String(val)) >= 0; break;
            default: visible = true;
        }

        if (visible) {
            tgtEl.classList.remove('cond-hidden');
        } else {
            tgtEl.classList.add('cond-hidden');
        }
    }

    function renderField(f) {
        var req = f.required ? '<span class="required">*</span>' : '';
        var ph = f.placeholder ? ' placeholder="' + escAttr(f.placeholder) + '"' : '';
        var inner = '';

        switch (f.type) {
            case 'text':
            case 'email':
            case 'date':
                inner = '<input type="' + f.type + '" id="ff_' + f.key + '"' + ph + '>';
                break;
            case 'number':
                var attrs = ph;
                if (f.validation) {
                    if (f.validation.min != null) attrs += ' min="' + f.validation.min + '"';
                    if (f.validation.max != null) attrs += ' max="' + f.validation.max + '"';
                    if (f.validation.step != null) attrs += ' step="' + f.validation.step + '"';
                }
                inner = '<input type="number" id="ff_' + f.key + '"' + attrs + '>';
                break;
            case 'textarea':
                inner = '<textarea id="ff_' + f.key + '"' + ph + ' rows="4"></textarea>';
                break;
            case 'select':
                var opts = '<option value="">— Select —</option>';
                if (f.options) {
                    for (var j = 0; j < f.options.length; j++) {
                        opts += '<option value="' + escAttr(f.options[j].value) + '">' + escHtml(f.options[j].label) + '</option>';
                    }
                }
                inner = '<select id="ff_' + f.key + '">' + opts + '</select>';
                break;
            case 'checkbox':
                return '<div class="wf-form-field" data-key="' + f.key + '">' +
                    '<div class="wf-form-check">' +
                    '<input type="checkbox" id="ff_' + f.key + '">' +
                    '<label for="ff_' + f.key + '">' + escHtml(f.label) + req + '</label>' +
                    '</div>' +
                    '<div class="field-error" id="err_' + f.key + '"></div>' +
                    '</div>';
            case 'file':
                var accept = (f.validation && f.validation.accept) ? ' accept="' + escAttr(f.validation.accept) + '"' : '';
                inner = '<input type="file" id="ff_' + f.key + '"' + accept + '>';
                break;
            default:
                inner = '<input type="text" id="ff_' + f.key + '"' + ph + '>';
        }

        return '<div class="wf-form-field" data-key="' + f.key + '">' +
            '<label for="ff_' + f.key + '">' + escHtml(f.label) + req + '</label>' +
            inner +
            '<div class="field-error" id="err_' + f.key + '"></div>' +
            '</div>';
    }

    window.submitForm = async function() {
        if (!FORM_TPL || !FORM_TPL.fields) return;
        var btn = document.getElementById('formSubmitBtn');
        if (btn) btn.disabled = true;

        // Clear previous errors
        document.querySelectorAll('.wf-form-field').forEach(function(el) {
            el.classList.remove('has-error');
        });
        document.querySelectorAll('.field-error').forEach(function(el) {
            el.textContent = '';
        });

        // Collect form data (v0.35.0: get all fields from fieldsets or top-level)
        var allFields = FORM_TPL.fields || [];
        if (FORM_TPL.fieldsets && FORM_TPL.fieldsets.length > 0) {
            allFields = [];
            for (var s = 0; s < FORM_TPL.fieldsets.length; s++) {
                allFields = allFields.concat(FORM_TPL.fieldsets[s].fields);
            }
        }
        var data = {};
        for (var i = 0; i < allFields.length; i++) {
            var f = allFields[i];
            var el = document.getElementById('ff_' + f.key);
            if (!el) continue;
            // v0.35.0: Skip hidden conditional fields
            var fieldWrap = document.querySelector('.wf-form-field[data-key="' + f.key + '"]');
            if (fieldWrap && fieldWrap.classList.contains('cond-hidden')) continue;
            if (f.type === 'checkbox') {
                data[f.key] = el.checked;
            } else if (f.type === 'number') {
                data[f.key] = el.value !== '' ? parseFloat(el.value) : null;
            } else {
                data[f.key] = el.value;
            }
        }

        try {
            var resp = await fetch(BASE + '/api/v1/w/' + CHAN_ID + '/form-submit', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ data: data }),
            });
            var result = await resp.json();
            if (!resp.ok) {
                if (result.errors) {
                    showErrors(result.errors);
                } else if (result.error) {
                    alert(result.error);
                }
                if (btn) btn.disabled = false;
                return;
            }

            // Success
            if (result.status === 'advanced' || result.status === 'completed') {
                showFormSuccess(result.status === 'completed'
                    ? 'Thank you! Your submission is complete.'
                    : 'Submitted! Moving to the next step...');
                if (result.status === 'advanced') {
                    setTimeout(function() { window.location.reload(); }, 1500);
                }
            } else {
                showFormSuccess('Your response has been submitted.');
            }
        } catch(e) {
            alert('Network error: ' + e.message);
            if (btn) btn.disabled = false;
        }
    };

    function showErrors(errors) {
        for (var i = 0; i < errors.length; i++) {
            var e = errors[i];
            var errEl = document.getElementById('err_' + e.key);
            if (errEl) errEl.textContent = e.message;
            var fieldEl = document.querySelector('.wf-form-field[data-key="' + e.key + '"]');
            if (fieldEl) fieldEl.classList.add('has-error');
        }
    }

    function showFormSuccess(msg) {
        var formArea = document.getElementById('formArea');
        if (formArea) {
            formArea.innerHTML = '<div class="wf-form-success"><h3>Submitted</h3><p>' + escHtml(msg) + '</p></div>';
        }
    }

    // ── Chat ───────────────────────────
    var chatEl = document.getElementById('chatMessages');
    var inputEl = document.getElementById('chatInput');
    var sendBtn = document.getElementById('sendBtn');
    var sending = false;

    function addMessage(role, content, name) {
        if (!chatEl) return;
        var div = document.createElement('div');
        div.className = 'message ' + role;
        var meta = name ? '<div class="meta">' + escHtml(name) + '</div>' : '';
        div.innerHTML = meta + '<div class="content">' + escHtml(content) + '</div>';
        chatEl.appendChild(div);
        chatEl.scrollTop = chatEl.scrollHeight;
    }

    function escHtml(s) {
        var d = document.createElement('div');
        d.textContent = s;
        return d.innerHTML;
    }

    function escAttr(s) {
        return String(s).replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
    }

    window.sendMessage = async function() {
        if (!inputEl || !sendBtn) return;
        var text = inputEl.value.trim();
        if (!text || sending) return;
        sending = true;
        sendBtn.disabled = true;
        inputEl.value = '';

        addMessage('user', text, '{{.Data.SessionName}}');

        try {
            var resp = await fetch(BASE + '/api/v1/w/' + CHAN_ID + '/completions', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ channel_id: CHAN_ID, content: text, stream: false }),
            });
            if (resp.ok) {
                var data = await resp.json();
                if (data.content) {
                    addMessage('assistant', data.content, data.persona_name || 'Assistant');
                }
            } else {
                var err = await resp.json().catch(function() { return {}; });
                addMessage('assistant', 'Error: ' + (err.error || resp.statusText));
            }
        } catch(e) {
            addMessage('assistant', 'Network error: ' + e.message);
        }

        sending = false;
        sendBtn.disabled = false;
        inputEl.focus();
    };

    // Auto-resize textarea
    if (inputEl) {
        inputEl.addEventListener('input', function() {
            this.style.height = 'auto';
            this.style.height = Math.min(this.scrollHeight, 160) + 'px';
        });
    }

    // ── Custom surface (v0.37.14: legacy registry removed) ──────────
    if (SURFACE_PKG_ID) {
        var mount = document.getElementById('customSurfaceMount');
        if (mount) {
            mount.innerHTML = '<div style="padding:24px;color:var(--danger)">Custom workflow surfaces require an updated package format. The legacy surface registry has been removed.</div>';
        }
    }

    function loadScript(src) {
        return new Promise(function(resolve, reject) {
            var s = document.createElement('script');
            s.src = src;
            s.onload = resolve;
            s.onerror = function() { reject(new Error('Failed to load ' + src)); };
            document.head.appendChild(s);
        });
    }

    // ── Review surface (v0.35.0: structured review with side-by-side + comments) ──
    if (STAGE_MODE === 'review') {
        var dataPanel = document.getElementById('reviewDataPanel');
        var actionPanel = document.getElementById('reviewActionPanel');
        if (dataPanel && actionPanel) {
            loadReviewSurface(dataPanel, actionPanel);
        }
    }

    async function loadReviewSurface(dataPanel, actionPanel) {
        dataPanel.innerHTML = '<div style="padding:24px;text-align:center;color:var(--text-3)">Loading\u2026</div>';

        // Left panel: structured data card
        var html = '<div style="padding:24px">';
        html += '<h3 style="margin-bottom:16px">Collected Data</h3>';

        try {
            var resp = await fetch(BASE + '/api/v1/channels/' + CHAN_ID + '/workflow/status', {
                headers: { 'Content-Type': 'application/json' },
            });
            if (resp.ok) {
                var status = await resp.json();
                if (status.stage_data && typeof status.stage_data === 'object') {
                    html += '<table style="width:100%;border-collapse:collapse">';
                    for (var key in status.stage_data) {
                        if (!status.stage_data.hasOwnProperty(key) || key.startsWith('_')) continue;
                        html += '<tr style="border-bottom:1px solid var(--border)">';
                        html += '<td style="padding:8px;font-weight:600;font-size:13px;width:30%;vertical-align:top">' + escHtml(key) + '</td>';
                        var val = status.stage_data[key];
                        var display = typeof val === 'object' ? JSON.stringify(val, null, 2) : String(val);
                        html += '<td style="padding:8px;font-size:13px;white-space:pre-wrap">' + escHtml(display) + '</td>';
                        html += '</tr>';
                    }
                    html += '</table>';
                } else {
                    html += '<p style="color:var(--text-3)">No data collected yet.</p>';
                }
            }
        } catch(e) {
            html += '<p style="color:var(--danger)">Failed to load review data.</p>';
        }
        html += '</div>';
        dataPanel.innerHTML = html;

        // Right panel: comment input + approve/reject buttons
        var actHtml = '<div style="padding:24px;flex:1;display:flex;flex-direction:column">';
        actHtml += '<h3 style="margin-bottom:16px">Review Actions</h3>';
        actHtml += '<div style="margin-bottom:16px">';
        actHtml += '<label style="font-size:13px;font-weight:600;display:block;margin-bottom:4px">Add Comment</label>';
        actHtml += '<textarea id="reviewComment" rows="3" style="width:100%;padding:8px;font-size:14px;border:1px solid var(--border);border-radius:6px;background:var(--input-bg);color:var(--text);font-family:var(--font);resize:vertical" placeholder="Optional comment\u2026"></textarea>';
        actHtml += '</div>';
        actHtml += '<div style="display:flex;gap:8px">';
        actHtml += '<button id="reviewAdvanceBtn" style="background:var(--accent);color:#fff;border:none;border-radius:8px;padding:10px 24px;font-weight:600;cursor:pointer;font-size:14px">Approve &amp; Advance</button>';
        actHtml += '<button id="reviewRejectBtn" style="background:var(--danger,#e74c3c);color:#fff;border:none;border-radius:8px;padding:10px 24px;font-weight:600;cursor:pointer;font-size:14px">Reject</button>';
        actHtml += '</div>';
        actHtml += '<div style="font-size:12px;color:var(--text-3);margin-top:8px">Ctrl+Enter: Approve &middot; Ctrl+Shift+Enter: Reject</div>';
        actHtml += '</div>';
        actionPanel.innerHTML = actHtml;

        // Keyboard shortcuts (v0.35.0)
        document.addEventListener('keydown', function(e) {
            if (e.ctrlKey && e.key === 'Enter') {
                e.preventDefault();
                if (e.shiftKey) {
                    document.getElementById('reviewRejectBtn').click();
                } else {
                    document.getElementById('reviewAdvanceBtn').click();
                }
            }
        });

        document.getElementById('reviewAdvanceBtn').addEventListener('click', async function() {
            this.disabled = true;
            try {
                var r = await fetch(BASE + '/api/v1/channels/' + CHAN_ID + '/workflow/advance', {
                    method: 'POST', headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ data: {} }),
                });
                if (r.ok) {
                    actionPanel.innerHTML = '<div style="padding:40px;text-align:center"><h3>Approved</h3><p style="color:var(--text-2)">Stage advanced.</p></div>';
                    setTimeout(function() { window.location.reload(); }, 1500);
                } else {
                    var err = await r.json().catch(function() { return {}; });
                    alert('Failed: ' + (err.error || 'unknown'));
                    document.getElementById('reviewAdvanceBtn').disabled = false;
                }
            } catch(e) { alert('Error: ' + e.message); }
        });

        document.getElementById('reviewRejectBtn').addEventListener('click', async function() {
            var comment = document.getElementById('reviewComment').value;
            var reason = comment || prompt('Rejection reason:');
            if (!reason) return;
            this.disabled = true;
            try {
                var r = await fetch(BASE + '/api/v1/channels/' + CHAN_ID + '/workflow/reject', {
                    method: 'POST', headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ reason: reason }),
                });
                if (r.ok) {
                    actionPanel.innerHTML = '<div style="padding:40px;text-align:center"><h3>Rejected</h3><p style="color:var(--text-2)">Sent back for revision.</p></div>';
                    setTimeout(function() { window.location.reload(); }, 1500);
                } else {
                    var err = await r.json().catch(function() { return {}; });
                    alert('Failed: ' + (err.error || 'unknown'));
                    document.getElementById('reviewRejectBtn').disabled = false;
                }
            } catch(e) { alert('Error: ' + e.message); }
        });
    }
})();
</script>
</body>
</html>
{{end}}
