/**
 * Team Admin > Workflows — v0.37.15 rewrite
 *
 * Tab layout: Workflows | Assignments | Monitor
 * - Workflows: CRUD + inline stage editor (E2)
 * - Assignments: Team assignment queue (E1)
 * - Monitor: Active instance list with cancel (E3)
 */
const { html } = window;
const { useState, useEffect, useCallback } = hooks;

const ENTRY_MODES = ['public_link', 'team_only'];
const STAGE_MODES = ['form', 'review', 'delegated', 'automated'];
const STAGE_TYPES = ['simple', 'dynamic', 'automated'];
const AUDIENCES = ['team', 'public', 'system'];
const TABS = ['Workflows', 'Assignments', 'Monitor'];

function _timeAgo(ts) {
    if (!ts) return '';
    const diff = Date.now() - new Date(ts).getTime();
    const mins = Math.floor(diff / 60000);
    if (mins < 1) return 'just now';
    if (mins < 60) return `${mins}m ago`;
    const hrs = Math.floor(mins / 60);
    if (hrs < 24) return `${hrs}h ago`;
    return `${Math.floor(hrs / 24)}d ago`;
}

function _formatDuration(seconds) {
    if (!seconds || seconds < 0) return '—';
    if (seconds < 60) return `${seconds}s`;
    const mins = Math.floor(seconds / 60);
    if (mins < 60) return `${mins}m`;
    const hrs = Math.floor(mins / 60);
    if (hrs < 24) return `${hrs}h ${mins % 60}m`;
    return `${Math.floor(hrs / 24)}d ${hrs % 24}h`;
}

// ── Main Section ────────────────────────────

export default function WorkflowsSection({ teamId }) {
    const [tab, setTab] = useState('Workflows');

    return html`
        <div>
            <div class="admin-tabs" style="display:flex;gap:4px;margin-bottom:16px;">
                ${TABS.map(t => html`
                    <button key=${t}
                        class="btn-small ${tab === t ? 'btn-primary' : ''}"
                        onClick=${() => setTab(t)}>${t}</button>
                `)}
            </div>
            ${tab === 'Workflows' && html`<${WorkflowsTab} teamId=${teamId} />`}
            ${tab === 'Assignments' && html`<${AssignmentsTab} teamId=${teamId} />`}
            ${tab === 'Monitor' && html`<${MonitorTab} teamId=${teamId} />`}
        </div>
    `;
}

// ── Tab 1: Workflows ────────────────────────

function _unwrapList(resp) {
    return Array.isArray(resp) ? resp : (resp && resp.data ? resp.data : []);
}

function WorkflowsTab({ teamId }) {
    const [workflows, setWorkflows] = useState([]);
    const [loading, setLoading] = useState(true);
    const [editing, setEditing] = useState(null);
    const [showCreate, setShowCreate] = useState(false);
    const [showAdopt, setShowAdopt] = useState(false);
    const [available, setAvailable] = useState([]);

    const load = useCallback(async () => {
        try {
            const data = await sw.api.teams.workflows(teamId);
            setWorkflows(_unwrapList(data));
        } catch (e) { sw.toast(e.message, 'error'); }
        finally { setLoading(false); }
    }, [teamId]);

    useEffect(() => { load(); }, [load]);

    async function createWorkflow(e) {
        e.preventDefault();
        const form = e.target;
        try {
            await sw.api.teams.createWorkflow(teamId, {
                name: form.name.value.trim(),
                slug: form.slug.value.trim(),
                entry_mode: form.entry_mode.value,
                description: form.description.value.trim(),
            });
            sw.toast('Workflow created', 'success');
            setShowCreate(false);
            load();
        } catch (e) { sw.toast(e.message, 'error'); }
    }

    async function openAdopt() {
        setShowAdopt(true);
        try {
            const data = await sw.api.teams.availableWorkflows(teamId);
            setAvailable(_unwrapList(data));
        } catch (e) { sw.toast(e.message, 'error'); }
    }

    async function adoptWorkflow(wfId) {
        try {
            await sw.api.teams.adoptWorkflow(teamId, wfId);
            sw.toast('Workflow adopted', 'success');
            setShowAdopt(false);
            load();
        } catch (e) { sw.toast(e.message, 'error'); }
    }

    if (loading) return html`<div class="settings-placeholder">Loading\u2026</div>`;

    if (editing) return html`<${WorkflowEditor} teamId=${teamId} workflow=${editing}
        onBack=${() => { setEditing(null); load(); }} />`;

    return html`
        <div>
            <div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
                <div style="flex:1"></div>
                <button class="btn-md" onClick=${openAdopt}>Adopt Global</button>
                <button class="btn-md btn-primary" onClick=${() => setShowCreate(true)}>+ Add</button>
            </div>

            ${showAdopt && html`
                <div class="admin-inline-form" style="margin-bottom:16px;">
                    <div style="display:flex;align-items:center;gap:8px;margin-bottom:8px;">
                        <strong>Adopt a Global Workflow</strong>
                        <div style="flex:1"></div>
                        <button class="btn-small" onClick=${() => setShowAdopt(false)}>Cancel</button>
                    </div>
                    ${available.length === 0 && html`<div class="empty-hint">No global workflows available</div>`}
                    <div class="admin-list">
                        ${available.map(w => html`
                            <div class="admin-surface-row" key=${w.id}>
                                <div style="flex:1;min-width:0;">
                                    <strong>${w.name}</strong>
                                    <span class="text-muted" style="margin-left:8px;font-size:11px;">/${w.slug}</span>
                                </div>
                                <span class="badge">${w.entry_mode}</span>
                                <button class="btn-small btn-primary" onClick=${() => adoptWorkflow(w.id)}>Adopt</button>
                            </div>
                        `)}
                    </div>
                </div>
            `}

            ${showCreate && html`
                <form class="admin-inline-form" style="margin-bottom:16px;" onSubmit=${createWorkflow}>
                    <div class="form-row">
                        <div class="form-group"><label>Name</label><input name="name" placeholder="Customer Intake" /></div>
                        <div class="form-group"><label>Slug</label><input name="slug" placeholder="customer-intake" /></div>
                        <div class="form-group"><label>Entry Mode</label>
                            <select name="entry_mode">
                                ${ENTRY_MODES.map(m => html`<option key=${m} value=${m}>${m}</option>`)}
                            </select>
                        </div>
                    </div>
                    <div class="form-group"><label>Description</label><input name="description" placeholder="Optional" /></div>
                    <div class="form-row" style="margin-top:8px;gap:8px;">
                        <button type="submit" class="btn-small btn-primary">Create</button>
                        <button type="button" class="btn-small" onClick=${() => setShowCreate(false)}>Cancel</button>
                    </div>
                </form>
            `}

            <div class="admin-list">
                ${workflows.length === 0 && html`<div class="empty-hint">No workflows — create one or adopt from global</div>`}
                ${workflows.map(w => html`
                    <div class="admin-surface-row" key=${w.id} style="cursor:pointer;" onClick=${() => setEditing(w)}>
                        <div style="flex:1;min-width:0;">
                            <strong>${w.name}</strong>
                            <span class="text-muted" style="margin-left:8px;font-size:11px;">/${w.slug}</span>
                        </div>
                        <span class="badge">${w.entry_mode}</span>
                        <span class="badge ${w.is_active ? 'badge-active' : 'badge-inactive'}">${w.is_active ? 'active' : 'inactive'}</span>
                        <span class="text-muted" style="font-size:11px;">v${w.version || 0}</span>
                    </div>
                `)}
            </div>
        </div>
    `;
}

// ── Workflow Editor (with Stage Editor) ─────

function WorkflowEditor({ teamId, workflow, onBack }) {
    const [stages, setStages] = useState([]);
    const [teams, setTeams] = useState([]);
    const [editingStage, setEditingStage] = useState(null); // null | 'new' | stage_id

    const loadStages = useCallback(async () => {
        try {
            const s = await sw.api.teams.workflowStages(teamId, workflow.id);
            setStages(s || []);
            setTeams(sw.auth?.teams || []);
        } catch (e) { sw.toast(e.message, 'error'); }
    }, [teamId, workflow.id]);

    useEffect(() => { loadStages(); }, [loadStages]);

    async function updateWorkflow(e) {
        e.preventDefault();
        const form = e.target;
        try {
            const patch = {
                name: form.name.value.trim(),
                description: form.description.value.trim(),
                entry_mode: form.entry_mode.value,
                is_active: form.is_active.checked,
            };
            const sth = form.staleness_timeout_hours.value.trim();
            if (sth !== '') patch.staleness_timeout_hours = parseInt(sth, 10);
            await sw.api.teams.updateWorkflow(teamId, workflow.id, patch);
            sw.toast('Workflow updated', 'success');
        } catch (e) { sw.toast(e.message, 'error'); }
    }

    async function publishWorkflow() {
        try {
            await sw.api.teams.publishWorkflow(teamId, workflow.id);
            sw.toast('Workflow published', 'success');
        } catch (e) { sw.toast(e.message, 'error'); }
    }

    async function deleteWorkflow() {
        const ok = await sw.confirm('Delete this workflow? All stages, versions, and instances will be deleted.', true);
        if (!ok) return;
        try {
            await sw.api.teams.deleteWorkflow(teamId, workflow.id);
            sw.toast('Workflow deleted', 'success');
            onBack();
        } catch (e) { sw.toast(e.message, 'error'); }
    }

    async function addStage(data) {
        try {
            await sw.api.teams.createWorkflowStage(teamId, workflow.id, data);
            setEditingStage(null);
            loadStages();
        } catch (e) { sw.toast(e.message, 'error'); }
    }

    async function updateStage(stageId, data) {
        try {
            await sw.api.teams.updateWorkflowStage(teamId, workflow.id, stageId, data);
            setEditingStage(null);
            loadStages();
        } catch (e) { sw.toast(e.message, 'error'); }
    }

    async function deleteStage(stageId) {
        const ok = await sw.confirm('Delete this stage?', true);
        if (!ok) return;
        try {
            await sw.api.teams.deleteWorkflowStage(teamId, workflow.id, stageId);
            loadStages();
        } catch (e) { sw.toast(e.message, 'error'); }
    }

    return html`
        <form onSubmit=${updateWorkflow}>
            <div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
                <button type="button" class="btn-small" onClick=${onBack}>\u2190 Back</button>
                <h4 style="margin:0;">Edit: ${workflow.name}</h4>
                <div style="flex:1"></div>
                <button type="button" class="btn-small" onClick=${publishWorkflow}>Publish</button>
                <button type="button" class="btn-small btn-danger" onClick=${deleteWorkflow}>Delete</button>
            </div>
            <div class="form-row">
                <div class="form-group"><label>Name</label><input name="name" value=${workflow.name || ''} /></div>
                <div class="form-group"><label>Entry Mode</label>
                    <select name="entry_mode">
                        ${ENTRY_MODES.map(m => html`<option key=${m} value=${m} selected=${workflow.entry_mode === m}>${m}</option>`)}
                    </select>
                </div>
            </div>
            <div class="form-row">
                <div class="form-group" style="flex:1;"><label>Description</label><input name="description" value=${workflow.description || ''} /></div>
                <div class="form-group" style="max-width:180px;"><label>Staleness (hours)</label>
                    <input type="number" name="staleness_timeout_hours" min="0"
                        value=${workflow.staleness_timeout_hours ?? ''} placeholder="disabled" />
                </div>
            </div>
            <label class="toggle-label" style="margin:8px 0;">
                <input type="checkbox" name="is_active" checked=${workflow.is_active !== false} />
                <span class="toggle-track"></span><span>Active</span>
            </label>

            ${workflow.entry_mode === 'public_link' && html`
                <div style="margin:8px 0;">
                    <label style="font-size:11px;color:var(--text-2);display:block;margin-bottom:4px;">Public Entry URL</label>
                    <div style="display:flex;gap:6px;align-items:center;">
                        <input type="text" readOnly value=${window.location.origin + (window.__BASE__ || '') + '/api/v1/public/workflows/' + workflow.id + '/start'}
                            style="flex:1;font-size:11px;padding:4px 8px;background:var(--input-bg);border:1px solid var(--border);border-radius:4px;color:var(--text);font-family:var(--mono);"
                            onClick=${e => e.target.select()} />
                        <button type="button" class="btn-small" onClick=${(e) => {
                            const url = window.location.origin + (window.__BASE__ || '') + '/api/v1/public/workflows/' + workflow.id + '/start';
                            navigator.clipboard.writeText(url).then(() => {
                                e.target.textContent = 'Copied!';
                                setTimeout(() => { e.target.textContent = 'Copy'; }, 1500);
                            });
                        }}>Copy</button>
                    </div>
                </div>
            `}

            <div class="form-row" style="margin-top:16px;gap:8px;">
                <button type="submit" class="btn-small btn-primary">Save</button>
            </div>
        </form>

        <!-- Stage Editor -->
        <div style="margin-top:24px;">
            <div style="display:flex;align-items:center;gap:8px;margin-bottom:8px;">
                <h5 style="margin:0;">Stages (${stages.length})</h5>
                <div style="flex:1"></div>
                <button class="btn-small" onClick=${() => setEditingStage('new')}>+ Add Stage</button>
            </div>

            <div class="admin-list">
                ${stages.map((s, i) => html`
                    <div class="admin-surface-row" key=${s.id || i}>
                        <span class="text-muted" style="font-size:11px;width:24px;">#${i + 1}</span>
                        <strong style="flex:1;">${s.name || `Stage ${i + 1}`}</strong>
                        <span class="badge">${s.stage_mode || '\u2014'}</span>
                        <span class="badge">${s.audience || 'team'}</span>
                        ${s.assignment_team_id && html`<span class="badge">team assign</span>`}
                        <button class="btn-small" onClick=${() => setEditingStage(s.id)}>Edit</button>
                        <button class="btn-small btn-danger" onClick=${() => deleteStage(s.id)}>\u00d7</button>
                    </div>
                `)}
                ${stages.length === 0 && html`<div class="empty-hint">No stages defined</div>`}
            </div>

            ${editingStage && html`
                <${StageForm}
                    stage=${editingStage === 'new' ? null : stages.find(s => s.id === editingStage)}
                    teams=${teams}
                    onSave=${(data) => editingStage === 'new' ? addStage(data) : updateStage(editingStage, data)}
                    onCancel=${() => setEditingStage(null)}
                />
            `}
        </div>
    `;
}

// ── Stage Form ──────────────────────────────

function StageForm({ stage, teams, onSave, onCancel }) {
    const [name, setName] = useState(stage?.name || '');
    const [mode, setMode] = useState(stage?.stage_mode || 'form');
    const [audience, setAudience] = useState(stage?.audience || 'team');
    const [stageType, setStageType] = useState(stage?.stage_type || 'simple');
    const [starlarkHook, setStarlarkHook] = useState(stage?.starlark_hook || '');
    const [assignTeam, setAssignTeam] = useState(stage?.assignment_team_id || '');
    const [autoTransition, setAutoTransition] = useState(stage?.auto_transition || false);
    const [sla, setSla] = useState(stage?.sla_seconds || '');
    const [branchRules, setBranchRules] = useState(
        stage?.branch_rules ? (typeof stage.branch_rules === 'string' ? stage.branch_rules : JSON.stringify(stage.branch_rules, null, 2)) : ''
    );

    // v0.3.4: stage_config fields
    const sc = stage?.stage_config ? (typeof stage.stage_config === 'string' ? JSON.parse(stage.stage_config || '{}') : stage.stage_config) : {};
    const [requiredRole, setRequiredRole] = useState(sc.required_role || '');
    const [valApprovals, setValApprovals] = useState(sc.validation?.required_approvals || '');
    const [valRole, setValRole] = useState(sc.validation?.required_role || '');
    const [valReject, setValReject] = useState(sc.validation?.reject_action || 'cancel');
    const [teamRoles, setTeamRoles] = useState(['admin', 'member']);

    useEffect(() => {
        if (!assignTeam) return;
        sw.api.get(`/api/v1/teams/${assignTeam}/roles`).then(r => setTeamRoles(r.data || ['admin', 'member'])).catch(() => {});
    }, [assignTeam]);

    function submit() {
        const stageConfig = {};
        if (requiredRole) stageConfig.required_role = requiredRole;
        if (valApprovals) {
            stageConfig.validation = {
                required_approvals: parseInt(valApprovals, 10),
                ...(valRole ? { required_role: valRole } : {}),
                reject_action: valReject || 'cancel',
            };
        }
        let parsedBranch = null;
        if (branchRules.trim()) {
            try { parsedBranch = JSON.parse(branchRules); } catch { sw.toast('Invalid branch_rules JSON', 'error'); return; }
        }
        onSave({
            name,
            stage_mode: mode,
            audience,
            stage_type: stageType,
            starlark_hook: starlarkHook || null,
            assignment_team_id: assignTeam || null,
            auto_transition: autoTransition,
            sla_seconds: sla ? parseInt(sla, 10) : null,
            stage_config: Object.keys(stageConfig).length ? stageConfig : {},
            branch_rules: parsedBranch || [],
        });
    }

    return html`
        <div style="margin-top:12px;padding:12px;border:1px solid var(--border-1);border-radius:6px;">
            <div class="form-row">
                <div class="form-group">
                    <label>Name</label>
                    <input value=${name} onInput=${e => setName(e.target.value)} />
                </div>
                <div class="form-group">
                    <label>Mode</label>
                    <select value=${mode} onChange=${e => setMode(e.target.value)}>
                        ${STAGE_MODES.map(m => html`<option key=${m} value=${m}>${m}</option>`)}
                    </select>
                </div>
            </div>
            <div class="form-row">
                <div class="form-group">
                    <label>Audience</label>
                    <select value=${audience} onChange=${e => setAudience(e.target.value)}>
                        ${AUDIENCES.map(a => html`<option key=${a} value=${a}>${a}</option>`)}
                    </select>
                </div>
                <div class="form-group">
                    <label>Stage Type</label>
                    <select value=${stageType} onChange=${e => setStageType(e.target.value)}>
                        ${STAGE_TYPES.map(t => html`<option key=${t} value=${t}>${t}</option>`)}
                    </select>
                </div>
            </div>
            ${stageType !== 'simple' && html`
                <div class="form-row">
                    <div class="form-group" style="flex:1;">
                        <label>Starlark Hook</label>
                        <input value=${starlarkHook} onInput=${e => setStarlarkHook(e.target.value)}
                               placeholder="package_id:entry_point" />
                    </div>
                </div>
            `}
            <div class="form-row">
                <div class="form-group">
                    <label>Queue to Team</label>
                    <select value=${assignTeam} onChange=${e => setAssignTeam(e.target.value)}>
                        <option value="">\u2014 none (visitor stage) \u2014</option>
                        ${teams.map(t => html`<option key=${t.id || t.team_id} value=${t.id || t.team_id}>${t.name || t.team_name}</option>`)}
                    </select>
                </div>
                <div class="form-group">
                    <label>SLA (seconds)</label>
                    <input type="number" value=${sla} onInput=${e => setSla(e.target.value)} placeholder="e.g. 3600" />
                </div>
            </div>
            ${assignTeam && html`
                <div class="form-row">
                    <div class="form-group">
                        <label>Required Role (claim)</label>
                        <select value=${requiredRole} onChange=${e => setRequiredRole(e.target.value)}>
                            <option value="">\u2014 any member \u2014</option>
                            ${teamRoles.map(r => html`<option key=${r} value=${r}>${r}</option>`)}
                        </select>
                    </div>
                </div>
                <div style="margin-top:8px;padding:8px;border:1px dashed var(--border-1);border-radius:4px;">
                    <strong style="font-size:12px;">Multi-party Validation</strong>
                    <div class="form-row" style="margin-top:4px;">
                        <div class="form-group">
                            <label>Required Approvals</label>
                            <input type="number" min="0" value=${valApprovals}
                                   onInput=${e => setValApprovals(e.target.value)} placeholder="0 = none" />
                        </div>
                        <div class="form-group">
                            <label>Signoff Role</label>
                            <select value=${valRole} onChange=${e => setValRole(e.target.value)}>
                                <option value="">\u2014 any member \u2014</option>
                                ${teamRoles.map(r => html`<option key=${r} value=${r}>${r}</option>`)}
                            </select>
                        </div>
                        <div class="form-group">
                            <label>On Reject</label>
                            <select value=${valReject} onChange=${e => setValReject(e.target.value)}>
                                <option value="cancel">Cancel instance</option>
                            </select>
                        </div>
                    </div>
                </div>
            `}
            <details style="margin-top:8px;">
                <summary style="cursor:pointer;font-size:12px;color:var(--text-muted);">Branch Rules (advanced)</summary>
                <div class="form-group" style="margin-top:4px;">
                    <textarea rows="3" value=${branchRules} onInput=${e => setBranchRules(e.target.value)}
                        placeholder='[{"field":"priority","op":"eq","value":"high","target_stage":"escalation"}]'
                        style="font-family:monospace;font-size:11px;width:100%;"></textarea>
                </div>
            </details>
            <label class="toggle-label">
                <input type="checkbox" checked=${autoTransition} onChange=${e => setAutoTransition(e.target.checked)} />
                <span class="toggle-track"></span><span>Auto-advance when complete</span>
            </label>
            <div class="form-row" style="margin-top:12px;gap:8px;">
                <button type="button" class="btn-small btn-primary" onClick=${submit}>
                    ${stage ? 'Update' : 'Add Stage'}
                </button>
                <button type="button" class="btn-small" onClick=${onCancel}>Cancel</button>
            </div>
        </div>
    `;
}

// ── Tab 2: Assignments ──────────────────────

function AssignmentsTab({ teamId }) {
    const [claimed, setClaimed] = useState([]);
    const [unassigned, setUnassigned] = useState([]);
    const [loading, setLoading] = useState(true);

    const load = useCallback(async () => {
        try {
            const [c, u] = await Promise.all([
                sw.api.teams.assignments(teamId, { status: 'claimed' }),
                sw.api.teams.assignments(teamId, { status: 'unassigned' }),
            ]);
            setClaimed(c || []);
            setUnassigned(u || []);
        } catch (e) { sw.toast(e.message, 'error'); }
        finally { setLoading(false); }
    }, [teamId]);

    useEffect(() => { load(); }, [load]);

    // WS live updates
    useEffect(() => {
        const off1 = sw.on('workflow.assigned', load);
        const off2 = sw.on('workflow.claimed', load);
        const off3 = sw.on('workflow.unclaimed', load);
        return () => { off1(); off2(); off3(); };
    }, [teamId]);

    async function claim(id) {
        try {
            await sw.api.workflowAssignments.claim(id);
            load();
        } catch (e) { sw.toast(e.message, 'error'); }
    }

    async function unclaim(id) {
        try {
            await sw.api.workflowAssignments.unclaim(id);
            load();
        } catch (e) { sw.toast(e.message, 'error'); }
    }

    async function complete(id) {
        try {
            await sw.api.workflowAssignments.complete(id);
            sw.toast('Assignment completed', 'success');
            load();
        } catch (e) { sw.toast(e.message, 'error'); }
    }

    if (loading) return html`<div class="settings-placeholder">Loading\u2026</div>`;

    const userId = sw.auth?.user?.id;

    return html`
        <div>
            <h4 style="margin:0 0 8px;">My Active (${claimed.length})</h4>
            <div class="admin-list">
                ${claimed.map(a => html`
                    <div class="admin-surface-row" key=${a.id} style="border-left:3px solid var(--accent-1);">
                        <div style="flex:1;min-width:0;">
                            <strong>${a.workflow_name || 'Workflow'}</strong>
                            <span class="badge">${a.stage_name || `Stage ${a.stage}`}</span>
                            ${a.sla_breached && html`<span class="badge badge-danger">SLA</span>`}
                        </div>
                        <div style="display:flex;gap:4px;">
                            <button class="btn-small" onClick=${() => unclaim(a.id)}>Release</button>
                            <button class="btn-small btn-primary"
                                onClick=${() => { location.href = sw.base + '/w/' + a.channel_id; }}>Open</button>
                            <button class="btn-small btn-success" onClick=${() => complete(a.id)}>Complete</button>
                        </div>
                    </div>
                `)}
                ${claimed.length === 0 && html`<div class="empty-hint">No claimed assignments</div>`}
            </div>

            <h4 style="margin:16px 0 8px;">Available (${unassigned.length})</h4>
            <div class="admin-list">
                ${unassigned.map(a => html`
                    <div class="admin-surface-row" key=${a.id}>
                        <div style="flex:1;min-width:0;">
                            <strong>${a.workflow_name || 'Workflow'}</strong>
                            <span class="badge">${a.stage_name || `Stage ${a.stage}`}</span>
                            <span class="text-muted" style="font-size:11px;">${_timeAgo(a.created_at)}</span>
                        </div>
                        <button class="btn-small btn-primary" onClick=${() => claim(a.id)}>Claim</button>
                    </div>
                `)}
                ${unassigned.length === 0 && html`<div class="empty-hint">No available assignments</div>`}
            </div>
        </div>
    `;
}

// ── Tab 3: Monitor ──────────────────────────

function MonitorTab({ teamId }) {
    const [instances, setInstances] = useState([]);
    const [loading, setLoading] = useState(true);
    const [expandedSignoff, setExpandedSignoff] = useState(null);

    const load = useCallback(async () => {
        try {
            const data = await sw.api.teams.workflowInstances(teamId);
            setInstances(data || []);
        } catch (e) { sw.toast(e.message, 'error'); }
        finally { setLoading(false); }
    }, [teamId]);

    useEffect(() => { load(); }, [load]);

    async function cancelInstance(channelId) {
        const ok = await sw.confirm('Cancel this workflow instance? All open assignments will be cancelled.', true);
        if (!ok) return;
        try {
            await sw.api.teams.cancelWorkflowInstance(teamId, channelId);
            sw.toast('Instance cancelled', 'success');
            load();
        } catch (e) { sw.toast(e.message, 'error'); }
    }

    if (loading) return html`<div class="settings-placeholder">Loading\u2026</div>`;

    return html`
        <div>
            <h4 style="margin:0 0 8px;">Active Instances (${instances.length})</h4>
            <div class="admin-list">
                ${instances.map(inst => html`
                    <div class="admin-surface-row" key=${inst.channel_id}>
                        <div style="flex:1;min-width:0;">
                            <strong>${inst.workflow_name}</strong>
                            <span class="badge">${inst.stage_name || `Stage ${inst.current_stage}`}</span>
                            ${inst.sla_breached && html`<span class="badge badge-danger">SLA breached</span>`}
                            <span class="text-muted" style="font-size:11px;">Age: ${_formatDuration(inst.age_seconds)}</span>
                        </div>
                        <div style="display:flex;gap:4px;">
                            <button class="btn-small"
                                onClick=${() => setExpandedSignoff(expandedSignoff === inst.id ? null : inst.id)}>Signoffs</button>
                            <button class="btn-small"
                                onClick=${() => { location.href = sw.base + '/w/' + inst.channel_id; }}>Open</button>
                            <button class="btn-small btn-danger" onClick=${() => cancelInstance(inst.channel_id)}>Cancel</button>
                        </div>
                        ${expandedSignoff === inst.id && html`<${SignoffPanel} instanceId=${inst.id} teamId=${teamId} />`}
                    </div>
                `)}
                ${instances.length === 0 && html`<div class="empty-hint">No active instances</div>`}
            </div>
        </div>
    `;
}

// ── Signoff Panel (v0.3.4) ──────────────────

function SignoffPanel({ instanceId, teamId }) {
    const [signoffs, setSignoffs] = useState([]);
    const [loading, setLoading] = useState(true);
    const [comment, setComment] = useState('');

    const load = useCallback(async () => {
        try {
            const resp = await sw.api.get(`/api/v1/instances/${instanceId}/signoffs`);
            setSignoffs(resp.data || []);
        } catch { setSignoffs([]); }
        finally { setLoading(false); }
    }, [instanceId]);

    useEffect(() => { load(); }, [load]);

    async function submit(decision) {
        try {
            await sw.api.post(`/api/v1/instances/${instanceId}/signoffs`, { decision, comment });
            sw.toast(decision === 'approve' ? 'Approved' : 'Rejected', 'success');
            setComment('');
            load();
        } catch (e) { sw.toast(e.message, 'error'); }
    }

    if (loading) return html`<span class="text-muted">Loading\u2026</span>`;

    const approvals = signoffs.filter(s => s.decision === 'approve').length;
    const rejections = signoffs.filter(s => s.decision === 'reject').length;

    return html`
        <div style="margin-top:8px;padding:8px;border:1px solid var(--border-1);border-radius:4px;font-size:12px;">
            <div style="display:flex;gap:8px;align-items:center;margin-bottom:4px;">
                <span>${approvals} approve${approvals !== 1 ? 's' : ''}</span>
                ${rejections > 0 && html`<span style="color:var(--danger);">${rejections} reject${rejections !== 1 ? 's' : ''}</span>`}
            </div>
            <div style="display:flex;gap:4px;align-items:center;">
                <input value=${comment} onInput=${e => setComment(e.target.value)}
                       placeholder="Comment (optional)" style="flex:1;font-size:12px;" />
                <button class="btn-small btn-success" onClick=${() => submit('approve')}>Approve</button>
                <button class="btn-small btn-danger" onClick=${() => submit('reject')}>Reject</button>
            </div>
            ${signoffs.length > 0 && html`
                <div style="margin-top:6px;">
                    ${signoffs.map(s => html`
                        <div key=${s.id} style="display:flex;gap:4px;align-items:center;font-size:11px;margin-top:2px;">
                            <span class="badge ${s.decision === 'approve' ? 'badge-success' : 'badge-danger'}">${s.decision}</span>
                            <span>${s.user_id}</span>
                            ${s.comment && html`<span class="text-muted">\u2014 ${s.comment}</span>`}
                        </div>
                    `)}
                </div>
            `}
        </div>
    `;
}
