// TreeGovernance.jsx — public vote affordance + provenance (doc 06 §1).
const { useState: useTGs, useEffect: useTGe, useCallback: useTGcb } = React;

function TreeVoteBar({ mode = 'patient', treeId, versionId, slug, compact }) {
  const [row, setRow] = useTGs(null);
  const [busy, setBusy] = useTGs(false);
  const [msg, setMsg] = useTGs('');

  const refresh = useTGcb(async () => {
    let meta = null;
    if (window.DecisionTreeEngine?.getMeta) meta = window.DecisionTreeEngine.getMeta(mode);
    const tid = treeId || meta?.tree_id;
    const vid = versionId || meta?.version_id;
    const sl = slug || meta?.slug;
    if (!tid && !sl) return;
    try {
      const r = await fetch('/api/trees');
      if (!r.ok) return;
      const d = await r.json();
      const list = d.trees || [];
      let match = tid ? list.find((t) => t.tree_id === tid) : null;
      if (!match && sl) match = list.find((t) => t.slug === sl);
      if (match) {
        setRow({
          ...match,
          version_id: vid || match.version_id,
          council_verified: match.council_verified || meta?.council_verified,
        });
      }
    } catch (_) { /* offline / unpublished */ }
  }, [mode, treeId, versionId, slug]);

  useTGe(() => { refresh(); }, [refresh]);

  const castVote = async (vote) => {
    if (!row?.tree_id || !row?.version_id || busy) return;
    setBusy(true);
    setMsg('');
    try {
      const r = await fetch(`/api/trees/${row.tree_id}/vote`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ version_id: row.version_id, vote }),
      });
      const d = await r.json().catch(() => ({}));
      if (r.status === 429) {
        setMsg('One vote per tree per day when browsing anonymously.');
        return;
      }
      if (!r.ok || !d.ok) {
        setMsg(d.error || d.hint || 'Vote not recorded');
        return;
      }
      if (d.totals) {
        setRow((prev) => (prev ? {
          ...prev,
          votes: d.totals,
          provenance_line: prev.provenance_line,
        } : prev));
      }
      setMsg(d.voter_badge ? `Recorded as ${d.voter_badge}` : 'Thanks — vote recorded');
      await refresh();
    } catch (e) {
      setMsg('Could not reach vote service');
    } finally {
      setBusy(false);
    }
  };

  if (!row?.version_id) return null;

  const up = Number(row.votes?.upvotes) || 0;
  const down = Number(row.votes?.downvotes) || 0;
  const pad = compact ? '10px 12px' : '12px 14px';

  return (
    <div
      className="tree-governance"
      style={{
        marginTop: compact ? 'var(--s-3)' : 'var(--s-5)',
        padding: pad,
        background: 'var(--bone)',
        borderRadius: 'var(--r-4)',
        border: '1px solid var(--ink-5)',
        fontSize: compact ? 12 : 13,
      }}
      aria-label="Decision tree community feedback"
    >
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center', marginBottom: 6 }}>
        {row.council_verified && (
          <span style={{
            fontWeight: 700,
            fontSize: 11,
            letterSpacing: '.04em',
            textTransform: 'uppercase',
            color: 'var(--seal)',
          }}
          >
            Council-verified {window.FlatIcon && React.createElement(window.FlatIcon, { name: 'check', size: 12, color: 'var(--seal)' })}
          </span>
        )}
        <span className="t-fine" style={{ margin: 0, color: 'var(--ink-3)' }}>
          Community signal — anonymous OK
        </span>
      </div>
      {row.provenance_line && (
        <div style={{ color: 'var(--ink-2)', lineHeight: 1.5, marginBottom: 8, fontFamily: 'var(--font-mono, monospace)', fontSize: 11 }}>
          {row.provenance_line}
        </div>
      )}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
        <button
          type="button"
          disabled={busy}
          onClick={() => castVote(1)}
          aria-label="Upvote this tree"
          style={{
            border: '1px solid var(--ink-5)',
            background: '#fff',
            borderRadius: 8,
            padding: '4px 10px',
            cursor: busy ? 'wait' : 'pointer',
            fontWeight: 700,
            fontFamily: 'var(--font-mono, monospace)',
          }}
        >
          ▲ {up}
        </button>
        <button
          type="button"
          disabled={busy}
          onClick={() => castVote(-1)}
          aria-label="Downvote this tree"
          style={{
            border: '1px solid var(--ink-5)',
            background: '#fff',
            borderRadius: 8,
            padding: '4px 10px',
            cursor: busy ? 'wait' : 'pointer',
            fontWeight: 700,
            fontFamily: 'var(--font-mono, monospace)',
          }}
        >
          ▼ {down}
        </button>
        {msg && <span style={{ color: 'var(--ink-3)', fontSize: 11 }}>{msg}</span>}
      </div>
    </div>
  );
}

window.TreeVoteBar = TreeVoteBar;
