import React, { useState, useMemo, useEffect } from 'react';
import {
PieChart, Pie, Cell, ResponsiveContainer, Tooltip as RechartsTooltip,
AreaChart, Area, XAxis, YAxis, CartesianGrid
} from 'recharts';
import {
Zap,
ArrowUpRight,
Cpu,
TrendingUp,
Terminal as TerminalIcon,
Activity,
Loader2,
Plus,
RefreshCw,
Pause,
Play,
Settings,
BrainCircuit,
BarChart3,
ShieldCheck,
AlertTriangle
} from 'lucide-react';
import { cryptoService } from '../services/cryptoService.ts';
import { getFinancialAdviceStream } from '../services/geminiService.ts';
import { CoinMarketData, GlobalData, AIInsight, AITradingBot } from '../types/index.ts';
// --- UI Components ---
const AIStatusBadge: React.FC<{ status: 'active' | 'learning' | 'processing' | 'thinking' }> = ({ status }) => {
const colors = {
active: 'bg-emerald-500',
learning: 'bg-blue-500',
processing: 'bg-purple-500',
thinking: 'bg-cyan-400',
};
const text = {
active: 'Fleet Online',
learning: 'Adapting Models',
processing: 'High Compute',
thinking: 'Synthesizing Alpha',
}
return (
{text[status]}
);
};
const TabButton: React.FC<{ active: boolean; onClick: () => void; label: string }> = ({ active, onClick, label }) => (
);
const TerminalCard: React.FC<{ title: string; subtitle?: string; children: React.ReactNode; className?: string }> = ({ title, subtitle, children, className = "" }) => (
{title}
{subtitle &&
{subtitle}
}
{children}
);
// --- Main Component ---
const CryptoTerminal: React.FC = () => {
type ActiveTab = 'summary' | 'bot-fleet' | 'neural-intel' | 'quantum-depth';
const [activeTab, setActiveTab] = useState('summary');
const [markets, setMarkets] = useState([]);
const [globalData, setGlobalData] = useState(null);
const [loading, setLoading] = useState(true);
// Stateful Bot Fleet Management
const [bots, setBots] = useState([
{ id: 'bot-1', name: 'Orion Alpha', strategy: 'Arbitrage', status: 'active', pnl: 2450.12, uptime: '142h' },
{ id: 'bot-2', name: 'Vesper Node', strategy: 'Momentum', status: 'active', pnl: 810.45, uptime: '89h' },
{ id: 'bot-3', name: 'Helios Prime', strategy: 'Mean Reversion', status: 'paused', pnl: -120.30, uptime: '24h' },
{ id: 'bot-4', name: 'Ghost Protocol', strategy: 'Arbitrage', status: 'active', pnl: 11200.50, uptime: '450h' },
]);
// Chat Interface
const [chatInput, setChatInput] = useState('');
const [chatHistory, setChatHistory] = useState<{ id: string; sender: 'user' | 'ai'; text: string; timestamp: Date }[]>([
{ id: '1', sender: 'ai', text: 'Fleet status verified. Orion Alpha is currently identifying spread opportunities on ETH/USDC.', timestamp: new Date() }
]);
const [isAiThinking, setIsAiThinking] = useState(false);
// --- Bot Logic ---
const toggleBot = (id: string) => {
setBots(prev => prev.map(bot => {
if (bot.id === id) {
const newStatus = bot.status === 'active' ? 'paused' : 'active';
return { ...bot, status: newStatus as 'active' | 'paused' };
}
return bot;
}));
};
const handleProvisionBot = () => {
const name = prompt("Enter Neural Designation (e.g. Nebula 7):");
if (!name) return;
const newBot: AITradingBot = {
id: `bot-${Date.now()}`,
name,
strategy: 'Momentum',
status: 'active',
pnl: 0,
uptime: '0h'
};
setBots([newBot, ...bots]);
};
// --- Chat Logic ---
const handleChatSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!chatInput.trim() || isAiThinking) return;
const userMsg = { id: Date.now().toString(), sender: 'user' as const, text: chatInput, timestamp: new Date() };
setChatHistory(prev => [...prev, userMsg]);
setChatInput('');
setIsAiThinking(true);
const assistantMsgId = (Date.now() + 1).toString();
setChatHistory(prev => [...prev, { id: assistantMsgId, sender: 'ai', text: '', timestamp: new Date() }]);
try {
const context = { system: "NEXUS_OS_FLEET_CONTROL", activeBots: bots.filter(b => b.status === 'active').length };
const stream = await getFinancialAdviceStream(chatInput, context);
let fullContent = '';
for await (const chunk of stream) {
const text = chunk.text;
if (text) {
fullContent += text;
setChatHistory(prev => prev.map(m =>
m.id === assistantMsgId ? { ...m, text: fullContent } : m
));
}
}
} catch (err) {
setChatHistory(prev => prev.map(m => m.id === assistantMsgId ? { ...m, text: 'Neural handshake timed out. Core is still online.' } : m));
} finally {
setIsAiThinking(false);
}
};
// --- Data Polling ---
const fetchData = async () => {
try {
const [marketData, global] = await Promise.all([
cryptoService.getMarkets('usd', 8),
cryptoService.getGlobal()
]);
setMarkets(marketData);
setGlobalData(global);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchData();
const interval = setInterval(fetchData, 60000);
return () => clearInterval(interval);
}, []);
// --- Mocks & Charts ---
const aiInsights: AIInsight[] = useMemo(() => [
{ id: '1', type: 'alpha', message: 'Orion detected unusual L2 liquidity inflow on Optimism. Executing directional bid.', confidence: 98, timestamp: '15s ago', actionable: true },
{ id: '2', type: 'warning', message: 'Gas prices spiking. Vesper Node shifting to low-frequency mode.', confidence: 92, timestamp: '4m ago', actionable: false },
{ id: '3', type: 'opportunity', message: 'Ghost Protocol identifies BTC/USDC arbitrage on derivative nodes.', confidence: 99, timestamp: '12m ago', actionable: true }
], []);
const quantumChartData = useMemo(() => Array.from({ length: 40 }, (_, i) => ({
name: `t-${40 - i}`,
val: 50 + Math.sin(i / 5) * 30 + Math.random() * 10,
})), []);
return (
{/* Real-time Global Bar */}
Global Cap
${globalData ? (globalData.total_market_cap.usd / 1e12).toFixed(2) : '--'}T
= 0 ? 'text-emerald-500' : 'text-rose-500'}`}>
{globalData?.market_cap_change_percentage_24h_usd.toFixed(1)}%
{/* Navigation */}
setActiveTab('summary')} label="Control Summary" />
setActiveTab('bot-fleet')} label="Manage Bot Fleet" />
setActiveTab('neural-intel')} label="Neural Intelligence" />
setActiveTab('quantum-depth')} label="Quantum Depth" />
{/* View Layer */}
{activeTab === 'summary' && (
s + b.pnl, 0) >= 0 ? 'text-emerald-500' : 'text-rose-500'}`}>
${bots.reduce((s, b) => s + b.pnl, 0).toLocaleString()}
Aggregated
{bots.slice(0, 3).map(bot => (
{bot.name}
= 0 ? 'text-emerald-500' : 'text-rose-500'}>${bot.pnl.toFixed(2)}
))}
"LQI analysis detects extreme demand for Ethereum Layer 2 scaling tokens. Ghost Protocol is positioning for breakout."
{aiInsights.map(insight => (
{insight.type} • {insight.timestamp}
"{insight.message}"
))}
Neural Convergence
Model parity is currently maintained at 99.98% across 12 distributed nodes.
Flash 3.0
Pro v2
)}
{/* Bot Fleet View */}
{activeTab === 'bot-fleet' && (
Active Agents
{bots.filter(b => b.status === 'active').length} / {bots.length}
Total USD Harvested
s + b.pnl, 0) >= 0 ? 'text-emerald-500' : 'text-rose-500'}`}>
${bots.reduce((s, b) => s + b.pnl, 0).toFixed(2)}
Neural Control Matrix
| Agent Identity |
Neural Strategy |
Performance (PNL) |
Sync Uptime |
Controls |
{bots.map(bot => (
|
|
{bot.strategy}
|
= 0 ? 'text-emerald-500' : 'text-rose-500'}`}>
{bot.pnl >= 0 ? '+' : ''}${bot.pnl.toFixed(2)}
|
{bot.uptime}
|
|
))}
)}
{/* Neural Intel Tab */}
{activeTab === 'neural-intel' && (
{aiInsights.map(insight => (
{insight.type} signal detected • {insight.timestamp}
{insight.confidence}% Match
"{insight.message}"
{insight.actionable && (
)}
))}
{chatHistory.map(msg => (
{msg.text || (isAiThinking &&
)}
{msg.timestamp.toLocaleTimeString([], { hour12: false })} • {msg.sender === 'user' ? 'U_IDENT' : 'NEXUS_OUT'}
))}
)}
{/* Depth Tab */}
{activeTab === 'quantum-depth' && (
Core Utilization
Node stability verified across all regions
)}
);
};
export default CryptoTerminal;