// ===== 主应用：路由、状态管理、页面切换 =====
const { useState: useStateApp, useEffect: useEffectApp, useCallback: useCallbackApp } = React;
const useStateQDS = React.useState;

function App() {
  const [initialized, setInitialized] = useStateApp(false);
  const [page, setPage] = useStateApp('home'); // home | list | device | ods | lockout | history | settings
  const [selectedDeviceId, setSelectedDeviceId] = useStateApp(null);
  const [currentUser, setCurrentUserState] = useStateApp(null);
  const [showLoginModal, setShowLoginModal] = useStateApp(false);
  const [showRegisterModal, setShowRegisterModal] = useStateApp(false);
  const [showAdminPanel, setShowAdminPanel] = useStateApp(false);
  const [toast, setToast] = useStateApp(null);
  const [showSuccess, setShowSuccess] = useStateApp(false);
  const [platform, setPlatform] = useStateApp('browser'); // feishu | wechat | dingtalk | browser
  const [syncing, setSyncing] = useStateApp(false);

  // 初始化数据
  useEffectApp(() => {
    // 检测平台
    setPlatform(detectPlatform());

    initAppData().then(() => {
      setInitialized(true);

      // 尝试从飞书同步最新设备和授权人员数据
      syncDataFromFeishu().then(result => {
        if (result.ok) {
          console.log('[同步] 数据同步完成');
        }
      });

      // 检查URL参数（飞书扫码进入）
      const deviceParam = getDeviceIdFromURL();
      const actionParam = getActionFromURL();
      if (deviceParam) {
        // 支持多种格式：设备ID、ODS编号、设备名称
        const found = findDeviceByScanCode(deviceParam);
        if (found) {
          setSelectedDeviceId(found.id);
          // 如果有 action=lockout 参数，直接进入锁定作业登记（仅限飞书环境且已授权）
          if (actionParam === 'lockout' && isFeishuPlatform()) {
            setPage('device');
            // 延迟一帧后再判断授权状态并跳转
            setTimeout(() => {
              const saved = localStorage.getItem(STORAGE_KEYS.CURRENT_USER);
              if (saved) {
                const user = JSON.parse(saved);
                if (isAuthorized(user, found)) {
                  setPage('lockout');
                }
              }
            }, 100);
          } else {
            setPage('device');
          }
        }
      }
      // 检查登录状态
      const saved = localStorage.getItem(STORAGE_KEYS.CURRENT_USER);
      if (saved) {
        setCurrentUserState(JSON.parse(saved));
      }
    });

    // 宣告可升级
    function announceUpgrade() {
      window.parent.postMessage({ type: 'miaoda:upgrade:available', kind: 'interactive-prototype' }, '*');
    }
    if (document.readyState === 'complete') {
      announceUpgrade();
    } else {
      window.addEventListener('load', announceUpgrade, { once: true });
    }
  }, []);

  const showToastMsg = useCallbackApp((msg, duration = 2000) => {
    setToast(msg);
    setTimeout(() => setToast(null), duration);
  }, []);

  const handleLogin = (user) => {
    setCurrentUser(user);
    setCurrentUserState(user);
    setShowLoginModal(false);
    showToastMsg(`${user.name} 已登录`);
  };

  const handleLogout = () => {
    setCurrentUser(null);
    setCurrentUserState(null);
    showToastMsg('已退出登录');
  };

  const handleSelectDevice = (deviceId) => {
    setSelectedDeviceId(deviceId);
    setPage('device');
  };

  const handleSubmitSuccess = (record) => {
    setShowSuccess(true);
    setTimeout(() => {
      setShowSuccess(false);
      setPage('history');
    }, 2000);
  };

  const device = selectedDeviceId ? getDeviceById(selectedDeviceId) : null;
  const ods = device ? getDeviceODS(device.name) : null;
  const authorized = isAuthorized();

  if (!initialized) {
    return (
      <div style={{
        minHeight: '100vh',
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center',
        background: 'var(--industrial-darker)',
      }}>
        <div style={{
          width: '56px',
          height: '56px',
          border: '4px solid var(--industrial-light)',
          borderTopColor: 'var(--safety-yellow)',
          borderRadius: '50%',
          animation: 'spin 0.8s linear infinite',
          marginBottom: '16px',
        }} />
        <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>
        <p style={{ color: 'var(--text-muted)', fontSize: '14px' }}>加载中...</p>
      </div>
    );
  }

  return (
    <div>
      {/* 首页 */}
      {page === 'home' && (
        <HomePage
          currentUser={currentUser}
          onDeviceList={() => setPage('list')}
          onSelectDevice={handleSelectDevice}
          onLogin={() => setShowLoginModal(true)}
          onLogout={handleLogout}
          onSyncData={async () => {
            setSyncing(true);
            const result = await syncDataFromFeishu();
            setSyncing(false);
            showToastMsg(result.ok ? '数据已更新' : '同步失败，使用本地数据');
          }}
          authorized={authorized}
          platform={platform}
          syncing={syncing}
        />
      )}

      {/* 设备列表 */}
      {page === 'list' && (
        <DeviceList
          onSelectDevice={handleSelectDevice}
          onBack={() => setPage('home')}
        />
      )}

      {/* 设备详情（两入口）*/}
      {page === 'device' && device && (
        <DeviceHome
          device={device}
          ods={ods}
           onBack={() => setPage('home')}
           onODS={() => setPage('ods')}
           onLockout={() => {
             const status = getSubmitterStatus();
             if (status === 'none') {
               setShowRegisterModal(true);
               return;
             }
             if (status === 'pending') {
               showToastMsg('您的注册申请正在审核中，请耐心等待管理员审批');
               return;
             }
            if (!ods) {
              showToastMsg('该设备暂无ODS数据');
              return;
            }
            setPage('lockout');
          }}
          onHistory={() => setPage('history')}
          authorized={authorized}
          canSubmit={isApprovedSubmitter()}
          platform={platform}
          onLogin={() => setShowLoginModal(true)}
          onAdminPanel={() => setShowAdminPanel(true)}
          onDeviceList={() => setPage('list')}
        />
      )}

      {/* ODS页 */}
      {page === 'ods' && device && (
        <ODSPage
          device={device}
          ods={ods}
          onBack={() => setPage('device')}
          onStartLockout={() => {
            const status = getSubmitterStatus();
            if (status === 'none') {
              setShowRegisterModal(true);
              return;
            }
            if (status === 'pending') {
              showToastMsg('您的注册申请正在审核中，请耐心等待管理员审批');
              return;
            }
            setPage('lockout');
          }}
        />
      )}

      {/* 锁定作业登记 */}
      {page === 'lockout' && device && ods && isApprovedSubmitter() && (
        <LockoutForm
          device={device}
          ods={ods}
          currentUser={currentUser}
          onBack={() => setPage('device')}
          onSubmit={handleSubmitSuccess}
        />
      )}

      {/* 历史记录 */}
      {page === 'history' && device && (
        <HistoryPage
          device={device}
          onBack={() => setPage('device')}
        />
      )}

      {/* 登录模态框 */}
      {showLoginModal && (
        <LoginModal
          onClose={() => setShowLoginModal(false)}
          onLogin={handleLogin}
        />
      )}

      {/* 注册模态框（微信用户首次填报） */}
      {showRegisterModal && (
        <RegisterModal
          onClose={() => setShowRegisterModal(false)}
          onRegister={(name, dept) => {
            const result = registerSubmitter(name, dept);
            setShowRegisterModal(false);
            if (result.status === 'pending') {
              setCurrentUserState(result.user);
              showToastMsg('注册申请已提交，等待管理员审批');
            } else if (result.status === 'already_pending') {
              showToastMsg('您已提交过申请，请等待审批');
            } else if (result.status === 'already_approved') {
              showToastMsg('您已通过审核，可直接填报');
            }
          }}
        />
      )}

      {/* 管理员审核面板 */}
      {showAdminPanel && (
        <AdminApprovalPanel
          onClose={() => setShowAdminPanel(false)}
          onApprove={(id) => {
            approveSubmitter(id);
            showToastMsg('已通过审核');
          }}
          onReject={(id) => {
            rejectSubmitter(id);
            showToastMsg('已拒绝申请');
          }}
        />
      )}

      {/* 成功提示 */}
      {showSuccess && (
        <div style={{
          position: 'fixed',
          top: 0, left: 0, right: 0, bottom: 0,
          background: 'rgba(0,0,0,0.8)',
          zIndex: 1000,
          display: 'flex',
          flexDirection: 'column',
          alignItems: 'center',
          justifyContent: 'center',
          animation: 'fadeIn 0.3s ease',
        }}>
          <style>{`@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }`}</style>
          <div style={{
            width: '80px',
            height: '80px',
            borderRadius: '50%',
            background: 'var(--success)',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            marginBottom: '16px',
            animation: 'scaleIn 0.4s cubic-bezier(0.68, -0.55, 0.27, 1.55)',
          }}>
            <style>{`@keyframes scaleIn { from { transform: scale(0); } to { transform: scale(1); } }`}</style>
            <svg width="44" height="44" viewBox="0 0 24 24" fill="none">
              <path d="M5 13l4 4L19 7" stroke="white" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
          </div>
          <div style={{ color: 'white', fontSize: '20px', fontWeight: 700 }}>提交成功</div>
          <div style={{ color: 'rgba(255,255,255,0.7)', fontSize: '14px', marginTop: '4px' }}>
            记录已保存
          </div>
        </div>
      )}

      {/* Toast */}
      {toast && <div className="toast">{toast}</div>}
    </div>
  );
}

// ===== 首页 =====
function HomePage({ currentUser, onDeviceList, onLogin, onLogout, onSyncData, authorized, platform, syncing, onSelectDevice }) {
  return (
    <div className="page" style={{ paddingBottom: 0 }}>
      {/* Hero 区 */}
      <div className="hero">
        <div className="hazard-stripe" style={{
          position: 'absolute', top: 0, left: 0, right: 0, height: '6px',
        }} />
        <div className="hero-content" style={{ paddingTop: '12px' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '16px' }}>
            <span className="hero-tag">LOTO · 上锁挂牌</span>
            <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
              {/* 平台标识 */}
              <span style={{
                fontSize: '11px',
                padding: '3px 8px',
                borderRadius: '6px',
                background: platform === 'feishu'
                  ? 'rgba(46,125,50,0.2)'
                  : platform === 'wechat'
                    ? 'rgba(76,175,80,0.2)'
                    : 'rgba(255,255,255,0.1)',
                color: platform === 'feishu'
                  ? '#81C784'
                  : platform === 'wechat'
                    ? '#A5D6A7'
                    : 'var(--text-muted)',
                fontWeight: 600,
              }}>
                {platform === 'feishu' ? '飞书' : platform === 'wechat' ? '微信' : platform === 'dingtalk' ? '钉钉' : '浏览器'}
              </span>
              {/* 手动同步按钮 */}
              <button
                onClick={onSyncData}
                disabled={syncing}
                title="同步最新数据"
                style={{
                  width: '32px',
                  height: '32px',
                  borderRadius: '50%',
                  background: 'rgba(255,255,255,0.1)',
                  border: '1px solid rgba(255,255,255,0.15)',
                  color: 'var(--text-primary)',
                  cursor: syncing ? 'not-allowed' : 'pointer',
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'center',
                  opacity: syncing ? 0.6 : 1,
                  padding: 0,
                }}
              >
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" style={{
                  animation: syncing ? 'spin 1s linear infinite' : 'none',
                }}>
                  <path d="M21 12a9 9 0 1 1-3-6.7" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
                  <path d="M21 4v5h-5" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
              </button>
              {currentUser ? (
                <div style={{
                  display: 'flex',
                  alignItems: 'center',
                  gap: '8px',
                  cursor: 'pointer',
                }} onClick={onLogout}>
                  <div style={{
                    width: '32px',
                    height: '32px',
                    borderRadius: '50%',
                    background: 'var(--safety-yellow)',
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    fontWeight: 700,
                    fontSize: '12px',
                    color: 'var(--industrial-darker)',
                  }}>
                    {currentUser.avatar || currentUser.name.slice(0, 2)}
                  </div>
                  <span style={{ fontSize: '13px', color: 'var(--text-secondary)' }}>
                    {currentUser.name}
                  </span>
                </div>
              ) : (
                <button
                  onClick={onLogin}
                  style={{
                    padding: '6px 14px',
                    background: 'rgba(255,255,255,0.1)',
                    border: '1px solid rgba(255,255,255,0.15)',
                    borderRadius: '8px',
                    color: 'var(--text-primary)',
                    fontSize: '13px',
                    cursor: 'pointer',
                    fontFamily: 'inherit',
                  }}
                >
                  登录
                </button>
              )}
            </div>
          </div>
          <h1 className="hero-title">
            延锋座椅<br />
            <span>长沙工厂</span><br />
            LOTO管理系统
          </h1>
          <p className="hero-desc">
            100台设备 · 131名授权人员 · 全程可追溯<br />
            为每一次上锁挂牌作业保驾护航
          </p>
        </div>
      </div>

      {/* 快速搜索设备 */}
      <div style={{ padding: '16px 16px 0' }}>
        <QuickDeviceSearch onSelect={onSelectDevice} />
      </div>

      {/* 入口卡片 */}
      <div className="entry-grid" style={{ marginTop: '16px' }}>
        <div className="entry-card" onClick={onDeviceList}>
          <div className="entry-card-icon yellow">
            <svg width="26" height="26" viewBox="0 0 24 24" fill="none">
              <rect x="3" y="4" width="18" height="16" rx="2" stroke="var(--safety-yellow)" strokeWidth="2" />
              <path d="M7 9h10M7 13h10M7 17h6" stroke="var(--safety-yellow)" strokeWidth="2" strokeLinecap="round" />
            </svg>
          </div>
          <div className="entry-card-title">设备列表</div>
          <div className="entry-card-desc">查看全部 {appData.devices.length} 台设备</div>
        </div>

        {authorized && (
          <div className="entry-card" onClick={onDeviceList}>
            <div className="entry-card-icon green">
              <svg width="26" height="26" viewBox="0 0 24 24" fill="none">
                <path d="M6 10V7a6 6 0 1 1 12 0v3" stroke="#4CAF50" strokeWidth="2" strokeLinecap="round" />
                <rect x="4" y="10" width="16" height="11" rx="2" fill="#4CAF50" opacity="0.8" />
              </svg>
            </div>
            <div className="entry-card-title">作业登记</div>
            <div className="entry-card-desc">选择设备新建锁定记录</div>
          </div>
        )}

        {!authorized && (
          <div className="entry-card" onClick={onLogin}>
            <div className="entry-card-icon red">
              <svg width="26" height="26" viewBox="0 0 24 24" fill="none">
                <path d="M6 10V7a6 6 0 1 1 12 0v3" stroke="#EF5350" strokeWidth="2" strokeLinecap="round" />
                <rect x="4" y="10" width="16" height="11" rx="2" fill="#EF5350" opacity="0.8" />
              </svg>
            </div>
            <div className="entry-card-title">授权登录</div>
            <div className="entry-card-desc">LOTO授权人员登录操作</div>
          </div>
        )}
      </div>

      {/* 统计信息 */}
      <div style={{ padding: '24px 16px 24px' }}>
        <div className="section-title">系统概览</div>
        <div className="info-grid" style={{ gridTemplateColumns: 'repeat(3, 1fr)' }}>
          <div className="info-item" style={{ textAlign: 'center' }}>
            <div style={{ fontSize: '24px', fontWeight: 900, color: 'var(--safety-yellow)' }}>{appData.devices.length}</div>
            <div className="info-item-label">在管设备</div>
          </div>
          <div className="info-item" style={{ textAlign: 'center' }}>
            <div style={{ fontSize: '24px', fontWeight: 900, color: 'var(--success-light)' }}>
              {appData.records.length}
            </div>
            <div className="info-item-label">作业记录</div>
          </div>
          <div className="info-item" style={{ textAlign: 'center' }}>
           <div style={{ fontSize: '24px', fontWeight: 900, color: '#42A5F5' }}>
               {appData.authorizedUsers.length}
             </div>
             <div className="info-item-label">授权人员</div>
          </div>
        </div>
      </div>

      {/* 安全提示 */}
      <div style={{
        margin: '0 16px 24px',
        padding: '14px 16px',
        background: 'rgba(255, 209, 0, 0.08)',
        border: '1px solid rgba(255, 209, 0, 0.2)',
        borderRadius: '12px',
        display: 'flex',
        gap: '12px',
      }}>
        <svg width="22" height="22" viewBox="0 0 24 24" fill="none" style={{ flexShrink: 0, marginTop: 1 }}>
          <path d="M12 9v4M12 17h.01" stroke="var(--safety-yellow)" strokeWidth="2" strokeLinecap="round" />
          <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" stroke="var(--safety-yellow)" strokeWidth="2" />
        </svg>
        <div style={{ fontSize: '13px', lineHeight: 1.6, color: 'var(--text-secondary)' }}>
          <span style={{ fontWeight: 700, color: 'var(--safety-yellow)' }}>安全提示：</span>
          维修保养设备前必须执行锁定挂牌程序，确认能量零能量状态后方可作业。
        </div>
      </div>

      {/* 底部导航区模拟占位 */}
      <div style={{ paddingBottom: '24px', textAlign: 'center' }}>
        <div style={{ fontSize: '11px', color: 'var(--text-muted)', opacity: 0.6 }}>
          延锋座椅BU2长沙工厂 · EHS安全管理
        </div>
      </div>
    </div>
  );
}

// ===== 设备详情（入口选择）=====
// ===== 快速搜索设备 =====
function QuickDeviceSearch({ onSelect }) {
  const [query, setQuery] = useStateQDS('');

  const results = React.useMemo(() => {
    if (!query.trim()) return [];
    const q = query.trim().toLowerCase();
    return appData.devices
      .filter(d => d.name.toLowerCase().includes(q) || d.id.toLowerCase().includes(q))
      .slice(0, 8);
  }, [query]);

  return (
    <div style={{ position: 'relative' }}>
      <div className="search-box" style={{ margin: 0 }}>
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
          <circle cx="11" cy="11" r="8" stroke="var(--text-muted)" strokeWidth="2" />
          <path d="m21 21-4.3-4.3" stroke="var(--text-muted)" strokeWidth="2" strokeLinecap="round" />
        </svg>
        <input
          type="text"
          placeholder="搜索设备名称或编号..."
          value={query}
          onChange={(e) => setQuery(e.target.value)}
        />
      </div>
      {results.length > 0 && (
        <div style={{
          position: 'absolute',
          top: '100%',
          left: 0, right: 0,
          marginTop: '6px',
          background: 'var(--card-bg)',
          border: '1px solid var(--border)',
          borderRadius: '12px',
          maxHeight: '320px',
          overflowY: 'auto',
          zIndex: 100,
          boxShadow: '0 8px 24px rgba(0,0,0,0.3)',
        }}>
          {results.map((d, i) => (
            <div
              key={d.id}
              onClick={() => {
                onSelect(d.id);
                setQuery('');
              }}
              style={{
                padding: '12px 14px',
                display: 'flex',
                alignItems: 'center',
                gap: '10px',
                borderBottom: i < results.length - 1 ? '1px solid var(--border)' : 'none',
                cursor: 'pointer',
              }}
            >
              <div style={{
                width: '36px', height: '36px',
                borderRadius: '8px',
                background: 'rgba(255,209,0,0.1)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                flexShrink: 0,
              }}>
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
                  <path d="M20 7h-3V3H7v4H4v11h16V7zM9 5h6v2H9V5z" fill="var(--safety-yellow)" />
                </svg>
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: '14px', fontWeight: 600, color: 'var(--text-primary)' }}>{d.name}</div>
                <div style={{ fontSize: '11px', color: 'var(--text-muted)' }}>{d.id}</div>
              </div>
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" style={{ flexShrink: 0, color: 'var(--text-muted)' }}>
                <path d="M9 18l6-6-6-6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ===== 设备操作界面（扫码直达）=====
function DeviceHome({ device, ods, onBack, onODS, onLockout, onHistory, authorized, platform, onLogin, onDeviceList }) {
  const recordCount = getDeviceRecords(device.id).length;
  const inFeishu = platform === 'feishu';
  const canLockout = inFeishu && authorized;
  const isReadOnly = !inFeishu; // 非飞书环境为只读模式

  // 非飞书环境：授权登录跳转飞书
  const handleAuthLogin = () => {
    const link = buildFeishuDeepLink(device.id, 'login');
    window.open(link, '_blank');
    showToastMsg('正在跳转飞书登录...');
  };

  return (
    <div className="page">
      {/* 黄黑警示条 */}
      <div className="hazard-stripe" />

      {/* 顶部：设备信息卡 */}
      <div style={{ background: 'var(--bg-primary)' }}>
        <div style={{ padding: '12px 16px 0' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: '10px', marginBottom: '16px' }}>
            <button
              className="back-btn"
              onClick={onBack}
              style={{
                width: '36px', height: '36px',
                background: 'rgba(255,255,255,0.06)',
                border: '1px solid rgba(255,255,255,0.08)',
                borderRadius: '10px',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                color: 'var(--text-primary)',
                cursor: 'pointer',
              }}
            >
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
                <path d="M15 18l-6-6 6-6" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
            </button>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: '13px', color: 'var(--text-muted)', marginBottom: '2px' }}>LOTO · 设备操作界面</div>
              <div style={{ fontSize: '17px', fontWeight: 800, color: 'var(--text-primary)' }}>{device.name}</div>
            </div>
            <span style={{
              fontSize: '11px',
              padding: '4px 10px',
              borderRadius: '6px',
              background: platform === 'feishu'
                ? 'rgba(46,125,50,0.2)'
                : platform === 'wechat'
                  ? 'rgba(76,175,80,0.2)'
                  : 'rgba(255,255,255,0.08)',
              color: platform === 'feishu'
                ? '#81C784'
                : platform === 'wechat'
                  ? '#A5D6A7'
                  : 'var(--text-muted)',
              fontWeight: 600,
            }}>
              {platform === 'feishu' ? '飞书环境' : platform === 'wechat' ? '微信环境' : platform === 'dingtalk' ? '钉钉环境' : '浏览器'}
            </span>
          </div>

          {/* 设备信息卡 */}
          <div style={{
            background: 'linear-gradient(135deg, var(--card-bg), rgba(255,209,0,0.06))',
            border: '1px solid var(--border)',
            borderRadius: '16px',
            padding: '18px',
            marginBottom: '16px',
          }}>
            <div style={{ display: 'flex', gap: '14px', alignItems: 'center', marginBottom: '16px' }}>
              <div style={{
                width: '56px',
                height: '56px',
                borderRadius: '14px',
                background: 'linear-gradient(135deg, rgba(255,209,0,0.25), rgba(255,209,0,0.05))',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                flexShrink: 0,
              }}>
                <svg width="30" height="30" viewBox="0 0 24 24" fill="none">
                  <path d="M20 7h-3V3H7v4H4v11h16V7zM9 5h6v2H9V5z" fill="var(--safety-yellow)" />
                </svg>
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: '18px', fontWeight: 800, color: 'var(--text-primary)', marginBottom: '4px' }}>
                  {device.name}
                </div>
                <div style={{ fontSize: '12px', color: 'var(--text-muted)' }}>
                  编号 {device.id}  ·  安全等级 {ods ? ods['安全等级'] : '暂无评级'}
                </div>
              </div>
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '10px' }}>
              <div style={{
                background: 'rgba(255,255,255,0.03)',
                borderRadius: '10px',
                padding: '10px 8px',
                textAlign: 'center',
              }}>
                <div style={{ fontSize: '10px', color: 'var(--text-muted)', marginBottom: '4px' }}>ODS文件</div>
                <div style={{ fontSize: '13px', fontWeight: 700, color: '#42A5F5' }}>
                  {ods ? ods['文件编号'] : '暂无'}
                </div>
              </div>
              <div style={{
                background: 'rgba(255,255,255,0.03)',
                borderRadius: '10px',
                padding: '10px 8px',
                textAlign: 'center',
              }}>
                <div style={{ fontSize: '10px', color: 'var(--text-muted)', marginBottom: '4px' }}>能量类型</div>
                <div style={{ fontSize: '13px', fontWeight: 700, color: 'var(--safety-yellow)' }}>
                  {ods ? new Set(ods['能量信息'].map(e => e['类型'])).size : 0} 种
                </div>
              </div>
              <div style={{
                background: 'rgba(255,255,255,0.03)',
                borderRadius: '10px',
                padding: '10px 8px',
                textAlign: 'center',
              }}>
                <div style={{ fontSize: '10px', color: 'var(--text-muted)', marginBottom: '4px' }}>锁定点</div>
                <div style={{ fontSize: '13px', fontWeight: 700, color: '#CE93D8' }}>
                  {ods ? ods['能量信息'].length : 0} 个
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <div className="page-body" style={{ paddingTop: '12px' }}>
        {/* 第一部分：系统概览 */}
        <div style={{ marginBottom: '24px' }}>
          <div className="section-title">系统概览</div>

          {/* 三个数字卡片 */}
          <div style={{
            display: 'grid',
            gridTemplateColumns: 'repeat(3, 1fr)',
            gap: '10px',
            marginBottom: '14px',
          }}>
            <div style={{
              background: 'var(--card-bg)',
              border: '1px solid var(--border)',
              borderRadius: '12px',
              padding: '14px 8px',
              textAlign: 'center',
            }}>
              <div style={{ fontSize: '22px', fontWeight: 900, color: 'var(--safety-yellow)', marginBottom: '4px' }}>
                {appData.devices.length}
              </div>
              <div style={{ fontSize: '11px', color: 'var(--text-muted)' }}>在管设备</div>
            </div>
            <div style={{
              background: 'var(--card-bg)',
              border: '1px solid var(--border)',
              borderRadius: '12px',
              padding: '14px 8px',
              textAlign: 'center',
            }}>
              <div style={{ fontSize: '22px', fontWeight: 900, color: 'var(--success-light)', marginBottom: '4px' }}>
                {appData.records.length}
              </div>
              <div style={{ fontSize: '11px', color: 'var(--text-muted)' }}>作业记录</div>
            </div>
            <div style={{
              background: 'var(--card-bg)',
              border: '1px solid var(--border)',
              borderRadius: '12px',
              padding: '14px 8px',
              textAlign: 'center',
            }}>
              <div style={{ fontSize: '22px', fontWeight: 900, color: '#42A5F5', marginBottom: '4px' }}>
                {appData.authorizedUsers.length}
              </div>
              <div style={{ fontSize: '11px', color: 'var(--text-muted)' }}>授权人员</div>
            </div>
          </div>

          {/* 安全提示滚动条 */}
          <div style={{
            background: 'rgba(255,209,0,0.08)',
            border: '1px solid rgba(255,209,0,0.25)',
            borderRadius: '10px',
            padding: '10px 12px',
            overflow: 'hidden',
            position: 'relative',
            height: '36px',
            display: 'flex',
            alignItems: 'center',
          }}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" style={{ flexShrink: 0, marginRight: '8px' }}>
              <path d="M12 9v4M12 17h.01" stroke="var(--safety-yellow)" strokeWidth="2" strokeLinecap="round" />
              <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" stroke="var(--safety-yellow)" strokeWidth="2" />
            </svg>
            <div className="safety-scroll" style={{ flex: 1, overflow: 'hidden', position: 'relative', height: '18px' }}>
              <div className="safety-scroll-inner" style={{
                whiteSpace: 'nowrap',
                position: 'absolute',
                top: 0,
                left: 0,
              }}>
                <span style={{
                  fontSize: '12px',
                  color: 'var(--safety-yellow)',
                  fontWeight: 500,
                  lineHeight: '18px',
                  marginRight: '40px',
                }}>⚠ LOTO作业前请确认所有危险能量已隔离</span>
                <span style={{
                  fontSize: '12px',
                  color: 'var(--safety-yellow)',
                  fontWeight: 500,
                  lineHeight: '18px',
                  marginRight: '40px',
                }}>⚠ 上锁挂牌作业仅限授权人员执行</span>
                <span style={{
                  fontSize: '12px',
                  color: 'var(--safety-yellow)',
                  fontWeight: 500,
                  lineHeight: '18px',
                  marginRight: '40px',
                }}>⚠ 每个锁定点必须独立验证能量为零</span>
                <span style={{
                  fontSize: '12px',
                  color: 'var(--safety-yellow)',
                  fontWeight: 500,
                  lineHeight: '18px',
                  marginRight: '40px',
                }}>⚠ 解锁前确认所有人员已离开危险区域</span>
                <span style={{
                  fontSize: '12px',
                  color: 'var(--safety-yellow)',
                  fontWeight: 500,
                  lineHeight: '18px',
                  marginRight: '40px',
                }}>⚠ LOTO作业前请确认所有危险能量已隔离</span>
                <span style={{
                  fontSize: '12px',
                  color: 'var(--safety-yellow)',
                  fontWeight: 500,
                  lineHeight: '18px',
                  marginRight: '40px',
                }}>⚠ 上锁挂牌作业仅限授权人员执行</span>
              </div>
            </div>
          </div>
        </div>

        {/* 权限提示 */}
        {isReadOnly && (
          <div className="permission-banner" style={{ marginBottom: '16px', color: '#FFB74D' }}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
              <path d="M12 9v4M12 17h.01" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
              <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" stroke="currentColor" strokeWidth="2" />
            </svg>
            <span style={{ flex: 1, fontSize: '12px', lineHeight: 1.5 }}>
              当前为非飞书环境，仅可查看。点击<span style={{ color: '#FFD54F', fontWeight: 600 }}>授权登录</span>跳转飞书完成操作
            </span>
          </div>
        )}
        {inFeishu && !authorized && (
          <div className="permission-banner" style={{ marginBottom: '16px' }}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
              <path d="M6 10V7a6 6 0 1 1 12 0v3" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
              <rect x="4" y="10" width="16" height="11" rx="2" fill="currentColor" opacity="0.3" />
            </svg>
            <span style={{ flex: 1, fontSize: '12px', lineHeight: 1.5 }}>
              您以访客身份浏览，锁定作业登记需要授权人员登录。
            </span>
          </div>
        )}
        {authorized && (
          <div style={{
            marginBottom: '16px',
            padding: '10px 12px',
            background: 'rgba(76,175,80,0.08)',
            border: '1px solid rgba(76,175,80,0.25)',
            borderRadius: '10px',
            display: 'flex',
            gap: '10px',
            alignItems: 'center',
          }}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
              <path d="M9 12l2 2 4-4M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0z" stroke="#81C784" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
            <span style={{ fontSize: '12px', color: '#A5D6A7', lineHeight: 1.5 }}>
              已授权：您可执行LOTO锁定挂牌作业。
            </span>
          </div>
        )}

        {/* 第二部分：系统功能入口 */}
        <div style={{ marginBottom: '24px' }}>
          <div className="section-title">系统功能入口</div>

          {/* 非飞书环境：授权登录入口 */}
          {isReadOnly && (
            <div
              className="list-item"
              onClick={handleAuthLogin}
              style={{
                padding: '20px 16px',
                marginBottom: '10px',
                background: 'linear-gradient(135deg, rgba(255,152,0,0.2), rgba(255,152,0,0.05))',
                borderRadius: '14px',
                border: '1px solid rgba(255,152,0,0.3)',
              }}
            >
              <div className="list-item-icon" style={{ background: 'rgba(255,152,0,0.2)', width: '48px', height: '48px', borderRadius: '12px' }}>
                <svg width="24" height="24" viewBox="0 0 24 24" fill="none">
                  <path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4" stroke="#FFB74D" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
                  <path d="M10 17l5-5-5-5M15 12H3" stroke="#FFB74D" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
              </div>
              <div className="list-item-content">
                <div className="list-item-title" style={{ fontSize: '15px' }}>
                  授权登录
                  <span style={{
                    marginLeft: '8px',
                    fontSize: '11px',
                    padding: '2px 8px',
                    borderRadius: '4px',
                    background: 'rgba(255,152,0,0.25)',
                    color: '#FFB74D',
                    fontWeight: 600,
                    verticalAlign: 'middle',
                  }}>
                    跳转飞书
                  </span>
                </div>
                <div className="list-item-subtitle">LOTO授权人员登录后可执行锁定作业</div>
              </div>
              <div className="list-item-arrow">
                <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
                  <path d="M9 18l6-6-6-6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
              </div>
            </div>
          )}

          {/* 飞书环境：设备列表入口（从设备操作界面快速返回列表） */}
          {inFeishu && onDeviceList && (
            <div
              className="list-item"
              onClick={onDeviceList}
              style={{
                padding: '18px 16px',
                marginBottom: '10px',
                background: 'var(--card-bg)',
                borderRadius: '14px',
                border: '1px solid var(--border)',
              }}
            >
              <div className="list-item-icon" style={{ background: 'rgba(66,165,245,0.15)', width: '48px', height: '48px', borderRadius: '12px' }}>
                <svg width="24" height="24" viewBox="0 0 24 24" fill="none">
                  <rect x="3" y="4" width="18" height="16" rx="2" stroke="#42A5F5" strokeWidth="2" />
                  <path d="M7 9h10M7 13h10M7 17h6" stroke="#42A5F5" strokeWidth="2" strokeLinecap="round" />
                </svg>
              </div>
              <div className="list-item-content">
                <div className="list-item-title" style={{ fontSize: '15px' }}>设备列表</div>
                <div className="list-item-subtitle">浏览全部 {appData.devices.length} 台设备及ODS信息</div>
              </div>
              <div className="list-item-arrow">
                <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
                  <path d="M9 18l6-6-6-6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
              </div>
            </div>
          )}

          {/* 查看ODS */}
          <div
            className="list-item"
            onClick={onODS}
            style={{
              padding: '18px 16px',
              marginBottom: '10px',
              background: 'var(--card-bg)',
              borderRadius: '14px',
              border: '1px solid var(--border)',
            }}
          >
            <div className="list-item-icon" style={{ background: 'rgba(66,165,245,0.15)', width: '48px', height: '48px', borderRadius: '12px' }}>
              <svg width="24" height="24" viewBox="0 0 24 24" fill="none">
                <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" stroke="#42A5F5" strokeWidth="2" />
                <path d="M14 2v6h6M16 13H8M16 17H8M10 9H8" stroke="#42A5F5" strokeWidth="2" strokeLinecap="round" />
              </svg>
            </div>
            <div className="list-item-content">
              <div className="list-item-title" style={{ fontSize: '15px' }}>查看ODS作业指导书</div>
              <div className="list-item-subtitle">能量信息、锁定点、控制措施、验证方法</div>
            </div>
            <div className="list-item-arrow">
              <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
                <path d="M9 18l6-6-6-6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
            </div>
          </div>

          {/* 锁定作业登记（非飞书环境不显示） */}
          {!isReadOnly && (
            <div
              className="list-item"
              onClick={onLockout}
              style={{
                padding: '20px 16px',
                marginBottom: '10px',
                background: canLockout
                  ? 'linear-gradient(135deg, rgba(46,125,50,0.2), rgba(46,125,50,0.05))'
                  : 'linear-gradient(135deg, rgba(255,152,0,0.15), rgba(255,152,0,0.03))',
                borderRadius: '14px',
                border: canLockout
                  ? '1px solid rgba(76,175,80,0.3)'
                  : '1px solid rgba(255,152,0,0.3)',
                opacity: canLockout ? 1 : 0.95,
              }}
            >
              <div className="list-item-icon" style={{
                background: canLockout ? 'rgba(46,125,50,0.2)' : 'rgba(255,152,0,0.2)',
                width: '48px', height: '48px', borderRadius: '12px',
              }}>
                <svg width="24" height="24" viewBox="0 0 24 24" fill="none">
                  <path d="M6 10V7a6 6 0 1 1 12 0v3" stroke={canLockout ? '#81C784' : '#FFB74D'} strokeWidth="2" strokeLinecap="round" />
                  <rect x="4" y="10" width="16" height="11" rx="2" fill={canLockout ? '#81C784' : '#FFB74D'} opacity="0.85" />
                </svg>
              </div>
              <div className="list-item-content">
                <div className="list-item-title" style={{ fontSize: '15px' }}>
                  锁定作业登记
                  {inFeishu && !authorized && (
                    <span style={{
                      marginLeft: '8px',
                      fontSize: '11px',
                      padding: '2px 8px',
                      borderRadius: '4px',
                      background: 'rgba(255,152,0,0.25)',
                      color: '#FFB74D',
                      fontWeight: 600,
                      verticalAlign: 'middle',
                    }}>
                      需登录授权
                    </span>
                  )}
                </div>
                <div className="list-item-subtitle">
                  A/B循环锁定、拍照、签名、提交记录
                </div>
              </div>
              <div className="list-item-arrow">
                <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
                  <path d="M9 18l6-6-6-6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
              </div>
            </div>
          )}

          {/* 历史记录 */}
          <div
            className="list-item"
            onClick={onHistory}
            style={{
              padding: '18px 16px',
              background: 'var(--card-bg)',
              borderRadius: '14px',
              border: '1px solid var(--border)',
            }}
          >
            <div className="list-item-icon" style={{ background: 'rgba(156,39,176,0.15)', width: '48px', height: '48px', borderRadius: '12px' }}>
              <svg width="24" height="24" viewBox="0 0 24 24" fill="none">
                <circle cx="12" cy="12" r="9" stroke="#CE93D8" strokeWidth="2" />
                <path d="M12 7v5l3 2" stroke="#CE93D8" strokeWidth="2" strokeLinecap="round" />
              </svg>
            </div>
            <div className="list-item-content">
              <div className="list-item-title" style={{ fontSize: '15px' }}>历史记录</div>
              <div className="list-item-subtitle">
                查看该设备所有LOTO作业记录 · 共 {recordCount} 条
              </div>
            </div>
            <div className="list-item-arrow">
              <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
                <path d="M9 18l6-6-6-6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
            </div>
          </div>
        </div>

        {/* 底部说明 */}
        <div style={{ textAlign: 'center', paddingTop: '8px', paddingBottom: '16px' }}>
          <div style={{ fontSize: '11px', color: 'var(--text-muted)', opacity: 0.5, lineHeight: 1.6 }}>
            延锋座椅BU2长沙工厂 · EHS安全管理<br />
            本系统操作仅限授权人员执行 · v2.0
          </div>
        </div>
      </div>
    </div>
  );
}

// ===== 登录模态框 =====
function LoginModal({ onClose, onLogin }) {
  const [searchQuery, setSearchQuery] = React.useState('');
  const [deptFilter, setDeptFilter] = React.useState('全部');

  const departments = React.useMemo(() => {
    const depts = [...new Set(appData.authorizedUsers.map(u => u.department).filter(Boolean))];
    return ['全部', ...depts.sort()];
  }, []);

  const filteredUsers = React.useMemo(() => {
    let list = appData.authorizedUsers;
    if (deptFilter !== '全部') {
      list = list.filter(u => u.department === deptFilter);
    }
    if (searchQuery.trim()) {
      const q = searchQuery.trim().toLowerCase();
      list = list.filter(u =>
        u.name.toLowerCase().includes(q) ||
        (u.team || '').toLowerCase().includes(q) ||
        (u.department || '').toLowerCase().includes(q)
      );
    }
    // 排序：按部门+姓名
    return [...list].sort((a, b) => {
      if (a.department !== b.department) return (a.department || '').localeCompare(b.department || '');
      return a.name.localeCompare(b.name);
    });
  }, [searchQuery, deptFilter]);

  const getAuthBadgeColor = (type) => {
    if (type === '监护人') return { bg: 'rgba(255,193,7,0.2)', color: '#FFC107' };
    if (type === '作业人员') return { bg: 'rgba(76,175,80,0.2)', color: '#4CAF50' };
    return { bg: 'var(--industrial-light)', color: 'var(--text-secondary)' };
  };

  return (
    <div
      style={{
        position: 'fixed',
        top: 0, left: 0, right: 0, bottom: 0,
        background: 'rgba(0,0,0,0.7)',
        zIndex: 200,
        display: 'flex',
        alignItems: 'flex-end',
        justifyContent: 'center',
        animation: 'fadeIn 0.2s ease',
      }}
      onClick={onClose}
    >
      <style>{`@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }`}</style>
      <div
        onClick={e => e.stopPropagation()}
        style={{
          width: '100%',
          maxWidth: '430px',
          background: 'var(--industrial-dark)',
          borderTopLeftRadius: '20px',
          borderTopRightRadius: '20px',
          padding: '20px 20px calc(24px + env(safe-area-inset-bottom))',
          animation: 'slideUp 0.3s ease',
        }}
      >
        <style>{`@keyframes slideUp { from { transform: translateY(100%); } to { transform: translateY(0); } }`}</style>
        <div style={{
          width: '40px',
          height: '4px',
          background: 'var(--industrial-light)',
          borderRadius: '2px',
          margin: '0 auto 16px',
        }} />

        <h2 style={{ fontSize: '18px', fontWeight: 700, marginBottom: '4px', textAlign: 'center' }}>
          选择授权人员
        </h2>
        <p style={{ fontSize: '13px', color: 'var(--text-muted)', textAlign: 'center', marginBottom: '16px' }}>
          共 {appData.authorizedUsers.length} 名授权人员 · 搜索姓名/部门/班组
        </p>

        {/* 搜索框 */}
        <div style={{
          position: 'relative',
          marginBottom: '12px',
        }}>
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" style={{
            position: 'absolute',
            left: '14px',
            top: '50%',
            transform: 'translateY(-50%)',
            color: 'var(--text-muted)',
          }}>
            <circle cx="11" cy="11" r="8" stroke="currentColor" strokeWidth="2" />
            <path d="M21 21l-4.35-4.35" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
          </svg>
          <input
            type="text"
            value={searchQuery}
            onChange={e => setSearchQuery(e.target.value)}
            placeholder="搜索姓名、部门或班组..."
            style={{
              width: '100%',
              padding: '12px 16px 12px 42px',
              background: 'var(--card-bg)',
              border: '1px solid var(--border)',
              borderRadius: '12px',
              color: 'var(--text-primary)',
              fontSize: '14px',
              outline: 'none',
              boxSizing: 'border-box',
            }}
          />
        </div>

        {/* 部门筛选 */}
        <div style={{
          display: 'flex',
          gap: '6px',
          overflowX: 'auto',
          marginBottom: '12px',
          paddingBottom: '4px',
        }}>
          {departments.map(dept => (
            <div
              key={dept}
              onClick={() => setDeptFilter(dept)}
              style={{
                padding: '6px 14px',
                borderRadius: '16px',
                fontSize: '12px',
                fontWeight: deptFilter === dept ? 600 : 400,
                background: deptFilter === dept ? 'var(--safety-yellow)' : 'var(--card-bg)',
                color: deptFilter === dept ? 'var(--industrial-darker)' : 'var(--text-secondary)',
                whiteSpace: 'nowrap',
                cursor: 'pointer',
                flexShrink: 0,
                border: '1px solid',
                borderColor: deptFilter === dept ? 'var(--safety-yellow)' : 'var(--border)',
              }}
            >
              {dept}
            </div>
          ))}
        </div>

        <div style={{ maxHeight: '45vh', overflowY: 'auto' }}>
          {filteredUsers.length === 0 ? (
            <div style={{
              textAlign: 'center',
              padding: '40px 20px',
              color: 'var(--text-muted)',
              fontSize: '13px',
            }}>
              未找到匹配的授权人员
            </div>
          ) : (
            filteredUsers.map(user => (
              <div
                key={user.id}
                onClick={() => onLogin(user)}
                style={{
                  display: 'flex',
                  alignItems: 'center',
                  gap: '12px',
                  padding: '12px 14px',
                  background: 'var(--card-bg)',
                  border: '1px solid var(--border)',
                  borderRadius: '12px',
                  marginBottom: '8px',
                  cursor: 'pointer',
                }}
              >
                <div style={{
                  width: '40px',
                  height: '40px',
                  borderRadius: '50%',
                  background: 'linear-gradient(135deg, var(--safety-yellow), #FFA000)',
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'center',
                  fontWeight: 700,
                  fontSize: '14px',
                  color: 'var(--industrial-darker)',
                  flexShrink: 0,
                }}>
                  {user.avatar || user.name.charAt(0)}
                </div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
                    <span style={{ fontWeight: 600, fontSize: '15px' }}>{user.name}</span>
                    <div style={{ display: 'flex', gap: '4px' }}>
                      {(user.auth_types || []).map(type => {
                        const c = getAuthBadgeColor(type);
                        return (
                          <span
                            key={type}
                            style={{
                              fontSize: '10px',
                              padding: '2px 6px',
                              borderRadius: '4px',
                              background: c.bg,
                              color: c.color,
                              fontWeight: 500,
                            }}
                          >
                            {type}
                          </span>
                        );
                      })}
                    </div>
                  </div>
                  <div style={{
                    fontSize: '12px',
                    color: 'var(--text-muted)',
                    marginTop: '3px',
                    display: 'flex',
                    gap: '8px',
                    flexWrap: 'wrap',
                  }}>
                    {user.department && <span>{user.department}</span>}
                    {user.team && <span>· {user.team}</span>}
                    {user.energy_scope && <span>· {user.energy_scope}</span>}
                  </div>
                </div>
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
                  <path d="M9 18l6-6-6-6" stroke="var(--text-muted)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
              </div>
            ))
          )}
        </div>

        {filteredUsers.length > 0 && (
          <div style={{
            textAlign: 'center',
            fontSize: '11px',
            color: 'var(--text-muted)',
            marginTop: '8px',
          }}>
            显示 {filteredUsers.length} / {appData.authorizedUsers.length} 人
          </div>
        )}

        <button
          onClick={onClose}
          className="btn btn-ghost"
          style={{ marginTop: '16px' }}
        >
          取消
        </button>

        <div style={{
          marginTop: '16px',
          padding: '12px',
          background: 'rgba(255,255,255,0.03)',
          borderRadius: '8px',
          fontSize: '12px',
          color: 'var(--text-muted)',
          textAlign: 'center',
        }}>
          非授权人员无需登录即可查看历史记录<br />
          支持微信/手机浏览器访问查询
        </div>
      </div>
    </div>
  );
}

// ===== 注册模态框（微信用户首次填报） =====
function RegisterModal({ onClose, onRegister }) {
  const [name, setName] = useStateApp('');
  const [department, setDepartment] = useStateApp('');
  const [error, setError] = useStateApp('');

  const handleSubmit = () => {
    if (!name.trim()) { setError('请输入姓名'); return; }
    if (!department.trim()) { setError('请输入部门'); return; }
    onRegister(name.trim(), department.trim());
  };

  return (
    <div style={{
      position: 'fixed', top: 0, left: 0, right: 0, bottom: 0,
      background: 'rgba(0,0,0,0.7)', zIndex: 1000,
      display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '20px',
    }}>
      <div style={{
        background: 'var(--industrial-dark)', borderRadius: '12px', padding: '24px',
        width: '100%', maxWidth: '360px',
      }}>
        <h3 style={{ color: 'var(--safety-yellow)', fontSize: '18px', marginBottom: '16px' }}>
          首次填报注册
        </h3>
        <p style={{ color: 'var(--text-muted)', fontSize: '13px', marginBottom: '16px' }}>
          首次提交LOTO作业记录需填写姓名和部门，经管理员审核后方可填报。
        </p>
        <input
          type="text" placeholder="姓名" value={name}
          onChange={e => { setName(e.target.value); setError(''); }}
          style={{ width: '100%', padding: '12px', marginBottom: '12px', borderRadius: '8px',
            border: '1px solid var(--industrial-light)', background: 'var(--industrial-darker)',
            color: 'white', fontSize: '15px', boxSizing: 'border-box' }}
        />
        <input
          type="text" placeholder="部门（如：EHS、维修部、生产部）" value={department}
          onChange={e => { setDepartment(e.target.value); setError(''); }}
          style={{ width: '100%', padding: '12px', marginBottom: '12px', borderRadius: '8px',
            border: '1px solid var(--industrial-light)', background: 'var(--industrial-darker)',
            color: 'white', fontSize: '15px', boxSizing: 'border-box' }}
        />
        {error && <div style={{ color: '#ef5350', fontSize: '13px', marginBottom: '8px' }}>{error}</div>}
        <button onClick={handleSubmit} className="btn btn-primary" style={{ width: '100%', marginBottom: '8px' }}>
          提交注册申请
        </button>
        <button onClick={onClose} className="btn btn-ghost" style={{ width: '100%' }}>
          取消
        </button>
      </div>
    </div>
  );
}

// ===== 管理员审核面板 =====
function AdminApprovalPanel({ onClose, onApprove, onReject }) {
  const [pending, setPending] = useStateApp([]);
  const [refreshKey, setRefreshKey] = useStateApp(0);

  useEffectApp(() => {
    setPending(getPendingSubmitters());
  }, [refreshKey]);

  const handleApprove = (id) => { onApprove(id); setRefreshKey(k => k + 1); };
  const handleReject = (id) => { onReject(id); setRefreshKey(k => k + 1); };

  return (
    <div style={{
      position: 'fixed', top: 0, left: 0, right: 0, bottom: 0,
      background: 'rgba(0,0,0,0.7)', zIndex: 1000,
      display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '20px',
    }}>
      <div style={{
        background: 'var(--industrial-dark)', borderRadius: '12px', padding: '24px',
        width: '100%', maxWidth: '420px', maxHeight: '80vh', overflow: 'auto',
      }}>
        <h3 style={{ color: 'var(--safety-yellow)', fontSize: '18px', marginBottom: '16px' }}>
          用户审核管理
        </h3>
        {pending.length === 0 ? (
          <p style={{ color: 'var(--text-muted)', textAlign: 'center', padding: '24px' }}>
            暂无待审核用户
          </p>
        ) : (
          pending.map(user => (
            <div key={user.id} style={{
              background: 'var(--industrial-darker)', borderRadius: '8px',
              padding: '12px', marginBottom: '8px',
            }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                <div>
                  <div style={{ color: 'white', fontSize: '15px', fontWeight: 600 }}>{user.name}</div>
                  <div style={{ color: 'var(--text-muted)', fontSize: '13px' }}>{user.department}</div>
                  <div style={{ color: 'var(--text-muted)', fontSize: '11px' }}>
                    申请时间：{new Date(user.registeredAt).toLocaleString('zh-CN')}
                  </div>
                </div>
                <div style={{ display: 'flex', gap: '8px' }}>
                  <button onClick={() => handleApprove(user.id)}
                    style={{ padding: '6px 16px', borderRadius: '6px', border: 'none',
                      background: 'var(--success)', color: 'white', fontSize: '13px', cursor: 'pointer' }}>
                    通过
                  </button>
                  <button onClick={() => handleReject(user.id)}
                    style={{ padding: '6px 16px', borderRadius: '6px', border: 'none',
                      background: '#ef5350', color: 'white', fontSize: '13px', cursor: 'pointer' }}>
                    拒绝
                  </button>
                </div>
              </div>
            </div>
          ))
        )}
        <button onClick={onClose} className="btn btn-ghost" style={{ width: '100%', marginTop: '12px' }}>
          关闭
        </button>
      </div>
    </div>
  );
}

// 渲染
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
