// ============================================================
// CHANNEL CONTROL CENTER — per-platform mission control
// Tabs: Accounts · Settings · Compose · Workflows · Logs
// ============================================================

// Per-platform mock account generator -----------------------------
const ACCOUNT_TEMPLATES = {
  tiktok:    [['Belmont Dental', '@belmont_dental'], ['Belmont Smile', '@belmont_smile'], ['Dr. Anya', '@dr_patel_uk'], ['Iyer Studio', '@iyer_studio'], ['Acme Property', '@acme_homes'], ['Demiurge UK', '@demiurge_uk']],
  instagram: [['Belmont Dental', 'belmont.dental'], ['Belmont Whitening', 'belmont.smile'], ['Dr. Anya Patel', 'dr.anya.patel'], ['Iyer Studio', 'iyer.studio'], ['Acme Property', 'acme.property'], ['Demiurge', 'demiurge.systems'], ['Demiurge EU', 'demiurge.eu']],
  youtube:   [['Belmont Dental Group', '@BelmontDentalUK'], ['Demiurge Systems', '@DemiurgeSystems']],
  facebook:  [['Belmont Dental Group', 'belmontdentalgroup'], ['Acme Property', 'acmeproperty']],
  linkedin:  [['Belmont Dental Group', 'belmont-dental'], ['Anya Patel, BDS', 'anya-patel-bds'], ['Marcus Whitfield', 'marcus-whitfield'], ['Demiurge Systems', 'demiurge-systems']],
  x:         [['Demiurge', '@demiurge_ai'], ['Anya Patel', '@dr_anya_patel']],
  threads:   [['Demiurge', '@demiurge.systems'], ['Iyer Studio', '@iyer.studio']],
  bluesky:   [['Demiurge', '@demiurge.systems.bsky.social']],
  pinterest: [['Belmont Dental Smile Gallery', 'belmontsmiles']],
  telegram:  [['Demiurge Ops', '@demiurge_ops_bot'], ['Belmont Bookings', '@belmont_bookings_bot']],
  whatsapp:  [['Belmont Dental · WA Business', '+44 20 7946 0421']],
  onlyfans:  [['Atelier · 12', '@atelier12']],
  fanvue:    [['Atelier · 12', '@atelier12']]
};

const PROXY_REGIONS = ['UK-LON', 'UK-MAN', 'EU-DE', 'EU-FR', 'EU-NL', 'US-E', 'US-W', 'AU-SYD'];

function buildAccounts(channelId, channelGroup) {
  const tpl = ACCOUNT_TEMPLATES[channelId] || [];
  return tpl.map((row, i) => {
    const seedVal = (channelId.charCodeAt(0) * 17 + i * 31) % 100;
    // status distribution
    let status;
    if (seedVal < 8 && i > 1)       status = 'error';
    else if (seedVal < 24 && i > 0) status = 'paused';
    else if (seedVal < 48)          status = 'warming';
    else                            status = 'live';
    if (channelGroup === 'creator') status = 'session';
    const stage = status === 'warming' ? `Day ${(i * 3 + 4) % 21 + 1} / 21` : status === 'session' ? 'Live · session' : status === 'paused' ? 'Paused' : status === 'error' ? '— halted' : 'Active';
    const health = status === 'error' ? 0.18 + (i * 0.04) : status === 'warming' ? 0.42 + (i * 0.07) % 0.4 : status === 'paused' ? 0.62 : 0.78 + (i * 0.03) % 0.22;
    return {
      id: `${channelId}-${i}`,
      name: row[0],
      handle: row[1],
      status,
      health: Math.min(0.99, health),
      proxy: PROXY_REGIONS[(i + seedVal) % PROXY_REGIONS.length],
      warmupStage: stage,
      queueDepth: status === 'live' || status === 'session' ? (i * 7 + 4) % 24 : status === 'warming' ? (i * 3 + 1) % 8 : 0,
      lastAction: status === 'error' ? 'auth_failed · 4m' : status === 'paused' ? 'paused by op · 2h' : status === 'session' ? 'session_refresh · 14m' : `posted · ${(i + 2) % 12 || 1}m`,
      nextAction: status === 'live' ? `compose · in ${(i + 1) * 11 % 60}m` : status === 'warming' ? `follow + view · in ${(i + 1) * 7 % 30}m` : status === 'session' ? `compose · ${['8:00 PM', '9:30 PM', '10:00 PM'][i % 3]}` : '—'
    };
  });
}

// Status pill ------------------------------------------------------
function StatusPill({ status }) {
  const map = {
    live:    { label: 'LIVE',    color: 'var(--cyan)',     bg: 'rgba(75,232,255,0.08)',   border: 'rgba(75,232,255,0.3)'  },
    warming: { label: 'WARMING', color: 'var(--warn)',     bg: 'rgba(255,177,75,0.08)',   border: 'rgba(255,177,75,0.3)'  },
    paused:  { label: 'PAUSED',  color: 'var(--text-dim)', bg: 'rgba(255,255,255,0.04)',  border: 'rgba(255,255,255,0.12)' },
    error:   { label: 'ERROR',   color: 'var(--danger)',   bg: 'rgba(255,93,110,0.08)',   border: 'rgba(255,93,110,0.3)'  },
    session: { label: 'SESSION', color: 'var(--warn)',     bg: 'rgba(255,177,75,0.08)',   border: 'rgba(255,177,75,0.3)'  }
  };
  const m = map[status] || map.live;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 5,
      padding: '2px 8px', fontFamily: 'var(--font-mono)', fontSize: 9.5,
      letterSpacing: '0.14em', borderRadius: 3,
      border: `1px solid ${m.border}`, background: m.bg, color: m.color,
      whiteSpace: 'nowrap'
    }}>
      <span style={{width: 5, height: 5, borderRadius: '50%', background: m.color, boxShadow: status === 'paused' ? 'none' : `0 0 6px ${m.color}`, animation: status === 'paused' ? 'none' : 'pulse 1.6s infinite'}}/>
      {m.label}
    </span>
  );
}

// Health bar -------------------------------------------------------
function HealthBar({ v }) {
  const color = v >= 0.7 ? 'var(--good)' : v >= 0.45 ? 'var(--warn)' : 'var(--danger)';
  return (
    <div style={{display: 'flex', alignItems: 'center', gap: 8}}>
      <div className="bar-track" style={{width: 60}}>
        <div className="bar-fill" style={{width: `${v * 100}%`, background: color, boxShadow: `0 0 6px ${color}`}}/>
      </div>
      <span className="mono" style={{fontSize: 10.5, color, minWidth: 22}}>{Math.round(v * 100)}</span>
    </div>
  );
}

// ===================== ACCOUNTS TAB =====================
function AccountsTab({ channel, accounts, onPushToast }) {
  const [selected, setSelected] = React.useState(new Set());
  const [filter, setFilter] = React.useState('all');

  const filtered = filter === 'all' ? accounts : accounts.filter(a => a.status === filter);
  const toggle = (id) => {
    const next = new Set(selected);
    if (next.has(id)) next.delete(id); else next.add(id);
    setSelected(next);
  };
  const toggleAll = () => {
    if (selected.size === filtered.length) setSelected(new Set());
    else setSelected(new Set(filtered.map(a => a.id)));
  };
  const bulk = (action) => {
    if (selected.size === 0) return;
    onPushToast(`${action} · ${selected.size} account${selected.size > 1 ? 's' : ''}`);
    setSelected(new Set());
  };
  const single = (action, account) => {
    onPushToast(`${action} · ${account.name}`);
  };

  const counts = accounts.reduce((acc, a) => { acc[a.status] = (acc[a.status] || 0) + 1; return acc; }, {});

  return (
    <div>
      {/* Filter pills */}
      <div style={{display: 'flex', alignItems: 'center', gap: 10, padding: '0 4px 14px', flexWrap: 'wrap'}}>
        {[
          ['all',     'All',      accounts.length],
          ['live',    'Live',     counts.live || 0],
          ['warming', 'Warming',  counts.warming || 0],
          ['paused',  'Paused',   counts.paused || 0],
          ['error',   'Error',    counts.error || 0],
          ['session', 'Session',  counts.session || 0]
        ].filter(([k, , n]) => k === 'all' || n > 0).map(([k, l, n]) => (
          <button key={k} onClick={() => setFilter(k)} className={`ccc-pill ${filter === k ? 'on' : ''}`}>
            {l} <span style={{opacity: 0.6, marginLeft: 4}}>{n}</span>
          </button>
        ))}
        <div style={{flex: 1}}/>
        <span className="mono faint" style={{fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase'}}>
          {filtered.length} shown · {accounts.length} total
        </span>
      </div>

      {/* Bulk action bar — shows when selection is active */}
      {selected.size > 0 && (
        <div className="ccc-bulk">
          <span className="mono" style={{fontSize: 11, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--cyan)'}}>
            {selected.size} selected
          </span>
          <span style={{flex: 1}}/>
          <button className="btn sm" onClick={() => bulk('Paused')}>Pause</button>
          <button className="btn sm" onClick={() => bulk('Resumed')}>Resume</button>
          <button className="btn sm" onClick={() => bulk('Proxy rotated')}>Rotate proxy</button>
          <button className="btn sm" onClick={() => bulk('Warmup started')}>Start warmup</button>
          <button className="btn sm" onClick={() => bulk('Workflow assigned')}>Assign workflow</button>
          <button className="btn sm" onClick={() => bulk('Campaign scheduled')}>Schedule campaign</button>
          <button className="btn sm ghost" onClick={() => setSelected(new Set())} title="Clear selection">✕</button>
        </div>
      )}

      {/* Account table */}
      <div className="ccc-table">
        <div className="ccc-row hd">
          <div className="c chk">
            <input type="checkbox" checked={selected.size > 0 && selected.size === filtered.length} onChange={toggleAll}/>
          </div>
          <div className="c">Account</div>
          <div className="c">Status</div>
          <div className="c">Health</div>
          <div className="c">Proxy</div>
          <div className="c">Warmup</div>
          <div className="c">Queue</div>
          <div className="c">Last</div>
          <div className="c">Next</div>
          <div className="c"></div>
        </div>
        {filtered.map(a => (
          <div key={a.id} className={`ccc-row ${selected.has(a.id) ? 'sel' : ''}`}>
            <div className="c chk">
              <input type="checkbox" checked={selected.has(a.id)} onChange={() => toggle(a.id)}/>
            </div>
            <div className="c name">
              <span className="ccc-acct-name">{a.name}</span>
              <span className="mono faint" style={{fontSize: 10}}>{a.handle}</span>
            </div>
            <div className="c"><StatusPill status={a.status}/></div>
            <div className="c"><HealthBar v={a.health}/></div>
            <div className="c mono dim" style={{fontSize: 11}}>{a.proxy}</div>
            <div className="c mono" style={{fontSize: 11, color: 'var(--text-dim)'}}>{a.warmupStage}</div>
            <div className="c mono tnum" style={{fontSize: 12, color: a.queueDepth > 0 ? 'var(--text)' : 'var(--text-faint)'}}>{a.queueDepth}</div>
            <div className="c mono faint" style={{fontSize: 10.5, letterSpacing: '0.04em'}}>{a.lastAction}</div>
            <div className="c mono" style={{fontSize: 10.5, color: 'var(--cyan)', letterSpacing: '0.04em'}}>{a.nextAction}</div>
            <div className="c actions">
              {a.status === 'paused' || a.status === 'error'
                ? <button className="ccc-iconbtn" title="Resume" onClick={() => single('Resumed', a)}><Icon.Play style={{width: 12, height: 12}}/></button>
                : <button className="ccc-iconbtn" title="Pause" onClick={() => single('Paused', a)}><Icon.Pause style={{width: 12, height: 12}}/></button>
              }
              <button className="ccc-iconbtn" title="Compose" data-handled="1" onClick={() => window.runAction('compose', { to: a.handle || a.name })}><Icon.Plus style={{width: 12, height: 12}}/></button>
              <button className="ccc-iconbtn" title="Rotate proxy" data-handled="1" onClick={() => window.runAction('testConnection', { name: a.name || channel.name })}><Icon.Refresh style={{width: 12, height: 12}}/></button>
              <button className="ccc-iconbtn" title="View logs" data-handled="1" onClick={() => window.runAction('viewLogs', { source: `${channel.name} · ${a.handle || a.name}` })}><Icon.Book style={{width: 12, height: 12}}/></button>
              <button className="ccc-iconbtn" title="More" onClick={() => single('Menu opened for', a)}><Icon.More style={{width: 12, height: 12}}/></button>
            </div>
          </div>
        ))}
        {filtered.length === 0 && (
          <div style={{padding: 32, textAlign: 'center', color: 'var(--text-faint)', fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.14em', textTransform: 'uppercase'}}>
            No accounts match this filter
          </div>
        )}
      </div>
    </div>
  );
}

// ===================== SETTINGS TAB =====================
function SettingsTab({ channel, onPushToast }) {
  const [freq, setFreq] = React.useState(4);
  const [daily, setDaily] = React.useState(20);
  const [autopilot, setAutopilot] = React.useState(true);
  const [approval, setApproval] = React.useState(false);
  const [risk, setRisk] = React.useState('conservative');
  const [types, setTypes] = React.useState({ text: true, image: true, video: true, story: false, livestream: false });
  const [fallback, setFallback] = React.useState('hold');

  const toggleType = (k) => setTypes(t => ({...t, [k]: !t[k]}));
  const save = () => onPushToast(`Settings saved for ${channel.name}`);

  return (
    <div className="ccc-settings">
      <div className="ccc-setting-card">
        <div className="ccc-setting-hd">Cadence</div>
        <div className="ccc-setting-row">
          <div>
            <div className="ccc-setting-lbl">Posting frequency</div>
            <div className="ccc-setting-sub">posts per account per day</div>
          </div>
          <div className="ccc-setting-ctrl">
            <input type="range" min="1" max="12" value={freq} onChange={e => setFreq(+e.target.value)} className="ccc-slider"/>
            <span className="mono" style={{minWidth: 28, textAlign: 'right'}}>{freq}</span>
          </div>
        </div>
        <div className="ccc-setting-row">
          <div>
            <div className="ccc-setting-lbl">Daily limit · workspace</div>
            <div className="ccc-setting-sub">hard ceiling across all accounts</div>
          </div>
          <div className="ccc-setting-ctrl">
            <input type="range" min="5" max="100" value={daily} onChange={e => setDaily(+e.target.value)} className="ccc-slider"/>
            <span className="mono" style={{minWidth: 28, textAlign: 'right'}}>{daily}</span>
          </div>
        </div>
      </div>

      <div className="ccc-setting-card">
        <div className="ccc-setting-hd">Content permissions</div>
        <div className="ccc-types">
          {[['text', 'Text'], ['image', 'Image'], ['video', 'Video'], ['story', 'Story / Reel'], ['livestream', 'Livestream']].map(([k, l]) => (
            <button key={k} className={`ccc-type ${types[k] ? 'on' : ''}`} onClick={() => toggleType(k)}>
              <span className="ccc-type-check">{types[k] ? '●' : '○'}</span> {l}
            </button>
          ))}
        </div>
      </div>

      <div className="ccc-setting-card">
        <div className="ccc-setting-hd">Autonomy</div>
        <div className="ccc-setting-row toggle">
          <div>
            <div className="ccc-setting-lbl">AI Autopilot</div>
            <div className="ccc-setting-sub">Calliope schedules and ships without human input</div>
          </div>
          <button className={`ccc-toggle ${autopilot ? 'on' : ''}`} onClick={() => setAutopilot(a => !a)}>
            <span className="ccc-toggle-knob"/>
          </button>
        </div>
        <div className="ccc-setting-row toggle">
          <div>
            <div className="ccc-setting-lbl">Approval required</div>
            <div className="ccc-setting-sub">Hold every post for human sign-off before publishing</div>
          </div>
          <button className={`ccc-toggle ${approval ? 'on' : ''}`} onClick={() => setApproval(a => !a)}>
            <span className="ccc-toggle-knob"/>
          </button>
        </div>
        <div className="ccc-setting-row">
          <div>
            <div className="ccc-setting-lbl">Risk posture</div>
            <div className="ccc-setting-sub">how aggressively to operate at platform edges</div>
          </div>
          <div className="ccc-setting-ctrl">
            <div className="segmented">
              {['conservative', 'balanced', 'aggressive'].map(k => (
                <button key={k} className={risk === k ? 'active' : ''} onClick={() => setRisk(k)}>{k}</button>
              ))}
            </div>
          </div>
        </div>
        <div className="ccc-setting-row">
          <div>
            <div className="ccc-setting-lbl">Fallback on platform error</div>
            <div className="ccc-setting-sub">how to recover when an action fails</div>
          </div>
          <div className="ccc-setting-ctrl">
            <div className="segmented">
              {[['hold', 'Hold'], ['retry', 'Retry'], ['reroute', 'Reroute']].map(([k, l]) => (
                <button key={k} className={fallback === k ? 'active' : ''} onClick={() => setFallback(k)}>{l}</button>
              ))}
            </div>
          </div>
        </div>
      </div>

      <div style={{display: 'flex', justifyContent: 'flex-end', gap: 8, paddingTop: 8}}>
        <button className="btn ghost">Discard</button>
        <button className="btn primary" onClick={save}>Save settings</button>
      </div>
    </div>
  );
}

// ===================== COMPOSE TAB =====================
function ComposeTab({ channel, onPushToast }) {
  const [mode, setMode] = React.useState('text');
  const [prompt, setPrompt] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const [result, setResult] = React.useState(null);

  const platformHint = {
    tiktok:    { text: '15s hook · vertical · trending sound · payoff', img: 'cover · 9:16 · brand palette' },
    instagram: { text: 'Reel caption · 6 hooks · 280 char', img: 'carousel · 5 slides · brand' },
    youtube:   { text: 'Shorts hook + title + description', img: 'thumbnail · 1280×720 · high-contrast' },
    facebook:  { text: 'Post · 80 char hook + 200 char body', img: 'square · brand · local audience' },
    linkedin:  { text: 'Founder voice · 1100 char · 1 PoV per para', img: 'square · text-light · brand' },
    x:         { text: 'Thread · 7 tweets · hook then payoff', img: 'card · 1200×675 · brand' },
    threads:   { text: 'Thread · conversational · 500 char', img: 'square · brand' },
    bluesky:   { text: 'Post · 300 char · open-web tone', img: 'square · brand' },
    pinterest: { text: 'Pin title + 500 char description + alt-text', img: 'vertical · 1000×1500 · pin-ready' },
    telegram:  { text: 'Channel broadcast · 600 char + CTA', img: '— skip · text channel' },
    whatsapp:  { text: 'Broadcast · 200 char · 1 CTA · personalized', img: 'square · brand · WA Business' },
    onlyfans:  { text: 'Caption · creator voice · 280 char · paywall hook', img: '— creator-managed media' },
    fanvue:    { text: 'Caption · creator voice · 280 char · paywall hook', img: '— creator-managed media' }
  };
  const hint = platformHint[channel.id] || platformHint.instagram;

  const generate = async () => {
    if (!prompt.trim()) return;
    setBusy(true);
    setResult(null);
    try {
      const text = await window.claude.complete({
        messages: [{
          role: 'user',
          content: `You are Calliope, the Demiurge content operator. Write 3 variants for ${channel.name}, optimized for that platform's conventions. Brief: "${prompt}". Output: 3 numbered variants, each labeled with intended hook angle. No preamble.`
        }]
      });
      setResult(text);
    } catch (e) {
      setResult(`1. ★ Hook · curiosity\nNetwork unavailable in preview. Live deployment streams variants in <2s through redundant model gateways.\n\n2. ★ Hook · social proof\nDemo offline. Real Calliope ships native to ${channel.name} with platform-conventions baked in.\n\n3. ★ Hook · contrarian\nGenerator running in sandbox mode. Production output adapts to brand voice + posting history.`);
    }
    setBusy(false);
  };

  const schedule = () => onPushToast(`Scheduled to ${channel.name} · queued behind 8 posts`);

  return (
    <div className="ccc-compose">
      <div className="ccc-compose-l">
        <div className="ccc-compose-card">
          <div className="ccc-setting-hd" style={{borderBottom: 'none', paddingBottom: 0}}>Compose for {channel.name}</div>
          <div className="segmented">
            {[['text', 'Text'], ['image', 'Image'], ['video', 'Video'], ['avatar', 'Avatar / clone'], ['campaign', 'Campaign']].map(([k, l]) => (
              <button key={k} className={mode === k ? 'active' : ''} onClick={() => setMode(k)}>{l}</button>
            ))}
          </div>
          <div className="ccc-compose-prompt">
            <span className="mono" style={{fontSize: 10, color: 'var(--text-faint)', letterSpacing: '0.14em', textTransform: 'uppercase'}}>
              Hint · {mode === 'image' ? hint.img : hint.text}
            </span>
            <textarea
              rows={3}
              value={prompt}
              onChange={e => setPrompt(e.target.value)}
              placeholder={`Brief Calliope for ${channel.name} (${mode})…`}
              style={{
                width: '100%',
                fontFamily: 'var(--font-mono)',
                fontSize: 13,
                lineHeight: 1.5,
                color: 'var(--text)',
                background: 'transparent',
                resize: 'vertical',
                minHeight: 80
              }}
            />
            <div style={{display: 'flex', gap: 8, alignItems: 'center'}}>
              <span className="mono faint" style={{fontSize: 10, letterSpacing: '0.1em', textTransform: 'uppercase'}}>
                Targeting {channel.name} · {mode}
              </span>
              <span style={{flex: 1}}/>
              <button className="btn sm">Attach brief</button>
              <button className="btn primary sm" onClick={generate} disabled={busy}>
                <Icon.Sparkles className="icon"/>
                {busy ? 'Generating…' : `Generate ${mode}`}
              </button>
            </div>
          </div>
        </div>
        {result && (
          <div className="ccc-compose-result">
            <div className="ccc-setting-hd">Variants</div>
            <pre>{result}</pre>
            <div style={{display: 'flex', gap: 8, justifyContent: 'flex-end'}}>
              <button className="btn sm">Regenerate</button>
              <button className="btn primary sm" onClick={schedule}>Schedule to {channel.name}</button>
            </div>
          </div>
        )}
        {(mode === 'video' || mode === 'avatar') && (
          <div className="ccc-compose-note">
            <span style={{color: 'var(--warn)'}}>● </span>
            {mode === 'video'
              ? 'Video synthesis runs on the add-on tier. Brief generates storyboard + voiceover script you can hand to your editor or render directly.'
              : 'Avatar / clone requires creator-explicit consent on file. Voice clones expire after 90 days unless renewed.'}
          </div>
        )}
      </div>
      <div className="ccc-compose-r">
        <div className="ccc-setting-hd">Posting queue</div>
        <div className="ccc-queue">
          {[
            { t: 'in 12m',  k: 'video',  d: 'Belmont · "before/after" carousel' },
            { t: 'in 48m',  k: 'image',  d: 'Iyer · Q2 case study graphic' },
            { t: 'in 2h',   k: 'text',   d: 'Founder POV · "why we replatformed"' },
            { t: 'in 4h',   k: 'video',  d: 'Anya Patel · patient testimonial 30s' },
            { t: 'tomorrow', k: 'text',   d: 'Recap · 5 lessons from cohort 014' }
          ].map((q, i) => (
            <div key={i} className="ccc-queue-row">
              <div style={{display: 'flex', flexDirection: 'column', minWidth: 0, flex: 1}}>
                <span style={{fontSize: 12.5, color: 'var(--text)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}>{q.d}</span>
                <span className="mono faint" style={{fontSize: 10, letterSpacing: '0.1em', textTransform: 'uppercase', marginTop: 2}}>{q.k} · {q.t}</span>
              </div>
              <button className="ccc-iconbtn" title="Edit"><Icon.Plus style={{width: 12, height: 12, transform: 'rotate(45deg)'}}/></button>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// ===================== WORKFLOWS TAB =====================
function WorkflowsTab({ channel, onPushToast }) {
  const WORKFLOWS = [
    { id: 'broadcast',    name: 'Broadcast posting',    desc: 'AI-generated content shipped daily at optimal times', active: true,  runs: 412, success: 96 },
    { id: 'dm',           name: 'DM response',          desc: 'Hermes triages inbound DMs in <30s with intent routing', active: true,  runs: 1840, success: 94 },
    { id: 'comment',      name: 'Comment reply',        desc: 'Iris reads every comment, replies, escalates concerns', active: true,  runs: 6240, success: 98 },
    { id: 'leadcapture',  name: 'Lead capture',         desc: 'High-intent profile visitors enriched and pushed to CRM', active: true,  runs: 84,   success: 88 },
    { id: 'review',       name: 'Review request',       desc: 'Post-purchase customers nudged for review on schedule', active: false, runs: 0,    success: 0  },
    { id: 'retarget',     name: 'Retargeting',          desc: 'Engaged-but-unconverted audiences synced to ad platforms', active: true,  runs: 312, success: 92 },
    { id: 'reactivation', name: 'Reactivation',         desc: 'Lapsed accounts nudged with personalized re-engagement', active: false, runs: 0,    success: 0  }
  ];
  const [states, setStates] = React.useState(() => Object.fromEntries(WORKFLOWS.map(w => [w.id, w.active])));
  const toggle = (id) => {
    setStates(s => {
      const next = {...s, [id]: !s[id]};
      onPushToast(`${next[id] ? 'Activated' : 'Paused'} · ${WORKFLOWS.find(w => w.id === id).name}`);
      return next;
    });
  };

  return (
    <div className="ccc-flows">
      <div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '0 4px 14px'}}>
        <span className="mono faint" style={{fontSize: 10.5, letterSpacing: '0.16em', textTransform: 'uppercase'}}>
          {Object.values(states).filter(Boolean).length} of {WORKFLOWS.length} workflows live
        </span>
        <button className="btn sm"><Icon.Plus className="icon"/>Attach workflow</button>
      </div>
      <div className="ccc-flow-grid">
        {WORKFLOWS.map(w => (
          <div key={w.id} className={`ccc-flow-card ${states[w.id] ? 'on' : ''}`}>
            <div className="ccc-flow-hd">
              <Icon.Flow style={{width: 14, height: 14, color: states[w.id] ? 'var(--cyan)' : 'var(--text-faint)'}}/>
              <span style={{flex: 1, color: 'var(--text)', fontSize: 13.5}}>{w.name}</span>
              <button className={`ccc-toggle ${states[w.id] ? 'on' : ''}`} onClick={() => toggle(w.id)}>
                <span className="ccc-toggle-knob"/>
              </button>
            </div>
            <div className="ccc-flow-desc">{w.desc}</div>
            <div className="ccc-flow-stats">
              <div>
                <div className="mono faint" style={{fontSize: 9.5, letterSpacing: '0.14em', textTransform: 'uppercase'}}>Runs / 7d</div>
                <div className="mono" style={{fontSize: 16, marginTop: 4, color: states[w.id] ? 'var(--text)' : 'var(--text-faint)'}}>{w.runs.toLocaleString()}</div>
              </div>
              <div>
                <div className="mono faint" style={{fontSize: 9.5, letterSpacing: '0.14em', textTransform: 'uppercase'}}>Success</div>
                <div className="mono" style={{fontSize: 16, marginTop: 4, color: w.success >= 95 ? 'var(--good)' : w.success >= 85 ? 'var(--cyan)' : 'var(--text-faint)'}}>
                  {states[w.id] ? `${w.success}%` : '—'}
                </div>
              </div>
              <button className="btn ghost sm">Configure</button>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ===================== LOGS TAB =====================
function LogsTab({ channel, accounts }) {
  const [filter, setFilter] = React.useState('all');
  const seed = channel.id.charCodeAt(0);
  const events = React.useMemo(() => {
    const types = [
      { k: 'posted',     icon: '✓', color: 'var(--cyan)',   label: 'posted',     verbs: ['Content shipped to', 'Published on', 'Story posted from'] },
      { k: 'scheduled',  icon: '◷', color: 'var(--text-dim)', label: 'scheduled', verbs: ['Queued for', 'Scheduled at 14:32 GMT for', 'Composed and queued for'] },
      { k: 'failed',     icon: '✕', color: 'var(--danger)', label: 'failed',     verbs: ['Auth refused for', 'Rate-limited on', 'Network error from'] },
      { k: 'retried',    icon: '↻', color: 'var(--warn)',   label: 'retried',    verbs: ['Retry · attempt 2 for', 'Backoff retry for', 'Auto-retry for'] },
      { k: 'proxy',      icon: '⇄', color: 'var(--violet)', label: 'proxy_rotated', verbs: ['Proxy rotated for', 'IP refreshed for', 'New residential IP for'] },
      { k: 'warmed',     icon: '◐', color: 'var(--warn)',   label: 'warmed',     verbs: ['Warmup tick for', 'Activity curve advanced for', 'Day +1 for'] },
      { k: 'approval',   icon: '⊕', color: 'var(--cyan)',   label: 'approval_request', verbs: ['Approval requested for', 'Held for human review for', 'Awaiting sign-off on'] }
    ];
    const ev = [];
    let t = 0;
    for (let i = 0; i < 32; i++) {
      const tIdx = (seed + i * 7) % types.length;
      const type = types[tIdx];
      const acct = accounts[(i + seed) % accounts.length];
      const min = (i + seed) % 60;
      const hr = Math.floor((i + seed * 3) / 6) % 24;
      const verb = type.verbs[i % type.verbs.length];
      t = t + Math.max(1, Math.floor(Math.random() * 8));
      ev.push({
        time: `${String(hr).padStart(2, '0')}:${String(min).padStart(2, '0')}:${String((i * 11) % 60).padStart(2, '0')}`,
        type: type,
        msg: `${verb} ${acct ? acct.name : 'workspace'}`,
        acct: acct ? acct.handle : '—',
        elapsed: t
      });
    }
    return ev;
  }, [channel.id, accounts, seed]);

  const filtered = filter === 'all' ? events : events.filter(e => e.type.k === filter);

  return (
    <div>
      <div style={{display: 'flex', alignItems: 'center', gap: 10, padding: '0 4px 14px', flexWrap: 'wrap'}}>
        {[['all', 'All'], ['posted', 'Posted'], ['scheduled', 'Scheduled'], ['failed', 'Failed'], ['retried', 'Retried'], ['proxy', 'Proxy'], ['warmed', 'Warmup'], ['approval', 'Approval']].map(([k, l]) => (
          <button key={k} onClick={() => setFilter(k)} className={`ccc-pill ${filter === k ? 'on' : ''}`}>{l}</button>
        ))}
        <span style={{flex: 1}}/>
        <span className="mono faint" style={{fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase'}}>
          Streaming · {filtered.length} events · last 24h
        </span>
      </div>
      <div className="ccc-logs">
        {filtered.map((e, i) => (
          <div key={i} className="ccc-log-row">
            <span className="mono faint" style={{fontSize: 10.5, color: 'var(--text-faint)', minWidth: 64}}>{e.time}</span>
            <span style={{
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              width: 18, height: 18, borderRadius: 3,
              background: `${e.type.color}15`,
              color: e.type.color,
              fontSize: 10,
              border: `1px solid ${e.type.color}40`
            }}>{e.type.icon}</span>
            <span className="mono" style={{fontSize: 10, color: e.type.color, letterSpacing: '0.12em', textTransform: 'uppercase', minWidth: 100}}>{e.type.label}</span>
            <span style={{fontSize: 12.5, color: 'var(--text)', flex: 1, minWidth: 0, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}>{e.msg}</span>
            <span className="mono faint" style={{fontSize: 10}}>{e.acct}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

// ===================== MAIN CONTROL CENTER =====================
function ChannelControlCenter({ channel, onBack }) {
  const [tab, setTab] = React.useState('accounts');
  const [toast, setToast] = React.useState(null);
  const accounts = React.useMemo(() => buildAccounts(channel.id, channel.group), [channel.id, channel.group]);

  const pushToast = (msg) => {
    setToast({ msg, id: Date.now() });
    setTimeout(() => setToast(t => (t && t.msg === msg ? null : t)), 2400);
  };

  // Aggregate stats
  const totals = accounts.reduce((s, a) => {
    s.total++;
    s[a.status] = (s[a.status] || 0) + 1;
    s.queued += a.queueDepth;
    return s;
  }, {total: 0, queued: 0});

  const tabs = [
    ['accounts',  'Accounts',  `${totals.total}`],
    ['settings',  'Settings',  null],
    ['compose',   'Compose',   null],
    ['workflows', 'Workflows', null],
    ['logs',      'Logs',      null]
  ];

  return (
    <div className="ccc-shell">
      {/* Header */}
      <div className="ccc-hd">
        <button className="ccc-back" onClick={onBack}>
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M19 12H5M11 18l-6-6 6-6"/></svg>
          <span>Channels</span>
        </button>
        <div className="ccc-hd-glyph" style={{color: channel.tone}}>
          <ConsoleChannelGlyph kind={channel.id} size={40}/>
        </div>
        <div className="ccc-hd-info">
          <div className="ccc-hd-title"><em>{channel.name}</em> control center</div>
          <div className="ccc-hd-sub">
            {channel.group === 'broadcast' ? 'Broadcast posting' : channel.group === 'bot' ? 'Messaging bot' : 'Creator session-based'}
            {' · '}{totals.total} accounts · {totals.queued} queued actions
          </div>
        </div>
        <div className="ccc-hd-actions">
          <button className="btn sm" data-handled="1" onClick={() => window.runAction('connect', { name: channel.name })}><Icon.Plus className="icon"/>Add account</button>
          <button className="btn primary sm" data-handled="1" onClick={() => window.runAction('createContent')}>
            <Icon.Sparkles className="icon"/>Compose with AI
          </button>
        </div>
      </div>

      {/* Aggregate stat strip */}
      <div className="ccc-stats">
        {[
          { lbl: 'Total accounts', v: totals.total, color: 'var(--text)' },
          { lbl: 'Active',         v: (totals.live || 0) + (totals.session || 0), color: 'var(--cyan)' },
          { lbl: 'Warming',        v: totals.warming || 0, color: 'var(--warn)' },
          { lbl: 'Paused',         v: totals.paused || 0, color: 'var(--text-dim)' },
          { lbl: 'Errors',         v: totals.error || 0, color: 'var(--danger)' },
          { lbl: 'Scheduled',      v: channel.scheduled, color: 'var(--violet)' },
          { lbl: 'Published 24h',  v: Math.round(channel.scheduled * 1.6), color: 'var(--text)' },
          { lbl: 'Reach 24h',      v: channel.reach24h, color: 'var(--text)' },
          { lbl: 'Engagement',     v: channel.eng, color: 'var(--cyan)' }
        ].map((s, i) => (
          <div key={i} className="ccc-stat">
            <div className="lbl">{s.lbl}</div>
            <div className="val" style={{color: s.color}}>{s.v}</div>
          </div>
        ))}
      </div>

      {/* Tabs */}
      <div className="ccc-tabs">
        {tabs.map(([k, l, badge]) => (
          <button key={k} className={`ccc-tab ${tab === k ? 'on' : ''}`} onClick={() => setTab(k)}>
            {l} {badge ? <span className="ccc-tab-badge">{badge}</span> : null}
          </button>
        ))}
        <div style={{flex: 1, borderBottom: '1px solid var(--border)'}}/>
      </div>

      {/* Tab body */}
      <div className="ccc-body">
        {tab === 'accounts'  && <AccountsTab  channel={channel} accounts={accounts} onPushToast={pushToast}/>}
        {tab === 'settings'  && <SettingsTab  channel={channel} onPushToast={pushToast}/>}
        {tab === 'compose'   && <ComposeTab   channel={channel} onPushToast={pushToast}/>}
        {tab === 'workflows' && <WorkflowsTab channel={channel} onPushToast={pushToast}/>}
        {tab === 'logs'      && <LogsTab      channel={channel} accounts={accounts}/>}
      </div>

      {/* Inline toast for action feedback */}
      {toast && (
        <div className="ccc-toast" key={toast.id}>
          <span className="pip" style={{background: 'var(--cyan)', boxShadow: '0 0 6px var(--cyan)'}}/>
          {toast.msg}
        </div>
      )}
    </div>
  );
}

// Expose for channels.jsx
window.ChannelControlCenter = ChannelControlCenter;
