import { useState, useEffect, useRef, useCallback } from 'react';
import { useServerMonitor } from './hooks/useServerMonitor';
import { usePublicServers } from './hooks/usePublicServers';
import { ServerCard } from './components/ServerCard/ServerCard';
import { ServerDetail } from './components/ServerDetail/ServerDetail';
import { AdminPanel } from './components/AdminPanel/AdminPanel';
import { RandomBackdrop } from './components/RandomBackdrop/RandomBackdrop';
import {
  verifyAdminToken,
  ADMIN_TOKEN_STORAGE,
} from './api/central';
import './App.css';

function App() {
  const { servers, loading, error, reload } = usePublicServers(30000);
  const [selectedServerId, setSelectedServerId] = useState<string | null>(null);
  const [showHeader, setShowHeader] = useState(true);

  const [showTokenGate, setShowTokenGate] = useState(false);
  const [tokenInput, setTokenInput] = useState('');
  const [tokenError, setTokenError] = useState<string | null>(null);
  const [adminOpen, setAdminOpen] = useState(false);

  const logoClickCount = useRef(0);
  const logoClickReset = useRef<ReturnType<typeof setTimeout> | null>(null);

  const statuses = useServerMonitor();

  const handleLogoClick = useCallback(() => {
    if (logoClickReset.current) {
      clearTimeout(logoClickReset.current);
    }
    logoClickCount.current += 1;
    if (logoClickCount.current >= 5) {
      logoClickCount.current = 0;
      const saved = sessionStorage.getItem(ADMIN_TOKEN_STORAGE);
      if (saved) {
        setAdminOpen(true);
      } else {
        setShowTokenGate(true);
        setTokenInput('');
        setTokenError(null);
      }
      return;
    }
    logoClickReset.current = setTimeout(() => {
      logoClickCount.current = 0;
    }, 2000);
  }, []);

  const submitToken = async () => {
    const ok = await verifyAdminToken(tokenInput.trim());
    if (!ok) {
      setTokenError('口令错误');
      return;
    }
    sessionStorage.setItem(ADMIN_TOKEN_STORAGE, tokenInput.trim());
    setShowTokenGate(false);
    setTokenError(null);
    setAdminOpen(true);
  };

  const closeAdmin = () => {
    setAdminOpen(false);
  };

  const invalidateAdminSession = () => {
    sessionStorage.removeItem(ADMIN_TOKEN_STORAGE);
    setAdminOpen(false);
    alert('管理凭证已失效，请重新验证');
  };

  useEffect(() => {
    return () => {
      if (logoClickReset.current) clearTimeout(logoClickReset.current);
    };
  }, []);

  const selectedStatus = selectedServerId ? statuses[selectedServerId] : null;
  const selectedServer = servers.find((s) => s.id === selectedServerId);

  const adminToken = sessionStorage.getItem(ADMIN_TOKEN_STORAGE) || '';

  return (
    <div className="app">
      <RandomBackdrop />
      {showTokenGate && (
        <div className="token-gate-overlay" role="dialog" aria-modal="true">
          <div className="token-gate-dialog">
            <h3>管理验证</h3>
            <p className="token-gate-hint">请输入管理口令（内网默认与中心服务 ADMIN_TOKEN 一致）。</p>
            <input
              type="password"
              className="token-gate-input"
              placeholder="Token"
              value={tokenInput}
              onChange={(e) => {
                setTokenInput(e.target.value);
                setTokenError(null);
              }}
              autoFocus
              onKeyDown={(e) => {
                if (e.key === 'Enter') void submitToken();
              }}
            />
            {tokenError && <p className="token-gate-error">{tokenError}</p>}
            <div className="token-gate-actions">
              <button type="button" className="btn-submit" onClick={() => void submitToken()}>
                进入后台
              </button>
              <button
                type="button"
                className="btn-cancel"
                onClick={() => {
                  setShowTokenGate(false);
                  setTokenError(null);
                }}
              >
                取消
              </button>
            </div>
          </div>
        </div>
      )}

      {adminOpen && adminToken && (
        <AdminPanel
          token={adminToken}
          onClose={closeAdmin}
          onSessionInvalid={invalidateAdminSession}
          onSaved={() => void reload()}
        />
      )}

      {!showHeader && (
        <button
          className="btn-show-header"
          onClick={() => setShowHeader(true)}
          title="显示导航栏"
          type="button"
        >
          👁️
        </button>
      )}

      {showHeader && (
        <header className="app-header">
          <h1>
            <button
              type="button"
              className="logo-hit"
              onClick={handleLogoClick}
              title="萌芽监控"
              aria-label="萌芽监控"
            >
              <img className="app-logo" src="/logo.png" alt="" />
            </button>
            萌芽监控面板
          </h1>
          <div className="header-actions">
            <button
              type="button"
              className="btn-icon"
              onClick={() => setShowHeader(false)}
              title="隐藏导航栏"
            >
              👁️
            </button>
          </div>
        </header>
      )}

      <main className="server-grid">
        {loading ? (
          <div className="empty-state">
            <p>正在从中心服务加载节点列表…</p>
          </div>
        ) : error ? (
          <div className="empty-state">
            <p>无法加载监控列表</p>
            <p className="hint">{error}</p>
            <p className="hint">请确认 mengyamonitor-backend-server 已启动，且 VITE_CENTRAL_API_URL 或开发代理配置正确。</p>
          </div>
        ) : servers.length === 0 ? (
          <div className="empty-state">
            <p>暂无已启用的监控节点</p>
            <p className="hint">请联系管理员在后台添加采集端地址。</p>
          </div>
        ) : (
          servers.map((server) => {
            const status = statuses[server.id];
            const storageUsage =
              status?.metrics?.storage?.reduce((max, s) => Math.max(max, s.usedPercent), 0) || 0;
            return (
              <ServerCard
                key={server.id}
                server={server}
                online={status?.online || false}
                metrics={status?.metrics}
                cpuUsage={status?.metrics?.cpu.usagePercent || 0}
                memoryUsage={status?.metrics?.memory.usedPercent || 0}
                storageUsage={storageUsage}
                uptime={status?.metrics?.uptimeSeconds}
                onDetail={() => setSelectedServerId(server.id)}
              />
            );
          })
        )}
      </main>

      {selectedStatus?.metrics && selectedServer && (
        <ServerDetail
          metrics={selectedStatus.metrics}
          serverName={selectedServer.name}
          onClose={() => setSelectedServerId(null)}
        />
      )}
    </div>
  );
}

export default App;
