/* screens-channels.jsx — 桌面端「设置 → 消息渠道」交互稿
 * 视觉对齐 officev3 桌面端 SettingModal（Tailwind + Shadcn）：
 *   - 外壳 880×620 / 16px 圆角 / 纯白底 / 50% 黑遮罩
 *   - 左导航 #F7F7F7 / 选中态紫色 #8E6BF2
 *   - 卡片 rounded-2xl + 1px 边框 + 16px 内边距
 *   - 主按钮紫底白字 / 次按钮白底灰边 / 危险红
 *   - 字体沿用项目 Inter + PingFang SC
 * 飞书图标取自 officev3/public/onboarding/feishu_2x.png
 * 微信图标采用经典「双气泡」微信 Logo（区别于微信支付的单气泡）
 */
/* global React */

const C = {
  brand: '#8E6BF2',
  brandSoft: '#F3EFFD',
  ok: '#56D9B6',
  okSoft: 'rgba(86,217,182,0.16)',
  danger: '#FF4F61',
  ink: '#0A0A06',
  ink2: '#333329',
  ink3: '#57574A',
  mute: '#808080',
  border: '#ECECEC',
  borderSoft: '#F2F2F0',
  navBg: '#F7F7F7',
  panel: '#FFFFFF',
  font: '"Inter","PingFang SC",-apple-system,BlinkMacSystemFont,system-ui,sans-serif',
};

/* ---------- 品牌 / 通用 icon ---------- */
function FeishuIcon({ size = 40 }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: 12, overflow: 'hidden',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      background: '#fff', boxShadow: '0 0 0 1px rgba(0,0,0,0.04)',
    }}>
      <img src="assets/feishu.png" alt="飞书" style={{ width: '88%', height: '88%', objectFit: 'contain' }} />
    </div>
  );
}
function WechatIcon({ size = 40 }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: 12,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      background: '#E7FBEF',
    }}>
      <svg width={size * 0.62} height={size * 0.62} viewBox="0 0 24 24" fill="#07C160" xmlns="http://www.w3.org/2000/svg">
        <path d="M9.5 4C5.36 4 2 6.91 2 10.5c0 2.02 1.07 3.82 2.74 5.01.2.14.32.36.32.6 0 .08-.02.16-.04.23l-.39 1.45c-.02.07-.05.15-.05.22 0 .16.12.29.28.29.06 0 .12-.02.18-.05l1.9-1.1c.14-.08.3-.13.46-.13.09 0 .17.01.25.04.84.24 1.74.37 2.85.37.18 0 .36 0 .54-.02-.12-.39-.18-.81-.18-1.23 0-3.13 3.02-5.67 6.75-5.67.18 0 .35.01.52.02C17.62 6.62 13.95 4 9.5 4zM7 9.25a1 1 0 110-2 1 1 0 010 2zm5 0a1 1 0 110-2 1 1 0 010 2z"/>
        <path d="M22 14.83c0-2.86-2.77-5.18-6.18-5.18s-6.18 2.32-6.18 5.18 2.77 5.18 6.18 5.18c.79 0 1.55-.12 2.25-.34a.7.7 0 01.21-.03c.13 0 .26.04.38.11l1.36.78c.04.03.09.04.13.04.13 0 .23-.1.23-.23 0-.06-.02-.11-.04-.17l-.28-1.05a.62.62 0 01-.03-.18c0-.19.09-.36.25-.48 1.31-.96 2.12-2.4 2.12-3.95zm-8.13-.81a.83.83 0 110-1.66.83.83 0 010 1.66zm4.13 0a.83.83 0 110-1.66.83.83 0 010 1.66z"/>
      </svg>
    </div>
  );
}
function RaccoonChannelIcon({ size = 40 }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: 12,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      background: C.brandSoft,
    }}>
      <img src="assets/office-raccoon-logo.svg" alt="移动端" style={{ width: '70%', height: '70%' }} />
    </div>
  );
}
function MiniAppIcon({ size = 20 }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: 5,
      background: 'linear-gradient(135deg,#8E6BF2,#6D4FD6)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      color: '#fff', fontSize: 11, fontWeight: 700, letterSpacing: -0.4,
    }}>浣</div>
  );
}

/* ---------- 通用控件 ---------- */
function Badge({ kind = 'gray', children }) {
  const map = {
    gray: { bg: '#F2F2F0', fg: C.ink2 },
    green: { bg: C.okSoft, fg: '#1E9C7E' },
    red: { bg: 'rgba(255,79,97,0.12)', fg: C.danger },
    mute: { bg: '#F2F2F0', fg: C.mute },
  };
  const s = map[kind];
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      background: s.bg, color: s.fg,
      padding: '2px 8px', borderRadius: 999,
      fontSize: 12, fontWeight: 500, lineHeight: 1.5,
      whiteSpace: 'nowrap',
    }}>
      {kind === 'green' && <span style={{ width: 6, height: 6, borderRadius: 3, background: '#1E9C7E' }} />}
      {children}
    </span>
  );
}
function Btn({ kind = 'secondary', children, disabled, loading, w }) {
  const base = {
    height: 32, padding: '0 14px', borderRadius: 6,
    fontSize: 13, fontWeight: 500, lineHeight: 1,
    fontFamily: 'inherit',
    cursor: disabled ? 'not-allowed' : 'pointer',
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
    border: '1px solid transparent', whiteSpace: 'nowrap',
    width: w,
    opacity: disabled ? 0.5 : 1,
    transition: 'all .12s',
  };
  const styles = {
    primary: { background: C.brand, color: '#fff' },
    secondary: { background: '#fff', color: C.ink2, borderColor: '#E6E6E6' },
    ghost: { background: 'transparent', color: C.ink3 },
    danger: { background: C.danger, color: '#fff' },
    dangerGhost: { background: '#fff', color: C.danger, borderColor: 'rgba(255,79,97,0.3)' },
  };
  return <button style={{ ...base, ...styles[kind] }}>{loading ? '注册中…' : children}</button>;
}
function Input({ value, placeholder, type = 'text' }) {
  return (
    <div style={{
      height: 34, border: `1px solid ${C.border}`, borderRadius: 6,
      padding: '0 12px', display: 'flex', alignItems: 'center',
      fontSize: 13, color: value ? C.ink2 : '#B5B5AE', background: '#fff',
      fontFamily: 'inherit',
    }}>
      {value ? (type === 'password' ? '•'.repeat(20) : value) : placeholder}
    </div>
  );
}

/* ---------- 设置 Modal 左导航 · 真实图标（来源：officev3/public/svgs/setting） ---------- */
function NavIcon({ kind, active }) {
  const stroke = active ? '#8E6BF2' : '#57574A';
  const accent = active ? '#8E6BF2' : stroke;
  const common = { width: 16, height: 16, viewBox: '0 0 20 20', fill: 'none', xmlns: 'http://www.w3.org/2000/svg' };
  if (kind === 'account') return (
    <svg {...common}>
      <path fillRule="evenodd" clipRule="evenodd" d="M10.6139 14.2308L10.3865 14.8863C10.3125 15.0997 10.0795 15.2127 9.86615 15.1386C9.74785 15.0976 9.65488 15.0046 9.61384 14.8863L9.38643 14.2308C9.28607 13.9415 9.0587 13.7141 8.7694 13.6137L8.11384 13.3863C7.90048 13.3123 7.78751 13.0793 7.86153 12.866C7.90257 12.7477 7.99554 12.6547 8.11384 12.6137L8.7694 12.3863C9.0587 12.2859 9.28607 12.0585 9.38643 11.7692L9.61384 11.1137C9.68786 10.9003 9.92082 10.7873 10.1342 10.8614C10.2525 10.9024 10.3455 10.9954 10.3865 11.1137L10.6139 11.7692C10.7143 12.0585 10.9416 12.2859 11.2309 12.3863L11.8865 12.6137C12.0999 12.6877 12.2128 12.9207 12.1388 13.134C12.0978 13.2523 12.0048 13.3453 11.8865 13.3863L11.2309 13.6137C10.9416 13.7141 10.7143 13.9415 10.6139 14.2308Z" fill={accent} />
      <path fillRule="evenodd" clipRule="evenodd" d="M9.99999 2C12.7614 2 15 4.23858 15 7C15 8.44094 14.3905 9.73951 13.4152 10.6519C14.6736 11.3403 15.6334 12.5336 16 14L16.6894 16.7575C16.8233 17.2933 16.4975 17.8362 15.9617 17.9701C15.8824 17.99 15.801 18 15.7192 18H4.28076C3.72848 18 3.28076 17.5523 3.28076 17C3.28076 16.9182 3.29079 16.8368 3.31062 16.7575L3.99999 14C4.36658 12.5336 5.32633 11.3403 6.58472 10.6499C5.60952 9.73951 4.99999 8.44094 4.99999 7C4.99999 4.23858 7.23856 2 9.99999 2Z" stroke={stroke} strokeLinejoin="round" />
    </svg>
  );
  if (kind === 'shortcut') return (
    <svg {...common}>
      <path fillRule="evenodd" clipRule="evenodd" d="M10.6134 8.23077L10.386 8.88633C10.312 9.09969 10.079 9.21266 9.86567 9.13864C9.74737 9.0976 9.65439 9.00463 9.61335 8.88633L9.38594 8.23077C9.28558 7.94147 9.05821 7.7141 8.76891 7.61374L8.11335 7.38633C7.89999 7.31231 7.78702 7.07935 7.86104 6.86598C7.90208 6.74768 7.99505 6.65471 8.11335 6.61367L8.76891 6.38626C9.05821 6.2859 9.28558 6.05853 9.38594 5.76923L9.61335 5.11367C9.68737 4.90031 9.92033 4.78734 10.1337 4.86136C10.252 4.9024 10.345 4.99537 10.386 5.11367L10.6134 5.76923C10.7138 6.05853 10.9412 6.2859 11.2305 6.38626L11.886 6.61367C12.0994 6.68769 12.2123 6.92065 12.1383 7.13402C12.0973 7.25232 12.0043 7.34529 11.886 7.38633L11.2305 7.61374C10.9412 7.7141 10.7138 7.94147 10.6134 8.23077Z" fill={accent} />
      <path fillRule="evenodd" clipRule="evenodd" d="M3.5 5.5V9.5C3.5 11.1569 4.84315 12.5 6.5 12.5H13.5C15.1569 12.5 16.5 11.1569 16.5 9.5V5.5C16.5 3.84315 15.1569 2.5 13.5 2.5H6.5C4.84315 2.5 3.5 3.84315 3.5 5.5Z" stroke={stroke} strokeLinejoin="round" />
      <path d="M3.49952 6.5L2.6978 15.3189C2.59779 16.419 3.40848 17.3918 4.50851 17.4918C4.56871 17.4973 4.62913 17.5 4.68958 17.5H15.3095C16.414 17.5 17.3095 16.6046 17.3095 15.5C17.3095 15.4395 17.3067 15.3791 17.3012 15.3189L16.4995 6.5" stroke={stroke} strokeLinejoin="round" />
    </svg>
  );
  if (kind === 'guide') return (
    <svg {...common}>
      <path d="M4.25 4.5C4.25 3.67157 4.92157 3 5.75 3H14.25C15.0784 3 15.75 3.67157 15.75 4.5V15.5C15.75 16.3284 15.0784 17 14.25 17H5.75C4.92157 17 4.25 16.3284 4.25 15.5V4.5Z" stroke={stroke} strokeLinejoin="round" />
      <path d="M7 7H13" stroke={stroke} strokeLinecap="round" />
      <path d="M7 10H11.5" stroke={stroke} strokeLinecap="round" />
      <path d="M7 13H9.5" stroke={stroke} strokeLinecap="round" />
      <path d="M13.75 12.25L14.25 13.25L15.25 13.75L14.25 14.25L13.75 15.25L13.25 14.25L12.25 13.75L13.25 13.25L13.75 12.25Z" fill={accent} />
    </svg>
  );
  if (kind === 'plugin') return (
    <svg {...common}>
      <path d="M3 6C3 4.89543 3.89543 4 5 4H15C16.1046 4 17 4.89543 17 6V14C17 15.1046 16.1046 16 15 16H5C3.89543 16 3 15.1046 3 14V6Z" stroke={stroke} strokeLinejoin="round" />
      <path d="M3.5 7.25H16.5" stroke={stroke} strokeLinecap="round" />
      <path d="M5.75 5.75H5.8" stroke={stroke} strokeLinecap="round" />
      <path d="M7.75 5.75H7.8" stroke={stroke} strokeLinecap="round" />
      <path d="M10.5 10.25L12.25 12L15 9.25" stroke={accent} strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
  if (kind === 'storage') return (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke={stroke} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" xmlns="http://www.w3.org/2000/svg">
      <line x1="22" x2="2" y1="12" y2="12" />
      <path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z" />
      <line x1="6" x2="6.01" y1="16" y2="16" />
      <line x1="10" x2="10.01" y1="16" y2="16" />
    </svg>
  );
  if (kind === 'channels') return (
    /* Lucide Database：沿用桌面端「连接数据源」入口图标 */
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke={stroke} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" xmlns="http://www.w3.org/2000/svg">
      <ellipse cx="12" cy="5" rx="9" ry="3" />
      <path d="M3 5v14a9 3 0 0 0 18 0V5" />
      <path d="M3 12a9 3 0 0 0 18 0" />
    </svg>
  );
  if (kind === 'about') return (
    <svg {...common}>
      <path fillRule="evenodd" clipRule="evenodd" d="M15 3.00052C16.4545 2.66667 16.7558 3.84251 16.7917 4.14112C16.8619 4.9575 16.6573 6.83963 16.3007 7.79064L16.2823 7.77909C17.7608 10.26 18.5 12.0005 18.5 13.0005C18.5 14.5005 14 18.5005 13 18.5005C12 18.5005 8 18.5005 7 18.5005C6 18.5005 1.5 14.5005 1.5 13.0005C1.5 12.0005 2.16576 10.2603 3.49727 7.77979L3.47837 7.79064C3.1218 6.83963 2.91717 4.9575 2.98736 4.14112L3.00829 4.00866C3.08775 3.6047 3.21335 2.70519 4.5 3.00052C5.92689 3.32803 7.23073 4.54479 7.64506 5.27843L12.134 5.27843C12.5483 4.54478 13.5731 3.32803 15 3.00052Z" stroke={stroke} strokeLinejoin="round" />
      <path fillRule="evenodd" clipRule="evenodd" d="M10.6139 12.2308L10.3865 12.8863C10.3125 13.0997 10.0795 13.2127 9.86615 13.1386C9.74785 13.0976 9.65488 13.0046 9.61384 12.8863L9.38643 12.2308C9.28607 11.9415 9.0587 11.7141 8.7694 11.6137L8.11384 11.3863C7.90048 11.3123 7.78751 11.0793 7.86153 10.866C7.90257 10.7477 7.99554 10.6547 8.11384 10.6137L8.7694 10.3863C9.0587 10.2859 9.28607 10.0585 9.38643 9.76923L9.61384 9.11367C9.68786 8.90031 9.92082 8.78734 10.1342 8.86136C10.2525 8.9024 10.3455 8.99537 10.3865 9.11367L10.6139 9.76923C10.7143 10.0585 10.9416 10.2859 11.2309 10.3863L11.8865 10.6137C12.0999 10.6877 12.2128 10.9207 12.1388 11.134C12.0978 11.2523 12.0048 11.3453 11.8865 11.3863L11.2309 11.6137C10.9416 11.7141 10.7143 11.9415 10.6139 12.2308Z" fill={accent} />
    </svg>
  );
  return null;
}

function SettingsShell({ children, active = 'channels', dim }) {
  const navItems = [
    { id: 'account', label: '我的账号' },
    { id: 'shortcut', label: '快捷键' },
    { id: 'guide', label: '新手引导' },
    { id: 'plugin', label: '插件' },
    { id: 'storage', label: '存储管理' },
    { id: 'channels', label: '消息渠道' },
    { id: 'about', label: '关于我们' },
  ];
  return (
    <div style={{
      width: 880, height: 620, background: C.panel, borderRadius: 16,
      boxShadow: '0 20px 60px rgba(0,0,0,0.18), 0 0 0 1px rgba(0,0,0,0.04)',
      display: 'flex', overflow: 'hidden', fontFamily: C.font, color: C.ink,
      position: 'relative',
      filter: dim ? 'brightness(0.96)' : 'none',
    }}>
      {/* 左导航 */}
      <div style={{ width: 180, background: C.navBg, padding: '20px 12px', display: 'flex', flexDirection: 'column', gap: 2 }}>
        <div style={{ fontSize: 13, fontWeight: 600, color: C.ink, padding: '6px 10px 10px' }}>设置</div>
        {navItems.map((n) => {
          const on = active === n.id;
          return (
            <div key={n.id} style={{
              height: 36, padding: '0 10px', borderRadius: 6,
              display: 'flex', alignItems: 'center', gap: 8,
              background: on ? 'linear-gradient(90deg,#EFE9FC,#F7F4FE)' : 'transparent',
              color: on ? C.brand : C.ink2,
              fontSize: 13, fontWeight: on ? 600 : 500,
              cursor: 'pointer',
            }}>
              <span style={{ width: 16, height: 16, display: 'flex', alignItems: 'center', justifyContent: 'center' }}><NavIcon kind={n.id} active={on} /></span>
              <span>{n.label}</span>
            </div>
          );
        })}
      </div>
      {/* 主内容区 */}
      <div style={{ flex: 1, padding: '26px 28px', overflow: 'hidden', display: 'flex', flexDirection: 'column' }}>
        {children}
      </div>
      {/* 右上角关闭 */}
      <div style={{
        position: 'absolute', top: 16, right: 16, width: 28, height: 28, borderRadius: 14,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        color: C.mute, cursor: 'pointer', fontSize: 18, lineHeight: 1,
      }}>×</div>
    </div>
  );
}

/* ---------- 消息渠道主页内容（注入到 SettingsShell） ---------- */
function ChannelsMain({ feishu = 'none', wechat = 'none' }) {
  return (
    <>
      <div style={{ fontSize: 18, fontWeight: 600, color: C.ink, letterSpacing: -0.2 }}>消息渠道</div>
      <div style={{ fontSize: 13, color: C.ink3, marginTop: 6, lineHeight: 1.6 }}>
        让常用的 IM 工具直接连上本地 AI，外部消息会转发到桌面端 local-agent 执行。
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 12, marginTop: 20 }}>
        <FeishuCard state={feishu} />
        <WechatCard state={wechat} />
        <MobileCard />
      </div>
    </>
  );
}

/* ---------- 飞书卡片 ---------- */
function FeishuCard({ state = 'none' }) {
  const connected = state === 'connected';
  return (
    <Card>
      <FeishuIcon />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <div style={{ fontSize: 14, fontWeight: 600, color: C.ink }}>飞书机器人</div>
          {connected && <Badge kind="green">已连接</Badge>}
        </div>
        <div style={{ fontSize: 12.5, color: C.ink3, marginTop: 4, lineHeight: 1.55 }}>
          注册飞书应用以通过飞书接收和回复消息。
        </div>
        {connected ? (
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 10 }}>
            <MiniAppIcon size={18} />
            <span style={{ fontSize: 12.5, color: C.ink2, fontWeight: 500 }}>办公小浣熊助手</span>
            <span style={{ fontSize: 12, color: C.mute }}>· cli_a92360••••9bb4</span>
          </div>
        ) : (
          <a href="https://open.feishu.cn/document/" target="_blank" rel="noopener" style={{ display: 'inline-block', marginTop: 8, fontSize: 12.5, color: C.brand, fontWeight: 500, textDecoration: 'none' }}>配置指南 →</a>
        )}
      </div>
      <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
        {connected && <Btn kind="dangerGhost">解绑</Btn>}
        <Btn kind={connected ? 'secondary' : 'primary'}>配置</Btn>
      </div>
    </Card>
  );
}

/* ---------- 微信卡片 ---------- */
function WechatCard({ state = 'none' }) {
  const connected = state === 'connected';
  return (
    <Card>
      <WechatIcon />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <div style={{ fontSize: 14, fontWeight: 600, color: C.ink }}>微信 ClawBot</div>
          {connected && <Badge kind="green">已连接</Badge>}
        </div>
        <div style={{ fontSize: 12.5, color: C.ink3, marginTop: 4, lineHeight: 1.55 }}>
          扫码授权微信 ClawBot 以接收和回复消息。
        </div>
        {connected ? (
          <div style={{ marginTop: 10, fontSize: 12.5, color: C.ink2 }}>
            Bot ID：<span style={{ color: C.mute }}>wxbot_3f9a••••e21c</span>
          </div>
        ) : null}
      </div>
      <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
        {connected && <Btn kind="dangerGhost">解绑</Btn>}
        <Btn kind={connected ? 'secondary' : 'primary'}>配置</Btn>
      </div>
    </Card>
  );
}

/* ---------- 自家移动端 · 敬请期待 ---------- */
function MobileCard() {
  return (
    <Card disabled>
      <RaccoonChannelIcon />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <div style={{ fontSize: 14, fontWeight: 600, color: C.ink2 }}>移动端办公小浣熊</div>
        </div>
        <div style={{ fontSize: 12.5, color: C.mute, marginTop: 4, lineHeight: 1.55 }}>
          将支持在手机办公小浣熊 App 内随时唤起本地 AI。
        </div>
      </div>
      <Badge kind="mute">敬请期待</Badge>
    </Card>
  );
}

function Card({ children, disabled }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'flex-start', gap: 14,
      padding: 16, borderRadius: 16, border: `1px solid ${C.border}`,
      background: disabled ? '#FAFAF8' : '#fff',
      opacity: disabled ? 0.7 : 1,
    }}>
      {children}
    </div>
  );
}

/* ===========================================================
 * 弹窗：飞书注册 / 微信注册 / 解绑确认
 * 每个弹窗都画在画板内：底层 Settings 面板被遮罩，弹窗居中
 * =========================================================== */

function ModalLayer({ children, w = 480 }) {
  return (
    <div style={{
      position: 'absolute', inset: 0, background: 'rgba(20,16,12,0.45)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      borderRadius: 16, zIndex: 5,
    }}>
      <div style={{
        width: w, background: '#fff', borderRadius: 14,
        boxShadow: '0 24px 60px rgba(0,0,0,0.24)',
        fontFamily: C.font, overflow: 'hidden',
      }}>{children}</div>
    </div>
  );
}
function ModalHeader({ title, onClose = true }) {
  return (
    <div style={{
      padding: '16px 20px', borderBottom: `1px solid ${C.borderSoft}`,
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
    }}>
      <div style={{ fontSize: 15, fontWeight: 600, color: C.ink }}>{title}</div>
      {onClose && <div style={{ color: C.mute, cursor: 'pointer', fontSize: 18, lineHeight: 1 }}>×</div>}
    </div>
  );
}

/* ---------- 飞书注册弹窗 · 空 / 错误 ---------- */
function FeishuModal({ variant = 'empty' }) {
  const error = variant === 'error';
  return (
    <ModalLayer w={480}>
      <ModalHeader title="注册飞书通道" />
      <div style={{ padding: '18px 20px' }}>
        <div style={{ fontSize: 13, color: C.ink3, lineHeight: 1.6 }}>
          输入飞书应用凭据以将此工作区绑定到飞书机器人。<br />
          App ID 和 App Secret 为必填项。
        </div>
        <a href="https://open.feishu.cn/document/" target="_blank" rel="noopener" style={{ display: 'inline-block', marginTop: 8, fontSize: 12.5, color: C.brand, fontWeight: 500, textDecoration: 'none' }}>配置指南 →</a>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginTop: 16 }}>
          <Input value={error ? 'cli_a92360a836b89bb4' : ''} placeholder="飞书 App ID（如 cli_a92360a836b89bb4）" />
          <Input value={error ? '••••••••••••••••••••' : ''} placeholder="飞书 App Secret" type="password" />
        </div>

        {error && (
          <div style={{
            marginTop: 12, padding: '8px 12px', borderRadius: 8,
            background: 'rgba(255,79,97,0.08)', color: C.danger,
            fontSize: 12.5, display: 'flex', gap: 6, alignItems: 'center',
          }}>
            <span>⚠</span>
            <span>凭证错误，请确认 App ID 与 App Secret 是否正确</span>
          </div>
        )}
      </div>
      <div style={{
        padding: '14px 20px', borderTop: `1px solid ${C.borderSoft}`,
        display: 'flex', justifyContent: 'flex-end', gap: 8,
      }}>
        <Btn kind="secondary">取消</Btn>
        <Btn kind="primary">{error ? '重试' : '注册'}</Btn>
      </div>
    </ModalLayer>
  );
}

/* ---------- 微信注册弹窗 · 等待扫码 / 已扫码 / 已过期 ---------- */
function WechatModal({ variant = 'waiting' }) {
  return (
    <ModalLayer w={480}>
      <ModalHeader title="注册微信 ClawBot" />
      <div style={{ padding: '18px 20px' }}>
        <div style={{ fontSize: 13, color: C.ink3, lineHeight: 1.6 }}>
          使用个人微信扫码授权 ClawBot 接入本机。<br />
          登录态由本地保管，不上传服务器。
        </div>

        <div style={{ display: 'flex', justifyContent: 'center', marginTop: 16 }}>
          <QrBox variant={variant} />
        </div>

        <div style={{
          marginTop: 14, textAlign: 'center', fontSize: 13,
          color: variant === 'expired' ? C.danger : (variant === 'scanned' ? '#1E9C7E' : C.ink3),
          fontWeight: 500,
        }}>
          {variant === 'waiting' && '⟳ 请使用微信扫描二维码'}
          {variant === 'scanned' && '✓ 请在手机上点击「确认」'}
          {variant === 'expired' && (
            <button style={{
              border: `1px solid ${C.border}`, background: '#fff', color: C.ink2,
              padding: '6px 14px', borderRadius: 6, fontSize: 12.5, fontWeight: 500,
              cursor: 'pointer', fontFamily: 'inherit',
            }}>重新生成二维码</button>
          )}
        </div>
      </div>
      <div style={{
        padding: '14px 20px', borderTop: `1px solid ${C.borderSoft}`,
        display: 'flex', justifyContent: 'flex-end',
      }}>
        <Btn kind="secondary">取消</Btn>
      </div>
    </ModalLayer>
  );
}

function QrBox({ variant }) {
  const size = 168;
  if (variant === 'scanned') {
    return (
      <div style={{
        width: size, height: size, border: `1px solid ${C.border}`, borderRadius: 10,
        display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
        background: '#FAFAF8', color: '#1E9C7E', gap: 8,
      }}>
        <div style={{
          width: 44, height: 44, borderRadius: 22, background: C.okSoft,
          display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 22, fontWeight: 700,
        }}>✓</div>
        <div style={{ fontSize: 13, fontWeight: 500 }}>已扫码</div>
      </div>
    );
  }
  if (variant === 'expired') {
    return (
      <div style={{
        width: size, height: size, border: `1px solid ${C.border}`, borderRadius: 10,
        display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
        background: '#FAFAF8', color: C.mute, gap: 8,
      }}>
        <div style={{
          width: 44, height: 44, borderRadius: 22, background: '#F2F2F0',
          display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 22,
        }}>⊘</div>
        <div style={{ fontSize: 13, fontWeight: 500 }}>二维码已过期</div>
      </div>
    );
  }
  // waiting: 伪二维码（CSS 矩阵）
  return (
    <div style={{
      width: size, height: size, padding: 10, border: `1px solid ${C.border}`, borderRadius: 10,
      background: '#fff',
    }}>
      <FakeQr />
    </div>
  );
}
function FakeQr() {
  // 14×14 网格的伪二维码
  const N = 14;
  const seed = [
    '11111110011111',
    '10000010111001',
    '10111010001101',
    '10111011110001',
    '10111010011011',
    '10000011001101',
    '11111110101011',
    '00000001100100',
    '11011110011011',
    '01000011101101',
    '11101010010011',
    '00100110110101',
    '11011011001011',
    '10110110100111',
  ];
  return (
    <div style={{ display: 'grid', gridTemplateColumns: `repeat(${N},1fr)`, gap: 1, width: '100%', height: '100%' }}>
      {seed.map((row, r) => row.split('').map((b, c) => (
        <div key={`${r}-${c}`} style={{ background: b === '1' ? '#1A1A14' : 'transparent' }} />
      )))}
    </div>
  );
}

/* ---------- 解绑确认 ---------- */
function UnbindModal({ channel = 'feishu' }) {
  const txt = channel === 'feishu'
    ? { title: '解绑飞书通道', body: '解绑后将无法在飞书里收发本地 AI 消息，下次需要重新填写 App ID 与 Secret。' }
    : { title: '解绑微信 ClawBot', body: '解绑后将无法通过微信 ClawBot 收发本地 AI 消息，下次需要重新扫码授权。' };
  return (
    <ModalLayer w={360}>
      <ModalHeader title={txt.title} />
      <div style={{ padding: '18px 20px', fontSize: 13, color: C.ink3, lineHeight: 1.7 }}>
        {txt.body}
      </div>
      <div style={{
        padding: '12px 20px 16px', display: 'flex', justifyContent: 'flex-end', gap: 8,
      }}>
        <Btn kind="secondary">取消</Btn>
        <Btn kind="danger">解绑</Btn>
      </div>
    </ModalLayer>
  );
}

/* ===========================================================
 * 画板导出（每个画板就是一张设置 Modal，单独或叠加弹窗）
 * 画板宽度 = 880（Modal 宽度），高度 = 620（Modal 高度）
 * =========================================================== */

function CH_Default() { return <SettingsShell><ChannelsMain feishu="none" wechat="none" /></SettingsShell>; }
function CH_FeishuConnected() { return <SettingsShell><ChannelsMain feishu="connected" wechat="none" /></SettingsShell>; }
function CH_BothConnected() { return <SettingsShell><ChannelsMain feishu="connected" wechat="connected" /></SettingsShell>; }

function CH_FeishuModalEmpty() {
  return <SettingsShell dim><ChannelsMain feishu="none" wechat="none" /><FeishuModal variant="empty" /></SettingsShell>;
}
function CH_FeishuModalError() {
  return <SettingsShell dim><ChannelsMain feishu="none" wechat="none" /><FeishuModal variant="error" /></SettingsShell>;
}
function CH_WechatWaiting() {
  return <SettingsShell dim><ChannelsMain feishu="connected" wechat="none" /><WechatModal variant="waiting" /></SettingsShell>;
}
function CH_WechatScanned() {
  return <SettingsShell dim><ChannelsMain feishu="connected" wechat="none" /><WechatModal variant="scanned" /></SettingsShell>;
}
function CH_WechatExpired() {
  return <SettingsShell dim><ChannelsMain feishu="connected" wechat="none" /><WechatModal variant="expired" /></SettingsShell>;
}
function CH_UnbindFeishu() {
  return <SettingsShell dim><ChannelsMain feishu="connected" wechat="connected" /><UnbindModal channel="feishu" /></SettingsShell>;
}
function CH_UnbindWechat() {
  return <SettingsShell dim><ChannelsMain feishu="connected" wechat="connected" /><UnbindModal channel="wechat" /></SettingsShell>;
}

Object.assign(window, {
  CH_Default, CH_FeishuConnected, CH_BothConnected,
  CH_FeishuModalEmpty, CH_FeishuModalError,
  CH_WechatWaiting, CH_WechatScanned, CH_WechatExpired,
  CH_UnbindFeishu, CH_UnbindWechat,
});
