import { AddLinkEventTracker, GetSessionDataManager, ILinkEventTracker, RemoveLinkEventTracker } from '@nitrots/nitro-renderer';
import { CSSProperties, FC, MouseEvent as ReactMouseEvent, ReactNode, useEffect, useMemo, useState } from 'react';
import { EmuStatsMemoryPoint, EmuStatsRoomRow, EmuStatsSnapshot, EmuStatsUserRow, EmuStatsWiredRow, EmuStatsWiredTopRoomRow, fetchEmuStats, getCachedEmuStats } from '../../api';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../common';

type EmuStatsSection = 'overview' | 'system' | 'wiredInsights' | 'users' | 'rooms' | 'wired';

const REFRESH_INTERVAL_MS = 2_500;

const formatDateTime = (value: number): string =>
{
    if(!value) return '-';

    return new Intl.DateTimeFormat(undefined, {
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit',
        year: 'numeric',
        month: '2-digit',
        day: '2-digit'
    }).format(new Date(value));
};

const formatUptime = (totalSeconds: number): string =>
{
    const hours = Math.floor(totalSeconds / 3600);
    const minutes = Math.floor((totalSeconds % 3600) / 60);
    const seconds = Math.floor(totalSeconds % 60);

    return `${ hours.toString().padStart(2, '0') }h ${ minutes.toString().padStart(2, '0') }m ${ seconds.toString().padStart(2, '0') }s`;
};

const formatCpu = (value: number): string => `${ value.toFixed(1) }%`;
const formatMemory = (used: number, max: number): string => `${ used } MB / ${ max } MB`;
const formatCompactNumber = (value: number): string => new Intl.NumberFormat().format(value);
const formatThroughput = (value: number, suffix: string): string => `${ value.toFixed(1) } ${ suffix }`;
const formatMs = (value: number): string => `${ value.toFixed(2) } ms`;
const formatBoolean = (value: boolean): string => value ? 'Yes' : 'No';
const formatRoomLabel = (roomId: number, roomName: string): string => roomId ? (roomName?.length ? `${ roomName } (#${ roomId })` : `#${ roomId }`) : '-';

const MemoryChart: FC<{ history: EmuStatsMemoryPoint[] }> = ({ history }) =>
{
    const [ hoveredIndex, setHoveredIndex ] = useState<number>(-1);

    const chart = useMemo(() =>
    {
        if(!history?.length)
        {
            return {
                linePoints: '',
                areaPoints: '',
                peak: 0,
                latest: 0,
                plotPoints: [],
                gridValues: [ 0, 0, 0, 0 ]
            };
        }

        const width = 100;
        const height = 100;
        const maxMb = Math.max(...history.map(point => point.maxMb || 1), 1);
        const lastIndex = Math.max(history.length - 1, 1);

        const plotPoints = history.map((point, index) =>
        {
            const x = (index / lastIndex) * width;
            const y = height - ((point.usedMb / maxMb) * (height - 8)) - 4;

            return {
                x,
                y,
                usedMb: point.usedMb,
                usagePercent: point.usagePercent,
                timestamp: point.timestamp
            };
        });

        const points = plotPoints.map(point => `${ point.x.toFixed(2) },${ point.y.toFixed(2) }`);
        const latest = history[history.length - 1]?.usedMb || 0;
        const peak = Math.max(...history.map(point => point.usedMb), 0);
        const gridValues = [ 1, 0.75, 0.5, 0.25 ].map(value => Math.round(maxMb * value));

        return {
            linePoints: points.join(' '),
            areaPoints: `0,100 ${ points.join(' ') } 100,100`,
            peak,
            latest,
            plotPoints,
            gridValues
        };
    }, [ history ]);

    const hoveredPoint = (hoveredIndex >= 0) ? chart.plotPoints[hoveredIndex] : null;

    const onMouseMove = (event: ReactMouseEvent<SVGSVGElement>) =>
    {
        if(!chart.plotPoints.length) return;

        const bounds = event.currentTarget.getBoundingClientRect();
        const relativeX = Math.min(Math.max(event.clientX - bounds.left, 0), bounds.width);
        const ratio = bounds.width > 0 ? (relativeX / bounds.width) : 0;
        const nextIndex = Math.min(chart.plotPoints.length - 1, Math.max(0, Math.round(ratio * (chart.plotPoints.length - 1))));

        setHoveredIndex(nextIndex);
    };

    return (
        <div className="nitro-emustats__chart-card">
            <div className="nitro-emustats__section-header">
                <div>
                    <h3>Realtime Memory Usage</h3>
                    <p>Rolling history from the emulator process.</p>
                </div>
                <div className="nitro-emustats__chart-meta">
                    <span>Peak { chart.peak } MB</span>
                    <strong>{ chart.latest } MB</strong>
                </div>
            </div>
            <div className="nitro-emustats__chart-shell">
                <div className="nitro-emustats__chart-axis">
                    { chart.gridValues.map((value, index) => <span key={ `${ value }-${ index }` }>{ value } MB</span>) }
                    <span>0 MB</span>
                </div>
                <div className="nitro-emustats__chart-canvas">
                    <svg
                        viewBox="0 0 100 100"
                        preserveAspectRatio="none"
                        className="nitro-emustats__chart"
                        onMouseLeave={ () => setHoveredIndex(-1) }
                        onMouseMove={ onMouseMove }
                    >
                        <defs>
                            <linearGradient id="emuStatsArea" x1="0" x2="0" y1="0" y2="1">
                                <stop offset="0%" stopColor="rgba(99,102,241,0.45)" />
                                <stop offset="100%" stopColor="rgba(99,102,241,0.02)" />
                            </linearGradient>
                        </defs>
                        <line x1="0" y1="20" x2="100" y2="20" className="nitro-emustats__chart-grid" />
                        <line x1="0" y1="40" x2="100" y2="40" className="nitro-emustats__chart-grid" />
                        <line x1="0" y1="60" x2="100" y2="60" className="nitro-emustats__chart-grid" />
                        <line x1="0" y1="80" x2="100" y2="80" className="nitro-emustats__chart-grid" />
                        { !!chart.areaPoints.length && <polygon points={ chart.areaPoints } fill="url(#emuStatsArea)" /> }
                        { !!chart.linePoints.length && <polyline points={ chart.linePoints } className="nitro-emustats__chart-line" /> }
                        { hoveredPoint &&
                            <>
                                <line x1={ hoveredPoint.x } y1="0" x2={ hoveredPoint.x } y2="100" className="nitro-emustats__chart-hover-line" />
                                <circle cx={ hoveredPoint.x } cy={ hoveredPoint.y } r="1.8" className="nitro-emustats__chart-hover-point" />
                            </> }
                    </svg>
                    { hoveredPoint &&
                        <div
                            className="nitro-emustats__chart-tooltip"
                            style={ {
                                left: `${ Math.min(88, Math.max(6, hoveredPoint.x)) }%`,
                                top: `${ Math.min(72, Math.max(6, hoveredPoint.y - 10)) }%`
                            } }
                        >
                            <strong>{ hoveredPoint.usedMb } MB</strong>
                            <span>{ hoveredPoint.usagePercent.toFixed(1) }%</span>
                            <small>{ formatDateTime(hoveredPoint.timestamp) }</small>
                        </div> }
                </div>
            </div>
        </div>
    );
};

const StatsTable = <TRow extends object>({ columns, rows, rowKey }: {
    columns: { key: keyof TRow; label: string; className?: string; render?: (row: TRow) => ReactNode; }[];
    rows: TRow[];
    rowKey: (row: TRow, index: number) => string;
}) =>
{
    return (
        <div className="nitro-emustats__table-shell">
            <table className="nitro-emustats__table">
                <thead>
                    <tr>
                        { columns.map(column => <th key={ String(column.key) } className={ column.className }>{ column.label }</th>) }
                    </tr>
                </thead>
                <tbody>
                    { rows.length === 0 &&
                        <tr>
                            <td colSpan={ columns.length } className="nitro-emustats__table-empty">Nothing to show right now.</td>
                        </tr> }
                    { rows.map((row, index) => (
                        <tr key={ rowKey(row, index) }>
                            { columns.map(column => (
                                <td key={ String(column.key) } className={ column.className }>
                                    { column.render ? column.render(row) : (row[column.key] as ReactNode) }
                                </td>
                            )) }
                        </tr>
                    )) }
                </tbody>
            </table>
        </div>
    );
};

const DetailPanel: FC<{ title: string; description?: string; children: ReactNode; }> = ({ title, description = '', children }) =>
{
    return (
        <div className="nitro-emustats__detail-panel">
            <div className="nitro-emustats__detail-panel-header">
                <h3>{ title }</h3>
                { !!description.length && <p>{ description }</p> }
            </div>
            { children }
        </div>
    );
};

const KeyValueGrid: FC<{ items: { label: string; value: string; tone?: 'default' | 'good' | 'warn'; }[]; columns?: 1 | 2; }> = ({ items, columns = 2 }) =>
{
    return (
        <div className={ `nitro-emustats__kv-grid is-${ columns }col` }>
            { items.map(item => (
                <div key={ item.label } className="nitro-emustats__kv-item">
                    <span>{ item.label }</span>
                    <strong data-tone={ item.tone || 'default' }>{ item.value }</strong>
                </div>
            )) }
        </div>
    );
};

const SystemSection: FC<{ snapshot: EmuStatsSnapshot }> = ({ snapshot }) =>
{
    const { databasePool, garbageCollector, network, overview, scheduler } = snapshot;

    return (
        <div className="nitro-emustats__detail-layout">
            <DetailPanel title="Database Pool" description="Current Hikari pool pressure and connection availability.">
                <KeyValueGrid
                    items={ [
                        { label: 'Active', value: formatCompactNumber(databasePool.activeConnections) },
                        { label: 'Idle', value: formatCompactNumber(databasePool.idleConnections) },
                        { label: 'Total', value: formatCompactNumber(databasePool.totalConnections) },
                        { label: 'Max', value: formatCompactNumber(databasePool.maxConnections) },
                        { label: 'Waiting Threads', value: formatCompactNumber(databasePool.waitingThreads), tone: databasePool.waitingThreads > 0 ? 'warn' : 'good' }
                    ] }
                />
            </DetailPanel>
            <DetailPanel title="Network Throughput" description="Realtime rates sampled from incoming and outgoing packet pipelines.">
                <KeyValueGrid
                    items={ [
                        { label: 'Incoming Packets/s', value: formatThroughput(network.incomingPacketsPerSecond, 'pkt') },
                        { label: 'Outgoing Packets/s', value: formatThroughput(network.outgoingPacketsPerSecond, 'pkt') },
                        { label: 'Incoming KB/s', value: formatThroughput(network.incomingKilobytesPerSecond, 'KB') },
                        { label: 'Outgoing KB/s', value: formatThroughput(network.outgoingKilobytesPerSecond, 'KB') },
                        { label: 'Total Incoming', value: formatCompactNumber(network.totalIncomingPackets) },
                        { label: 'Total Outgoing', value: formatCompactNumber(network.totalOutgoingPackets) }
                    ] }
                />
            </DetailPanel>
            <DetailPanel title="Scheduler" description="Executor load behind delayed tasks and internal service work.">
                <KeyValueGrid
                    items={ [
                        { label: 'Queued Tasks', value: formatCompactNumber(scheduler.queuedTasks), tone: scheduler.queuedTasks > 0 ? 'warn' : 'good' },
                        { label: 'Active Threads', value: formatCompactNumber(scheduler.activeThreads) },
                        { label: 'Pool Size', value: formatCompactNumber(scheduler.poolSize) },
                        { label: 'Completed Tasks', value: formatCompactNumber(scheduler.completedTasks) },
                        { label: 'Running', value: formatBoolean(scheduler.running), tone: scheduler.running ? 'good' : 'warn' }
                    ] }
                />
            </DetailPanel>
            <DetailPanel title="Garbage Collection" description="Observed JVM collection activity since emulator startup.">
                <KeyValueGrid
                    items={ [
                        { label: 'Total Collections', value: formatCompactNumber(garbageCollector.totalCollections) },
                        { label: 'Collections This Sample', value: formatCompactNumber(garbageCollector.collectionsSinceLastSample) },
                        { label: 'Total Pause Time', value: `${ formatCompactNumber(garbageCollector.totalCollectionTimeMs) } ms` },
                        { label: 'Last Observed Pause', value: `${ formatCompactNumber(garbageCollector.lastObservedPauseMs) } ms`, tone: garbageCollector.lastObservedPauseMs > 250 ? 'warn' : 'default' },
                        { label: 'Sampled At', value: formatDateTime(garbageCollector.sampledAtEpochMs) }
                    ] }
                />
            </DetailPanel>
            <DetailPanel title="Cycle Health" description="Aggregated timing from the active room update loop.">
                <KeyValueGrid
                    items={ [
                        { label: 'Average Room Cycle', value: formatMs(overview.averageRoomCycleMs) },
                        { label: 'Worst Room Cycle', value: formatMs(overview.worstRoomCycleMs), tone: overview.worstRoomCycleMs > 20 ? 'warn' : 'default' },
                        { label: 'Worst Room', value: formatRoomLabel(overview.worstRoomCycleRoomId, overview.worstRoomCycleRoomName) },
                        { label: 'WebSocket Sessions', value: `${ formatCompactNumber(overview.activeWebSocketSessions) } / ${ formatCompactNumber(overview.peakWebSocketSessions) } peak` }
                    ] }
                    columns={ 1 }
                />
            </DetailPanel>
        </div>
    );
};

const WiredInsightsSection: FC<{ snapshot: EmuStatsSnapshot }> = ({ snapshot }) =>
{
    const { overview } = snapshot;

    return (
        <div className="nitro-emustats__detail-layout">
            <DetailPanel title="Wired Pressure" description="Live summary of tick load, delayed actions and heavy rooms.">
                <KeyValueGrid
                    items={ [
                        { label: 'Tickables', value: formatCompactNumber(overview.wiredTickables) },
                        { label: 'Delayed Events', value: formatCompactNumber(overview.delayedEventsPending), tone: overview.delayedEventsPending > 0 ? 'warn' : 'good' },
                        { label: 'Heavy Rooms', value: formatCompactNumber(overview.heavyWiredRooms), tone: overview.heavyWiredRooms > 0 ? 'warn' : 'good' },
                        { label: 'Overloaded Rooms', value: formatCompactNumber(overview.overloadedWiredRooms), tone: overview.overloadedWiredRooms > 0 ? 'warn' : 'good' },
                        { label: 'Activity / Second', value: formatThroughput(overview.wiredActivityPerSecond, 'ops') }
                    ] }
                />
            </DetailPanel>
            <DetailPanel title="Top Wired Rooms" description="Highest usage rooms in the current diagnostics window.">
                <StatsTable<EmuStatsWiredTopRoomRow>
                    columns={ [
                        { key: 'roomId', label: 'Room', className: 'is-xs' },
                        { key: 'name', label: 'Name' },
                        { key: 'usagePercent', label: 'Usage', className: 'is-xs', render: row => `${ row.usagePercent }%` },
                        { key: 'averageTickMs', label: 'Avg Tick', className: 'is-sm', render: row => `${ row.averageTickMs } ms` },
                        { key: 'peakTickMs', label: 'Peak Tick', className: 'is-sm', render: row => `${ row.peakTickMs } ms` },
                        { key: 'delayedEventsPending', label: 'Delayed', className: 'is-xs' },
                        { key: 'activityPerSecond', label: 'Ops/s', className: 'is-sm', render: row => row.activityPerSecond.toFixed(1) },
                        { key: 'heavy', label: 'Heavy', className: 'is-sm', render: row => formatBoolean(row.heavy) }
                    ] }
                    rowKey={ row => `wired-top-${ row.roomId }` }
                    rows={ snapshot.wiredTopRooms }
                />
            </DetailPanel>
        </div>
    );
};

const MetricCard: FC<{ title: string; value: string; subtitle?: string; accent?: string; }> = ({ title, value, subtitle = '', accent }) =>
{
    return (
        <div className="nitro-emustats__metric-card" style={ accent ? { '--emustats-accent': accent } as CSSProperties : undefined }>
            <span>{ title }</span>
            <strong>{ value }</strong>
            { !!subtitle.length && <small>{ subtitle }</small> }
        </div>
    );
};

export const EmuStatsView: FC<{}> = () =>
{
    const [ isVisible, setIsVisible ] = useState(false);
    const [ isLoading, setIsLoading ] = useState(false);
    const [ error, setError ] = useState<string>(null);
    const [ section, setSection ] = useState<EmuStatsSection>('overview');
    const [ version, setVersion ] = useState(0);

    useEffect(() =>
    {
        const linkTracker: ILinkEventTracker = {
            eventUrlPrefix: 'emustats/',
            linkReceived: url =>
            {
                const parts = url.split('/');

                if(parts.length < 2) return;

                switch(parts[1])
                {
                    case 'show':
                        setIsVisible(true);
                        return;
                    case 'hide':
                        setIsVisible(false);
                        return;
                    case 'toggle':
                        setIsVisible(value => !value);
                        return;
                    case 'refresh':
                        setVersion(value => value + 1);
                        return;
                }
            }
        };

        AddLinkEventTracker(linkTracker);

        return () => RemoveLinkEventTracker(linkTracker);
    }, []);

    useEffect(() =>
    {
        if(!isVisible) return;

        let cancelled = false;

        const load = async (force = false) =>
        {
            try
            {
                setIsLoading(true);
                const payload = await fetchEmuStats(force);

                if(cancelled) return;

                if(payload) setError(null);
            }
            catch(err)
            {
                if(cancelled) return;

                setError(String((err as Error)?.message || err));
            }
            finally
            {
                if(!cancelled) setIsLoading(false);
            }
        };

        void load(version > 0);

        const interval = window.setInterval(() => void load(true), REFRESH_INTERVAL_MS);

        return () =>
        {
            cancelled = true;
            window.clearInterval(interval);
        };
    }, [ isVisible, version ]);

    const snapshot = getCachedEmuStats();
    const overview = snapshot?.overview;
    const session = GetSessionDataManager();

    const navItems: { key: EmuStatsSection; label: string; count?: number; }[] = [
        { key: 'overview', label: 'Overview' },
        { key: 'system', label: 'System Health' },
        { key: 'wiredInsights', label: 'Wired Insights', count: snapshot?.wiredTopRooms?.length || 0 },
        { key: 'wired', label: 'Wired Diagnostics', count: snapshot?.wired?.length || 0 },
        { key: 'users', label: 'Online Users', count: snapshot?.users?.length || 0 },
        { key: 'rooms', label: 'Active Rooms', count: snapshot?.rooms?.length || 0 }
    ];

    const content = useMemo(() =>
    {
        if(!snapshot || !overview) return null;

        switch(section)
        {
            case 'system':
                return <SystemSection snapshot={ snapshot } />;
            case 'wiredInsights':
                return <WiredInsightsSection snapshot={ snapshot } />;
            case 'users':
                return (
                    <StatsTable<EmuStatsUserRow>
                        columns={ [
                            { key: 'id', label: 'ID', className: 'is-xs' },
                            { key: 'username', label: 'Username' },
                            { key: 'rank', label: 'Rank' },
                            { key: 'credits', label: 'Credits', className: 'is-sm' },
                            { key: 'roomId', label: 'Room ID', className: 'is-sm' }
                        ] }
                        rowKey={ row => `user-${ row.id }` }
                        rows={ snapshot.users }
                    />
                );
            case 'rooms':
                return (
                    <StatsTable<EmuStatsRoomRow>
                        columns={ [
                            { key: 'roomId', label: 'Room', className: 'is-xs' },
                            { key: 'name', label: 'Name' },
                            { key: 'players', label: 'Players', className: 'is-xs' },
                            { key: 'items', label: 'Items', className: 'is-xs' },
                            { key: 'tickables', label: 'Tickables', className: 'is-xs' },
                            { key: 'cpuMs', label: 'CPU (ms)', className: 'is-sm', render: row => row.cpuMs.toFixed(2) },
                            { key: 'estimatedRamKb', label: 'RAM (KB)', className: 'is-sm' },
                            { key: 'thread', label: 'Thread', className: 'is-md' }
                        ] }
                        rowKey={ row => `room-${ row.roomId }` }
                        rows={ snapshot.rooms }
                    />
                );
            case 'wired':
                return (
                    <StatsTable<EmuStatsWiredRow>
                        columns={ [
                            { key: 'roomId', label: 'Room', className: 'is-xs' },
                            { key: 'averageTickMs', label: 'Avg Tick', className: 'is-sm', render: row => `${ row.averageTickMs } ms` },
                            { key: 'peakTickMs', label: 'Peak Tick', className: 'is-sm', render: row => `${ row.peakTickMs } ms` },
                            { key: 'usagePercent', label: 'Usage', className: 'is-xs', render: row => `${ row.usagePercent }%` },
                            { key: 'delayedEventsPending', label: 'Delayed', className: 'is-xs' },
                            { key: 'overloaded', label: 'Overloaded', className: 'is-sm', render: row => formatBoolean(row.overloaded) },
                            { key: 'heavy', label: 'Heavy', className: 'is-sm', render: row => formatBoolean(row.heavy) }
                        ] }
                        rowKey={ row => `wired-${ row.roomId }` }
                        rows={ snapshot.wired }
                    />
                );
            case 'overview':
            default:
                return (
                    <div className="nitro-emustats__overview">
                        <div className="nitro-emustats__overview-cards">
                            <MetricCard title="Uptime" accent="#6366f1" value={ formatUptime(overview.uptimeSeconds) } />
                            <MetricCard title="Last Refresh" accent="#22c55e" value={ formatDateTime(overview.lastRefreshEpochMs) } />
                            <MetricCard title="GUI Status" accent="#f59e0b" value={ overview.guiStatus } />
                            <MetricCard title="Memory Allocation" value={ formatMemory(overview.memoryUsedMb, overview.memoryMaxMb) } subtitle={ `${ overview.memoryAllocatedMb } MB allocated` } />
                            <MetricCard title="CPU Load" value={ formatCpu(overview.cpuLoadPercent) } />
                            <MetricCard title="Active OS Threads" value={ String(overview.activeOsThreads) } />
                            <MetricCard title="Connected Players" value={ String(overview.connectedPlayers) } />
                            <MetricCard title="Peak Players" value={ String(overview.peakPlayers) } />
                            <MetricCard title="Loaded Rooms" value={ String(overview.loadedRooms) } />
                            <MetricCard title="Wired Tickables" value={ String(overview.wiredTickables) } />
                            <MetricCard title="WS Sessions" value={ `${ overview.activeWebSocketSessions } / ${ overview.peakWebSocketSessions }` } subtitle="current / peak" />
                            <MetricCard title="Avg Room Cycle" value={ formatMs(overview.averageRoomCycleMs) } />
                        </div>
                        <MemoryChart history={ snapshot.memoryHistory } />
                    </div>
                );
        }
    }, [ overview, section, snapshot ]);

    if(!isVisible) return null;

    return (
        <NitroCardView className="nitro-emustats-window w-[980px] h-[620px]" isResizable={ false } theme="primary-slim" uniqueKey="emu-stats">
            <NitroCardHeaderView headerText="Emulator Stats" onCloseClick={ () => setIsVisible(false) } />
            <NitroCardContentView classNames={ [ 'nitro-emustats-window__content' ] }>
                <div className="nitro-emustats">
                    <aside className="nitro-emustats__sidebar">
                        <div className="nitro-emustats__sidebar-brand">
                            <h2>Arcturus</h2>
                            <p>{ session?.userName || 'Operator' }</p>
                        </div>
                        <nav className="nitro-emustats__nav">
                            { navItems.map(item => (
                                <button
                                    key={ item.key }
                                    className={ `nitro-emustats__nav-button ${ section === item.key ? 'is-active' : '' }` }
                                    onClick={ () => setSection(item.key) }
                                    type="button"
                                >
                                    <span>{ item.label }</span>
                                    { typeof item.count === 'number' && <strong>{ item.count }</strong> }
                                </button>
                            )) }
                        </nav>
                        <div className="nitro-emustats__sidebar-footer">
                            <button className="nitro-emustats__refresh-button" onClick={ () => setVersion(value => value + 1) } type="button">
                                Refresh now
                            </button>
                            <p>Auto refresh every { REFRESH_INTERVAL_MS / 1000 }s</p>
                        </div>
                    </aside>
                    <section className="nitro-emustats__main">
                        <div className="nitro-emustats__header">
                            <div>
                                <h1>{ navItems.find(item => item.key === section)?.label || 'Overview' }</h1>
                                <p>Live operational view of emulator health, activity and wired performance.</p>
                            </div>
                            { overview &&
                                <div className="nitro-emustats__status-pill" data-status={ overview.guiStatus.toLowerCase().replace(/\s+/g, '-') }>
                                    { overview.guiStatus }
                                </div> }
                        </div>
                        { error &&
                            <div className="nitro-emustats__error">
                                { error }
                            </div> }
                        { isLoading && !snapshot &&
                            <div className="nitro-emustats__empty">
                                Loading emulator stats...
                            </div> }
                        { !isLoading && !snapshot && !error &&
                            <div className="nitro-emustats__empty">
                                No emulator stats available yet.
                            </div> }
                        { snapshot &&
                            <div className="nitro-emustats__body" style={ { '--emustats-section': `"${ section }"` } as CSSProperties }>
                                { content }
                            </div> }
                    </section>
                </div>
            </NitroCardContentView>
        </NitroCardView>
    );
};
