import { useState, useEffect, useMemo } from 'react';
import type { BotState } from '../hooks/useWebSocket';
import { useAuth } from '../components/AuthContext';
import { aggregateCanonicalLifecycleTrades } from '../lib/orderLifecycleLedger';
import { useCanonicalLifecycle } from '../hooks/useCanonicalLifecycle';
import { fetchTradeProfiles } from '../lib/profileApi';
import { Button } from '../components/ui/Primitives';

interface OverviewTabProps {
    botState: BotState;
    previewAsCustomer?: boolean;
    connected?: boolean;
}

interface ActiveProfileCapital {
    id: string;
    name: string;
    allocated: number;
    cooldownMinutes: number;
}

interface TradeAggregate {
    tradeCount: number;
    wins: number;
    winRate: number;
    netPnl: number;
    lastClosedTradeAt: number;
}

interface ProfileSignalAggregate {
    totalSignals: number;
    activeSignals: number;
    blockedSignals: number;
    skippedSignals: number;
    executedSignals: number;
}

type WinRateWindow = '24h' | '7d' | '30d' | 'all';

const WIN_RATE_WINDOW_OPTIONS: Array<{ key: WinRateWindow; label: string; ms?: number }> = [
    { key: '24h', label: '24H', ms: 24 * 60 * 60 * 1000 },
    { key: '7d', label: '7D', ms: 7 * 24 * 60 * 60 * 1000 },
    { key: '30d', label: '30D', ms: 30 * 24 * 60 * 60 * 1000 },
    { key: 'all', label: 'All' }
];
const REFRESH_INTERVAL_MS = 30_000;
const overviewWarningBorder = '1px solid color-mix(in oklab, var(--bl-warning) 28%, transparent)';
const overviewWarningSurface = 'var(--bl-warning-muted)';
const overviewWarningText = 'var(--bl-warning)';
const overviewDangerBorder = '1px solid color-mix(in oklab, var(--bl-danger) 28%, transparent)';
const overviewDangerSurface = 'var(--bl-danger-muted)';
const overviewDangerText = 'var(--bl-danger)';
const overviewMutedText = 'var(--bl-text-faint)';
const overviewQuietText = 'var(--bl-text-quiet)';
const overviewInfoText = 'var(--bl-info-strong)';
const overviewAttentionText = 'var(--bl-warning)';
const overviewSuccessText = 'var(--bl-success)';
const overviewNeutralText = 'var(--foreground)';
const overviewSoftBorder = '1px solid var(--bl-border-subtle)';
const overviewActiveBorder = '1px solid color-mix(in oklab, var(--bl-success) 45%, transparent)';
const overviewActiveSurface = 'color-mix(in oklab, var(--bl-success) 8%, transparent)';
const overviewMutedSurface = 'color-mix(in oklab, var(--foreground) 3%, transparent)';
const overviewSectionBorder = '1px solid color-mix(in oklab, var(--bl-border) 70%, transparent)';
const overviewCardGradient = 'linear-gradient(145deg, color-mix(in oklab, var(--bl-surface-overlay) 92%, var(--card-elevated)), color-mix(in oklab, var(--bl-surface-overlay) 84%, var(--background)))';
const overviewCardBorder = '1px solid color-mix(in oklab, var(--bl-border) 55%, transparent)';
const overviewDivider = '1px solid color-mix(in oklab, var(--bl-border) 45%, transparent)';
const overviewBotMuted = 'color-mix(in oklab, var(--muted-foreground) 62%, var(--background))';
const overviewBotQuiet = 'color-mix(in oklab, var(--muted-foreground) 52%, var(--background))';
const overviewTagBorder = '1px solid color-mix(in oklab, var(--bl-border) 82%, transparent)';


const formatUptime = (ms: number): string => {
    if (ms < 60000) return `${Math.floor(ms / 1000)}s`;
    if (ms < 3600000) return `${Math.floor(ms / 60000)}m`;
    const hours = Math.floor(ms / 3600000);
    const mins = Math.floor((ms % 3600000) / 60000);
    return `${hours}h ${mins}m`;
};

const formatDurationCompact = (ms: number): string => {
    if (!Number.isFinite(ms) || ms <= 0) return '0m';
    const totalMinutes = Math.max(0, Math.floor(ms / 60000));
    const days = Math.floor(totalMinutes / 1440);
    const hours = Math.floor((totalMinutes % 1440) / 60);
    const minutes = totalMinutes % 60;
    if (days > 0) return `${days}d ${hours}h`;
    if (hours > 0) return `${hours}h ${minutes}m`;
    return `${minutes}m`;
};

const formatUsd = (value: number): string =>
    `$${value.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;

const compactTag = (value?: string): string => {
    const token = String(value || '').trim();
    if (!token) return '-';
    return token.length > 24 ? `${token.slice(0, 12)}...${token.slice(-8)}` : token;
};

export const dedupeLivePositions = (positions: BotState['positions'] = []): BotState['positions'] => {
    const mergedByKey = new Map<string, BotState['positions'][0]>();

    const score = (position: BotState['positions'][0]): number => {
        const tradeScore = position.tradeId ? 4 : 0;
        const profileScore = position.profileId ? 3 : 0;
        const userScore = position.profileName ? 1 : 0;
        const notional = Math.abs(Number(position.entryPrice || 0) * Number(position.size || 0));
        return tradeScore + profileScore + userScore + Math.min(notional, 100_000);
    };

    for (const position of positions || []) {
        const tradeId = String(position.tradeId || '').trim();
        const key = tradeId
            ? `trade:${tradeId}`
            : `fallback:${position.profileId || 'global'}|${position.symbol}|${position.side}`;

        const existing = mergedByKey.get(key);
        if (!existing) {
            mergedByKey.set(key, position);
            continue;
        }

        const preferred = score(position) >= score(existing) ? position : existing;
        const fallback = preferred === position ? existing : position;
        mergedByKey.set(key, {
            ...fallback,
            ...preferred,
            profileId: preferred.profileId || fallback.profileId,
            profileName: preferred.profileName || fallback.profileName,
            tradeId: preferred.tradeId || fallback.tradeId
        });
    }

    return Array.from(mergedByKey.values());
};

export const OverviewTab = ({ botState, previewAsCustomer = false, connected = true }: OverviewTabProps) => {
    const { user, profile } = useAuth();
    const {
        snapshot: canonicalSnapshot,
        loading: canonicalLoading,
        error: canonicalError
    } = useCanonicalLifecycle();
    const isAdminView = profile?.role === 'admin' && !previewAsCustomer;
    const symbols = Object.keys(botState.symbols || {});
    const [fallbackCapital, setFallbackCapital] = useState(botState.settings.totalCapital);
    const [profileCount, setProfileCount] = useState(0);
    const [activeProfiles, setActiveProfiles] = useState<ActiveProfileCapital[]>([]);
    const [winRateWindow, setWinRateWindow] = useState<WinRateWindow>('7d');
    const canonicalLifecycleReady = Boolean(canonicalSnapshot && !canonicalSnapshot.diagnostics?.truncated);

    useEffect(() => {
        if (!user) return;
        let cancelled = false;

        const loadStats = async () => {
            if (cancelled) return;

            try {
                const profilesData = await fetchTradeProfiles({ scope: profile?.role === 'admin' ? 'all' : 'user' });

                const activeProfileRows: ActiveProfileCapital[] = ((profilesData as any[]) || [])
                    .filter((p: any) => Boolean(p.is_active))
                    .map((p: any) => {
                        const rawCooldown = Number(p?.strategy_config?.execution?.cooldownMinutes);
                        return {
                            id: String(p.id),
                            name: String(p.name || p.id),
                            allocated: Number(p.allocated_capital || 0),
                            cooldownMinutes: Number.isFinite(rawCooldown) && rawCooldown >= 0 ? rawCooldown : 30
                        };
                    });

                const activeCapital = activeProfileRows.reduce((sum, p) => sum + p.allocated, 0);
                if (cancelled) return;
                setFallbackCapital(activeCapital || botState.settings.totalCapital);
                setProfileCount(activeProfileRows.length);
                setActiveProfiles(activeProfileRows);
            } catch (err) {
                console.error('[OverviewTab] Unexpected load error:', err);
            }
        };
        loadStats();
        const refreshTimer = window.setInterval(loadStats, REFRESH_INTERVAL_MS);
        return () => {
            cancelled = true;
            window.clearInterval(refreshTimer);
        };
    }, [user, profile?.role, botState.settings.totalCapital]);

    const lifecycleOpenByProfile = useMemo(() => {
        if (canonicalLifecycleReady && canonicalSnapshot) {
            const usedByProfile = new Map<string, number>();
            const unrealizedByProfile = new Map<string, number>();
            const openTradesByProfile = new Map<string, number>();
            for (const [profileId, aggregate] of Object.entries(canonicalSnapshot.aggregates.byProfile || {})) {
                const openNotional = Number(aggregate.openNotional || 0);
                const unrealizedPnl = Number(aggregate.unrealizedPnl || 0);
                const openTrades = Number(aggregate.openTrades || 0);
                if (openNotional > 0) usedByProfile.set(profileId, openNotional);
                if (Math.abs(unrealizedPnl) > 0) unrealizedByProfile.set(profileId, unrealizedPnl);
                if (openTrades > 0) openTradesByProfile.set(profileId, openTrades);
            }

            return {
                hasRows: true,
                usedByProfile,
                unrealizedByProfile,
                openTradesByProfile
            };
        }
        return {
            hasRows: false,
            usedByProfile: new Map<string, number>(),
            unrealizedByProfile: new Map<string, number>(),
            openTradesByProfile: new Map<string, number>()
        };
    }, [canonicalLifecycleReady, canonicalSnapshot]);

    const liveOpenByProfile = useMemo(() => {
        const usedByProfile = new Map<string, number>();
        const unrealizedByProfile = new Map<string, number>();
        const openTradesByProfile = new Map<string, number>();
        const deduped = dedupeLivePositions(botState.positions || []);

        for (const position of deduped) {
            const profileId = String(position.profileId || '').trim();
            if (!profileId) continue;

            const notional = Math.max(0, Math.abs(Number(position.entryPrice || 0) * Number(position.size || 0)));
            const unrealized = Number(position.unrealizedPnl || 0);

            usedByProfile.set(profileId, (usedByProfile.get(profileId) || 0) + notional);
            unrealizedByProfile.set(profileId, (unrealizedByProfile.get(profileId) || 0) + unrealized);
            openTradesByProfile.set(profileId, (openTradesByProfile.get(profileId) || 0) + 1);
        }

        return {
            hasRows: deduped.length > 0,
            usedByProfile,
            unrealizedByProfile,
            openTradesByProfile
        };
    }, [botState.positions]);

    const effectiveOpenByProfile = useMemo(() => {
        const usedByProfile = new Map<string, number>(lifecycleOpenByProfile.usedByProfile);
        const unrealizedByProfile = new Map<string, number>(lifecycleOpenByProfile.unrealizedByProfile);
        const openTradesByProfile = new Map<string, number>(lifecycleOpenByProfile.openTradesByProfile);
        const suppressedLifecycleNotionalByProfile = new Map<string, number>();

        // If lifecycle still claims open notional while live inventory is flat, prefer live 0 usage
        // to avoid stale capital-lock visuals in Overview while reconciliation catches up.
        for (const [profileId, canonicalUsedRaw] of usedByProfile.entries()) {
            const canonicalUsed = Math.max(0, Number(canonicalUsedRaw || 0));
            if (!(canonicalUsed > 1e-8)) continue;

            const canonicalOpenCount = Number(openTradesByProfile.get(profileId) || 0);
            const liveUsed = Math.max(0, Number(liveOpenByProfile.usedByProfile.get(profileId) || 0));
            const liveOpenCount = Number(liveOpenByProfile.openTradesByProfile.get(profileId) || 0);
            if (canonicalOpenCount <= 0) continue;

            if (liveOpenCount <= 0 && !(liveUsed > 1e-8)) {
                suppressedLifecycleNotionalByProfile.set(profileId, canonicalUsed);
                usedByProfile.set(profileId, 0);
                openTradesByProfile.set(profileId, 0);
                unrealizedByProfile.delete(profileId);
            }
        }

        for (const [profileId, liveUsed] of liveOpenByProfile.usedByProfile.entries()) {
            const canonicalUsed = Number(usedByProfile.get(profileId) || 0);
            if (!(canonicalUsed > 0)) {
                usedByProfile.set(profileId, liveUsed);
            }
        }

        for (const [profileId, liveUnrealized] of liveOpenByProfile.unrealizedByProfile.entries()) {
            const canonicalUnrealized = Number(unrealizedByProfile.get(profileId) || 0);
            if (Math.abs(canonicalUnrealized) <= 1e-8) {
                unrealizedByProfile.set(profileId, liveUnrealized);
            }
        }

        for (const [profileId, liveOpenCount] of liveOpenByProfile.openTradesByProfile.entries()) {
            const canonicalOpenCount = Number(openTradesByProfile.get(profileId) || 0);
            if (liveOpenCount > canonicalOpenCount) {
                openTradesByProfile.set(profileId, liveOpenCount);
            }
        }

        return {
            hasRows: lifecycleOpenByProfile.hasRows || liveOpenByProfile.hasRows,
            usedByProfile,
            unrealizedByProfile,
            openTradesByProfile,
            suppressedLifecycleNotionalByProfile
        };
    }, [lifecycleOpenByProfile, liveOpenByProfile]);

    const openPositionsByProfile = useMemo(() => {
        return effectiveOpenByProfile.openTradesByProfile;
    }, [effectiveOpenByProfile]);

    const profileSignalsByProfile = useMemo(() => {
        const byProfile = new Map<string, ProfileSignalAggregate>();
        for (const symbol of Object.keys(botState.symbols || {})) {
            const symbolState = botState.symbols[symbol];
            const entries = Object.entries(symbolState?.profileSignals || {});
            for (const [profileId, signalState] of entries) {
                const current = byProfile.get(profileId) || {
                    totalSignals: 0,
                    activeSignals: 0,
                    blockedSignals: 0,
                    skippedSignals: 0,
                    executedSignals: 0
                };
                current.totalSignals += 1;

                const signal = String((signalState as any)?.signal || '').toUpperCase();
                const passed = Boolean((signalState as any)?.passed);
                const directional = signal === 'BUY' || signal === 'SELL';
                const executionStatus = String((signalState as any)?.execution?.status || '').toUpperCase();
                if (passed && directional) {
                    if (executionStatus === 'BLOCKED') {
                        current.blockedSignals += 1;
                    } else if (executionStatus === 'SKIPPED') {
                        current.skippedSignals += 1;
                    } else {
                        current.activeSignals += 1;
                        if (executionStatus === 'EXECUTED') {
                            current.executedSignals += 1;
                        }
                    }
                }

                byProfile.set(profileId, current);
            }
        }
        return byProfile;
    }, [botState.symbols]);

    const canonicalLifecycleTrades = useMemo(() => {
        if (canonicalLifecycleReady && canonicalSnapshot) {
            return canonicalSnapshot.realizedTrades.map((trade) => ({
                id: trade.id,
                tradeId: trade.tradeId,
                profileId: trade.profileId,
                symbol: trade.symbol,
                side: trade.side,
                size: Number(trade.size || 0),
                entryPrice: Number(trade.entryPrice || 0),
                exitPrice: Number(trade.exitPrice || 0),
                pnl: Number(trade.pnl || 0),
                pnlPercent: Number(trade.pnlPercent || 0),
                closedAtMs: Number(trade.closedAt || 0)
            }));
        }
        return [];
    }, [canonicalLifecycleReady, canonicalSnapshot]);
    const hasCanonicalLifecyclePnl = canonicalLifecycleReady;
    const canonicalAggregate = useMemo(
        () => aggregateCanonicalLifecycleTrades(canonicalLifecycleTrades),
        [canonicalLifecycleTrades]
    );
    const winRateWindowConfig = useMemo(
        () => WIN_RATE_WINDOW_OPTIONS.find((option) => option.key === winRateWindow) || WIN_RATE_WINDOW_OPTIONS[1],
        [winRateWindow]
    );

    const canonicalWindowTrades = useMemo(() => {
        if (!winRateWindowConfig.ms) return canonicalLifecycleTrades;
        const cutoff = Date.now() - winRateWindowConfig.ms;
        return canonicalLifecycleTrades.filter((trade) => Number(trade.closedAtMs || 0) >= cutoff);
    }, [canonicalLifecycleTrades, winRateWindowConfig.ms]);
    const canonicalWindowAggregate = useMemo(
        () => aggregateCanonicalLifecycleTrades(canonicalWindowTrades),
        [canonicalWindowTrades]
    );

    const displayRealizedPnl = hasCanonicalLifecyclePnl
        ? canonicalAggregate.totalPnl
        : 0;
    const displayWindowAggregate = hasCanonicalLifecyclePnl
        ? canonicalWindowAggregate
        : { totalPnl: 0, tradeCount: 0, wins: 0, winRate: 0, byProfile: {} as Record<string, TradeAggregate> };

    const pnlWindow = useMemo(() => {
        if (hasCanonicalLifecyclePnl) {
            const timestamps = canonicalLifecycleTrades
                .map((trade) => Number(trade.closedAtMs || 0))
                .filter((ts) => Number.isFinite(ts) && ts > 0);
            if (timestamps.length === 0) {
                return {
                    durationLabel: '-',
                    fromTs: 0,
                    toTs: 0
                };
            }

            const fromTs = Math.min(...timestamps);
            const toTs = Math.max(...timestamps);
            return {
                durationLabel: formatDurationCompact(Math.max(0, toTs - fromTs)),
                fromTs,
                toTs
            };
        }
        return {
            durationLabel: '-',
            fromTs: 0,
            toTs: 0
        };
    }, [canonicalLifecycleTrades, hasCanonicalLifecyclePnl]);

    const profileTradeStats = useMemo(() => {
        const aggregates: Record<string, TradeAggregate> = {};
        const source = hasCanonicalLifecyclePnl ? canonicalAggregate.byProfile : {};
        for (const [profileId, agg] of Object.entries(source)) {
            aggregates[profileId] = {
                tradeCount: agg.tradeCount,
                wins: agg.wins,
                winRate: agg.winRate,
                netPnl: agg.realizedPnl,
                lastClosedTradeAt: agg.lastClosedTradeAt
            };
        }
        return aggregates;
    }, [canonicalAggregate.byProfile, hasCanonicalLifecyclePnl]);

    const profileWindowStats = useMemo(() => {
        const aggregates: Record<string, { tradeCount: number; winRate: number }> = {};
        for (const [profileId, agg] of Object.entries(displayWindowAggregate.byProfile)) {
            aggregates[profileId] = {
                tradeCount: agg.tradeCount,
                winRate: agg.winRate
            };
        }
        return aggregates;
    }, [displayWindowAggregate.byProfile]);

    const unrealizedPnl = useMemo(() => {
        if (!effectiveOpenByProfile.hasRows) return 0;
        return Array.from(effectiveOpenByProfile.unrealizedByProfile.values()).reduce((sum, value) => sum + value, 0);
    }, [effectiveOpenByProfile]);

    const netPnl = displayRealizedPnl + unrealizedPnl;

    const profileCapitalRows = useMemo(() => {
        const usedByProfile = effectiveOpenByProfile.usedByProfile;
        const suppressedLifecycleNotionalByProfile = effectiveOpenByProfile.suppressedLifecycleNotionalByProfile;

        const now = Date.now();
        return activeProfiles.map((profileRow) => {
            const allocated = Math.max(0, Number(profileRow.allocated || 0));
            const rawUsed = Math.max(0, Number(usedByProfile.get(profileRow.id) || 0));
            const suppressedLifecycleNotional = Math.max(0, Number(suppressedLifecycleNotionalByProfile?.get(profileRow.id) || 0));
            const used = Math.min(rawUsed, allocated);
            const overAllocatedAmount = Math.max(0, rawUsed - allocated);
            const remaining = Math.max(0, allocated - used);
            const utilizationPct = allocated > 0 ? (used / allocated) * 100 : 0;

            const tradeStats = profileTradeStats[profileRow.id] || {
                tradeCount: 0,
                wins: 0,
                winRate: 0,
                netPnl: 0,
                lastClosedTradeAt: 0
            };
            const windowStats = profileWindowStats[profileRow.id] || {
                tradeCount: 0,
                winRate: 0
            };

            const openCount = openPositionsByProfile.get(profileRow.id) || 0;
            const signalStats = profileSignalsByProfile.get(profileRow.id) || {
                totalSignals: 0,
                activeSignals: 0,
                blockedSignals: 0,
                skippedSignals: 0,
                executedSignals: 0
            };

            const cooldownMs = Math.max(0, Number(profileRow.cooldownMinutes || 0)) * 60_000;
            let cooldownRemainingMs = 0;
            if (openCount === 0 && cooldownMs > 0 && tradeStats.lastClosedTradeAt > 0) {
                const elapsed = now - tradeStats.lastClosedTradeAt;
                if (elapsed < cooldownMs) {
                    cooldownRemainingMs = cooldownMs - elapsed;
                }
            }

            let runtimeState = 'Monitoring (no signal)';
            let runtimeDetail = 'Rules are running; waiting for entry setup.';
            let runtimeTone: 'running' | 'cooldown' | 'armed' | 'blocked' | 'idle' = 'idle';

            if (suppressedLifecycleNotional > 1e-8) {
                runtimeState = 'Lifecycle sync pending';
                runtimeDetail = `Canonical lifecycle still reports ${formatUsd(suppressedLifecycleNotional)} open notional, but live inventory is flat. Utilization is temporarily based on live state.`;
                runtimeTone = 'blocked';
            } else if (overAllocatedAmount > 1e-8) {
                runtimeState = 'Capital sync warning';
                runtimeDetail = `Raw open-position notional is ${formatUsd(overAllocatedAmount)} above allocated capital. Showing capped utilization for clarity.`;
                runtimeTone = 'armed';
            } else if (openCount > 0) {
                runtimeState = `In Position (${openCount} open)`;
                runtimeDetail = 'Capital is deployed in active open positions.';
                runtimeTone = 'running';
            } else if (cooldownRemainingMs > 0) {
                runtimeState = `Cooldown (wake up in ${Math.ceil(cooldownRemainingMs / 60000)}m)`;
                runtimeDetail = 'Recent close detected; profile is waiting for cooldown expiry.';
                runtimeTone = 'cooldown';
            } else if (signalStats.blockedSignals > 0 && signalStats.activeSignals === 0) {
                runtimeState = 'Signal blocked by guard';
                runtimeDetail = 'Directional setup exists, but execution guards blocked entry (pause/capital/risk/cooldown).';
                runtimeTone = 'blocked';
            } else if (signalStats.executedSignals > 0 && signalStats.activeSignals > 0) {
                runtimeState = 'Entry submitted, awaiting fill';
                runtimeDetail = 'Signal executed recently and waiting for broker fill confirmation.';
                runtimeTone = 'armed';
            } else if (signalStats.activeSignals > 0) {
                if (profileRow.allocated <= 0) {
                    runtimeState = 'Signal active, no allocation';
                    runtimeDetail = 'Allocated capital is 0. Increase allocation to place entries.';
                } else if (remaining <= 1e-8) {
                    runtimeState = 'Signal active, capital full';
                    runtimeDetail = 'No free capital remains in this profile right now.';
                } else {
                    runtimeState = 'Signal active, waiting entry';
                    runtimeDetail = 'No filled entry yet. Utilization will increase once an entry fills.';
                }
                runtimeTone = 'armed';
            }

            return {
                ...profileRow,
                allocated,
                rawUsed,
                used,
                overAllocatedAmount,
                remaining,
                utilizationPct,
                winRate: windowStats.winRate,
                tradeCount: windowStats.tradeCount,
                netPnl: tradeStats.netPnl,
                runtimeState,
                runtimeDetail,
                runtimeTone
            };
        });
    }, [
        activeProfiles,
        effectiveOpenByProfile,
        profileSignalsByProfile,
        profileTradeStats,
        profileWindowStats,
        openPositionsByProfile
    ]);

    const allocatedCapital = useMemo(() => {
        if (profileCapitalRows.length > 0) {
            return profileCapitalRows.reduce((sum, row) => sum + row.allocated, 0);
        }
        return Number(fallbackCapital || 0);
    }, [profileCapitalRows, fallbackCapital]);

    const capitalUsed = useMemo(() => {
        if (profileCapitalRows.length > 0) {
            return profileCapitalRows.reduce((sum, row) => sum + row.used, 0);
        }
        return 0;
    }, [profileCapitalRows]);

    const rawCapitalUsed = useMemo(() => {
        if (profileCapitalRows.length > 0) {
            return profileCapitalRows.reduce((sum, row) => sum + row.rawUsed, 0);
        }
        return 0;
    }, [profileCapitalRows]);

    const overAllocatedCapital = Math.max(0, rawCapitalUsed - capitalUsed);
    const remainingCapital = Math.max(0, allocatedCapital - capitalUsed);
    const canonicalUnavailable = !canonicalLifecycleReady || !!canonicalError;

    return (
        <div className="overview-tab">
            <div className="tab-header">
                <h2>Market Readiness</h2>
                <p>Global view of market conditions and bot status.</p>
            </div>

            {canonicalUnavailable && (
                <div style={{
                    marginBottom: '12px',
                    padding: '8px 10px',
                    borderRadius: '8px',
                    border: overviewWarningBorder,
                    background: overviewWarningSurface,
                    color: overviewWarningText,
                    fontSize: '0.75rem'
                }}>
                    Canonical lifecycle is unavailable{canonicalLoading ? ' (loading)' : ''}. Showing fallback values from DB/runtime sources.
                    {canonicalError ? ` ${canonicalError}` : ''}
                </div>
            )}
            {canonicalSnapshot?.diagnostics?.truncated && (
                <div style={{
                    marginBottom: '12px',
                    padding: '8px 10px',
                    borderRadius: '8px',
                    border: overviewDangerBorder,
                    background: overviewDangerSurface,
                    color: overviewDangerText,
                    fontSize: '0.75rem'
                }}>
                    Canonical lifecycle snapshot is truncated ({canonicalSnapshot.diagnostics.orderRows} rows). Narrow scope before using this for operational decisions.
                </div>
            )}

            <div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '12px', flexWrap: 'wrap' }}>
                <span style={{ fontSize: '0.72rem', color: overviewMutedText, textTransform: 'uppercase', letterSpacing: '0.04em' }}>
                    Win Rate Window:
                </span>
                {WIN_RATE_WINDOW_OPTIONS.map((option) => {
                    const active = option.key === winRateWindow;
                    return (
                        <Button
                            type="button"
                            key={option.key}
                            onClick={() => setWinRateWindow(option.key)}
                            variant={active ? 'secondary' : 'ghost'}
                            size="sm"
                            style={{
                                border: active ? overviewActiveBorder : overviewSoftBorder,
                                color: active ? overviewSuccessText : overviewQuietText,
                                background: active ? overviewActiveSurface : overviewMutedSurface,
                                borderRadius: '8px',
                                fontSize: '0.7rem',
                                fontWeight: 700
                            }}
                        >
                            {option.label}
                        </Button>
                    );
                })}
            </div>

            <div className="bot-status-bar">
                <div className="status-item">
                    <span className="label">System:</span>
                    {(() => {
                        const mode = botState?.health?.tradingControl?.mode;
                        const wsConnected = connected;

                        if (!wsConnected) return <span className="value status-offline">DISCONNECTED</span>;
                        if (mode === 'PAUSED') return <span className="value status-paused">PAUSED</span>;
                        if (mode === 'RUNNING' || !mode) return <span className="value status-online">RUNNING</span>;
                        return <span className="value text-amber-500">{mode}</span>;
                    })()}
                </div>
                <div className="status-item">
                    <span className="label">Mode:</span>
                    <span className={`value mode-${botState.settings.executionMode.toLowerCase()}`}>
                        {botState.settings.executionMode}
                    </span>
                </div>
                <div className="status-item">
                    <span className="label">Allocated:</span>
                    <span className="value">{formatUsd(allocatedCapital)}</span>
                    {profileCount > 0 && <span style={{ fontSize: '0.65rem', color: overviewQuietText, marginLeft: '4px' }}>({profileCount} profiles)</span>}
                </div>
                <div className="status-item">
                    <span className="label">Capital Used:</span>
                    <span className="value" style={{ color: overviewInfoText }}>{formatUsd(capitalUsed)}</span>
                    {overAllocatedCapital > 1e-8 && (
                        <span style={{ fontSize: '0.65rem', color: overviewAttentionText }}>
                            capped (+{formatUsd(overAllocatedCapital)} raw)
                        </span>
                    )}
                </div>
                <div className="status-item">
                    <span className="label">Remaining:</span>
                    <span className={`value ${overAllocatedCapital > 1e-8 ? 'status-offline' : 'status-online'}`}>
                        {formatUsd(remainingCapital)}
                    </span>
                </div>
                <div className="status-item">
                    <span className="label">Uptime:</span>
                    <span className="value">{formatUptime(botState.uptime)}</span>
                </div>
                <div className="status-item">
                    <span className="label">Realized P&L (90d):</span>
                    <span className={`value ${displayRealizedPnl >= 0 ? 'status-online' : 'status-offline'}`}>
                        {formatUsd(displayRealizedPnl)}
                    </span>
                </div>
                <div className="status-item">
                    <span className="label">Net P&L (90d):</span>
                    <span className={`value ${netPnl >= 0 ? 'status-online' : 'status-offline'}`}>
                        {formatUsd(netPnl)}
                    </span>
                </div>
                <div className="status-item">
                    <span className="label">Win Rate ({winRateWindowConfig.label}):</span>
                    <span className="value" style={{ color: displayWindowAggregate.winRate >= 50 ? overviewSuccessText : overviewWarningText }}>
                        {displayWindowAggregate.winRate.toFixed(1)}%
                    </span>
                    <span style={{ fontSize: '0.65rem', color: overviewMutedText }}>
                        {displayWindowAggregate.tradeCount} trades
                    </span>
                </div>
                <div className="status-item">
                    <span className="label">P&L Duration:</span>
                    <span
                        className="value"
                        title={pnlWindow.fromTs > 0
                            ? `${new Date(pnlWindow.fromTs).toLocaleString()} -> ${new Date(pnlWindow.toTs).toLocaleString()}`
                            : 'No realized trades yet'}
                    >
                        {pnlWindow.durationLabel}
                    </span>
                    <span style={{ fontSize: '0.65rem', color: overviewMutedText }}>
                        {pnlWindow.fromTs > 0
                            ? `From ${new Date(pnlWindow.fromTs).toLocaleDateString()}`
                            : 'Awaiting trade history'}
                    </span>
                </div>
            </div>

            {/* --- NEW: Alpaca Account Health --- */}
            <div className="bot-status-bar" style={{ marginTop: '16px', borderTop: overviewSectionBorder, paddingTop: '16px' }}>
                <div className="status-item">
                    <span className="label">Broker Balance (Alpaca):</span>
                    <span className={`value ${botState.accountSnapshot ? 'status-online' : 'status-offline'}`}>
                        {botState.accountSnapshot
                            ? formatUsd(botState.accountSnapshot.buying_power)
                            : 'Waiting for snapshot...'}
                    </span>
                    {botState.accountSnapshot && (
                        <span style={{ fontSize: '0.65rem', color: overviewMutedText }}>
                            Cash: {formatUsd(botState.accountSnapshot.cash)} ({botState.accountSnapshot.currency})
                        </span>
                    )}
                </div>
                {botState.accountSnapshot && (
                    <div className="status-item">
                        <span className="label">Last Sync:</span>
                        <span className="value">
                            {new Date(botState.accountSnapshot.timestamp).toLocaleTimeString()}
                        </span>
                    </div>
                )}
                {/* Parity & Self-Healing Heartbeat */}
                <div className="status-item" style={{ borderLeft: overviewSoftBorder, paddingLeft: '16px' }}>
                    <span className="label">Parity Heartbeat:</span>
                    <span className={`value ${botState.health?.reconciliationParityMismatchTrades ? 'status-offline' : 'status-online'}`}>
                        {botState.health?.reconciliationParityMismatchTrades || 0} Mismatches
                    </span>
                    {Number(botState.health?.reconciliationParityAutoClosedTrades || 0) > 0 && (
                        <span style={{ fontSize: '0.65rem', color: overviewSuccessText, marginLeft: '4px' }}>
                            ({botState.health?.reconciliationParityAutoClosedTrades} Self-Healed)
                        </span>
                    )}
                    {Number(botState.health?.reconciliationParityQuarantinedTrades || 0) > 0 && (
                        <span style={{ fontSize: '0.65rem', color: overviewWarningText, marginLeft: '4px' }}>
                            ({botState.health?.reconciliationParityQuarantinedTrades} Quarantined)
                        </span>
                    )}
                </div>
                {/* Recent Failures Summary */}
                {(botState.orderFailures || []).length > 0 && (
                    <div className="status-item" style={{ marginLeft: 'auto', borderLeft: overviewSoftBorder, paddingLeft: '16px' }}>
                        <span className="label" style={{ color: overviewDangerText }}>Recent Rejections:</span>
                        <span className="value" style={{ color: overviewDangerText }}>{(botState.orderFailures || []).length}</span>
                        <span style={{ fontSize: '0.65rem', color: overviewMutedText }}>
                            Latest: {(botState.orderFailures || [])[0].symbol} ({(botState.orderFailures || [])[0].reason?.substring(0, 20)}...)
                        </span>
                    </div>
                )}
            </div>

            <div className="table-container" style={{ marginBottom: '32px' }}>
                <table className="pro-table w-full">
                    <thead>
                        <tr>
                            <th>Capital Scope</th>
                            <th style={{ textAlign: 'right' }}>Allocated</th>
                            <th style={{ textAlign: 'right' }}>Used</th>
                            <th style={{ textAlign: 'right' }}>Remaining</th>
                            <th style={{ textAlign: 'right' }}>Utilization</th>
                            <th style={{ textAlign: 'right' }}>Win Rate ({winRateWindowConfig.label})</th>
                            <th style={{ textAlign: 'right' }}>Realized P&L</th>
                            <th>State</th>
                        </tr>
                    </thead>
                    <tbody>
                        {profileCapitalRows.length > 0 ? (
                            profileCapitalRows.map((row) => {
                                const overAllocated = row.overAllocatedAmount > 1e-8;
                                const stateColor = row.runtimeTone === 'running'
                                    ? overviewSuccessText
                                    : row.runtimeTone === 'cooldown'
                                        ? overviewWarningText
                                        : row.runtimeTone === 'armed'
                                            ? overviewInfoText
                                            : row.runtimeTone === 'blocked'
                                                ? overviewDangerText
                                            : overviewQuietText;
                                return (
                                    <tr key={row.id}>
                                        <td style={{ fontWeight: 700 }}>{row.name}</td>
                                        <td style={{ textAlign: 'right' }}>{formatUsd(row.allocated)}</td>
                                        <td style={{ textAlign: 'right', color: overviewInfoText }}>{formatUsd(row.used)}</td>
                                        <td style={{ textAlign: 'right', color: overAllocated ? overviewDangerText : overviewSuccessText }}>
                                            {formatUsd(row.remaining)}
                                            {overAllocated && (
                                                <div style={{ color: overviewAttentionText, fontSize: '0.65rem' }}>
                                                    raw +{formatUsd(row.overAllocatedAmount)}
                                                </div>
                                            )}
                                        </td>
                                        <td style={{ textAlign: 'right', color: overAllocated ? overviewDangerText : overviewNeutralText }}>
                                            {row.utilizationPct.toFixed(1)}%
                                        </td>
                                        <td style={{ textAlign: 'right', color: row.winRate >= 50 ? overviewSuccessText : overviewWarningText }}>
                                            {row.winRate.toFixed(1)}%
                                            <span style={{ color: overviewMutedText, marginLeft: '4px', fontSize: '0.65rem' }}>
                                                ({row.tradeCount})
                                            </span>
                                        </td>
                                        <td style={{ textAlign: 'right', color: row.netPnl >= 0 ? overviewSuccessText : overviewDangerText }}>
                                            {formatUsd(row.netPnl)}
                                        </td>
                                        <td>
                                            <div>
                                                <div style={{ color: stateColor, fontWeight: 700 }}>
                                                    {row.runtimeState}
                                                </div>
                                                <div style={{ color: overviewMutedText, fontSize: '0.68rem' }}>
                                                    {row.runtimeDetail}
                                                </div>
                                            </div>
                                        </td>
                                    </tr>
                                );
                            })
                        ) : (
                            <tr>
                                <td style={{ fontWeight: 700 }}>Account (Fallback)</td>
                                <td style={{ textAlign: 'right' }}>{formatUsd(allocatedCapital)}</td>
                                <td style={{ textAlign: 'right', color: overviewInfoText }}>{formatUsd(capitalUsed)}</td>
                                <td style={{ textAlign: 'right', color: overAllocatedCapital > 1e-8 ? overviewDangerText : overviewSuccessText }}>
                                    {formatUsd(remainingCapital)}
                                    {overAllocatedCapital > 1e-8 && (
                                        <div style={{ color: overviewAttentionText, fontSize: '0.65rem' }}>
                                            raw +{formatUsd(overAllocatedCapital)}
                                        </div>
                                    )}
                                </td>
                                <td style={{ textAlign: 'right' }}>
                                    {allocatedCapital > 0 ? ((capitalUsed / allocatedCapital) * 100).toFixed(1) : '0.0'}%
                                </td>
                                <td style={{ textAlign: 'right' }}>-</td>
                                <td style={{ textAlign: 'right', color: displayRealizedPnl >= 0 ? overviewSuccessText : overviewDangerText }}>{formatUsd(displayRealizedPnl)}</td>
                                <td>
                                    <span style={{ color: overviewQuietText, fontWeight: 700 }}>No signal</span>
                                </td>
                            </tr>
                        )}
                    </tbody>
                </table>
            </div>

            {/* NEW: Recent Order Rejections List */}
            {botState.orderFailures && botState.orderFailures.length > 0 && (
                <div style={{ marginBottom: '32px' }}>
                    <h3 style={{ fontSize: '0.9rem', fontWeight: 700, marginBottom: '12px', color: overviewDangerText }}>Recent Order Rejections</h3>
                    <div className="table-container">
                        <table className="pro-table w-full">
                            <thead>
                                <tr>
                                    <th>Time</th>
                                    <th>Symbol</th>
                                    <th>Side</th>
                                    <th>Qty</th>
                                    <th>Reason</th>
                                    <th>Sub-tag</th>
                                    <th>Profile</th>
                                </tr>
                            </thead>
                            <tbody>
                                {botState.orderFailures.slice(0, 10).map((fail, idx) => (
                                    <tr key={idx}>
                                        <td style={{ color: overviewMutedText, fontSize: '0.75rem' }}>{new Date(fail.timestamp).toLocaleString()}</td>
                                        <td style={{ fontWeight: 600 }}>{fail.symbol}</td>
                                        <td className={`side-${fail.side.toLowerCase()}`}>{fail.side}</td>
                                        <td>{fail.qty}</td>
                                        <td style={{ color: overviewDangerText, maxWidth: '300px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={fail.reason}>
                                            {fail.reason}
                                        </td>
                                        <td style={{ color: overviewQuietText, fontFamily: 'monospace' }} title={fail.subTag || ''}>
                                            {compactTag(fail.subTag)}
                                        </td>
                                        <td style={{ color: overviewMutedText }}>{fail.profileId || 'Unknown'}</td>
                                    </tr>
                                ))}
                            </tbody>
                        </table>
                    </div>
                </div>
            )}

            {/* Symbol Cards — role-aware rendering */}
            {isAdminView ? (
                /* ── ADMIN: Full technical view ─────────────────── */
                <div className="readiness-grid">
                    {symbols.map(symbol => {
                        const data = botState.symbols[symbol];
                        const profileSignals = Object.values(data.profileSignals || {});
                        const bias4h = data.indicators.ema50_4h && data.indicators.ema200_4h
                            ? (data.indicators.ema50_4h > data.indicators.ema200_4h ? 'BULLISH' : 'BEARISH')
                            : 'NEUTRAL';
                        const momentum1h = data.indicators.rsi_1h ? (data.indicators.rsi_1h > 50 ? 'BULLISH' : 'BEARISH') : 'NEUTRAL';
                        const normalizedSignal = String(data.signal || 'NONE').toUpperCase();
                        const hasDirectionalSignal = normalizedSignal === 'BUY' || normalizedSignal === 'SELL';
                        const readinessLabel = normalizedSignal === 'MIXED' ? 'PROFILE SIGNALS MIXED' : hasDirectionalSignal ? 'SIGNAL ACTIVE' : 'NO SIGNAL';
                        const readinessClass = hasDirectionalSignal ? 'yes' : 'maybe';
                        return (
                            <div key={symbol} className="readiness-card">
                                <div className="card-header">
                                    <h3>{symbol}</h3>
                                    <span className={`signal-label ${String(data.signal || 'none').toLowerCase()}`}>{data.signal}</span>
                                </div>
                                {profileSignals.length > 0 && (
                                    <div style={{ marginBottom: '0.6rem', display: 'flex', gap: '0.35rem', flexWrap: 'wrap' }}>
                                        {profileSignals.map((ps, idx) => (
                                            <span key={`${symbol}-ps-${idx}`} style={{ fontSize: '0.55rem', fontWeight: 700, letterSpacing: '0.06em', padding: '0.15rem 0.35rem', borderRadius: '8px', border: overviewTagBorder, color: overviewNeutralText }} title={ps.reason || ps.signal}>
                                                {(ps.profileName || `P${idx + 1}`)}: {ps.signal}
                                            </span>
                                        ))}
                                    </div>
                                )}
                                <div className="metrics-list">
                                    <div className="metric"><span>4H Trend Bias</span><span className={`value ${bias4h.toLowerCase()}`}>{bias4h}</span></div>
                                    <div className="metric"><span>1H Momentum (RSI)</span><span className={`value ${momentum1h.toLowerCase()}`}>{momentum1h} {data.indicators.rsi_1h ? `(${data.indicators.rsi_1h.toFixed(1)})` : ''}</span></div>
                                    <div className="metric"><span>Session</span><span className="value">{data.session}</span></div>
                                    <div className="metric"><span>Volatility</span><span className={`value vol-${data.volatility.toLowerCase()}`}>{data.volatility}</span></div>
                                    {data.indicators.ema50_4h && <div className="metric"><span>EMA50 (4H)</span><span className="value">{data.indicators.ema50_4h.toFixed(2)}</span></div>}
                                    {data.indicators.ema200_4h && <div className="metric"><span>EMA200 (4H)</span><span className="value">{data.indicators.ema200_4h.toFixed(2)}</span></div>}
                                </div>
                                <div className="readiness-footer">
                                    <span>Can trade?</span>
                                    <span className={`check ${readinessClass}`}>{readinessLabel}</span>
                                </div>
                            </div>
                        );
                    })}
                </div>
            ) : (
                /* ── CONSUMER: Plain-English friendly cards ────── */
                <div className="readiness-grid">
                    {symbols.map(symbol => {
                        const data = botState.symbols[symbol];
                        const normalizedSignal = String(data.signal || 'NONE').toUpperCase();

                        // ── Friendly translations ──────────────────────────
                        const bias4h = data.indicators.ema50_4h && data.indicators.ema200_4h
                            ? (data.indicators.ema50_4h > data.indicators.ema200_4h ? 'BULLISH' : 'BEARISH')
                            : 'NEUTRAL';

                        const directionLabel = bias4h === 'BULLISH' ? 'Uptrend' : bias4h === 'BEARISH' ? 'Downtrend' : 'Sideways';
                        const directionColor = bias4h === 'BULLISH' ? overviewSuccessText : bias4h === 'BEARISH' ? overviewDangerText : overviewAttentionText;

                        const rsi = data.indicators.rsi_1h || 50;
                        const momentumLabel = rsi > 60 ? 'Building strongly' : rsi > 50 ? 'Gaining' : rsi > 40 ? 'Neutral' : 'Fading';
                        const momentumColor = rsi > 55 ? overviewSuccessText : rsi > 45 ? overviewAttentionText : overviewDangerText;

                        const sessionIsOff = data.session === 'OFF' || !data.session;
                        const sessionLabel = sessionIsOff ? 'Outside window' : 'Active now';
                        const sessionColor = sessionIsOff ? overviewBotMuted : overviewSuccessText;

                        const volLabel = data.volatility === 'HIGH' ? 'Very Active' : data.volatility === 'MEDIUM' ? 'Moderate' : data.volatility === 'LOW' ? 'Calm' : 'Normal';
                        const volColor = data.volatility === 'HIGH' ? overviewAttentionText : data.volatility === 'MEDIUM' ? overviewInfoText : overviewQuietText;

                        const botStatusEmoji = normalizedSignal === 'BUY' ? '📈' : normalizedSignal === 'SELL' ? '📉' : normalizedSignal === 'MIXED' ? '⚡' : '👀';
                        const botStatusLabel =
                            normalizedSignal === 'BUY' ? 'Entry opportunity detected' :
                                normalizedSignal === 'SELL' ? 'Exit / short signal detected' :
                                    normalizedSignal === 'MIXED' ? 'Conditions mixed — holding off' :
                                        'Watching markets for the right setup';
                        const botStatusColor =
                            normalizedSignal === 'BUY' ? overviewSuccessText :
                                normalizedSignal === 'SELL' ? overviewDangerText :
                                    normalizedSignal === 'MIXED' ? overviewAttentionText :
                                        overviewBotMuted;

                        const change24h = data.change24h || 0;

                        return (
                            <div key={symbol} style={{
                                background: overviewCardGradient,
                                border: overviewCardBorder,
                                borderRadius: '20px',
                                padding: '24px',
                                display: 'flex',
                                flexDirection: 'column',
                                gap: '0',
                                transition: 'all 0.2s ease',
                                position: 'relative',
                                overflow: 'hidden'
                            }}>
                                {/* Top accent line based on signal */}
                                <div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: '2px', background: botStatusColor, opacity: normalizedSignal === 'NONE' ? 0.15 : 0.6 }} />

                                {/* Header */}
                                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: '20px' }}>
                                    <div>
                                        <div style={{ fontSize: '1.1rem', fontWeight: 900, color: overviewNeutralText, letterSpacing: '-0.02em' }}>
                                            {symbol.split('/')[0]}
                                            <span style={{ fontSize: '0.7rem', color: overviewBotQuiet, fontWeight: 600, marginLeft: '4px' }}>/{symbol.split('/')[1] || 'USDT'}</span>
                                        </div>
                                        <div style={{ fontSize: '0.75rem', fontWeight: 700, color: change24h >= 0 ? overviewSuccessText : overviewDangerText, marginTop: '2px', fontFamily: 'monospace' }}>
                                            {change24h >= 0 ? '+' : ''}{change24h.toFixed(2)}% today
                                        </div>
                                    </div>
                                    <div style={{ fontSize: '1.4rem' }}>{botStatusEmoji}</div>
                                </div>

                                {/* Friendly metrics */}
                                <div style={{ display: 'flex', flexDirection: 'column', gap: '10px', flex: 1 }}>
                                    {[
                                        { label: 'Market Direction', value: directionLabel, color: directionColor },
                                        { label: 'Short-term Momentum', value: momentumLabel, color: momentumColor },
                                        { label: 'Trading Window', value: sessionLabel, color: sessionColor },
                                        { label: 'Market Activity', value: volLabel, color: volColor },
                                    ].map(({ label, value, color }) => (
                                        <div key={label} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                                            <span style={{ fontSize: '0.78rem', color: overviewBotMuted, fontWeight: 600 }}>{label}</span>
                                            <div style={{ display: 'flex', alignItems: 'center', gap: '6px' }}>
                                                <div style={{ width: '6px', height: '6px', borderRadius: '50%', background: color, boxShadow: `0 0 6px ${color}` }} />
                                                <span style={{ fontSize: '0.78rem', fontWeight: 800, color: overviewNeutralText }}>{value}</span>
                                            </div>
                                        </div>
                                    ))}
                                </div>

                                {/* Bot Status Footer */}
                                <div style={{ marginTop: '20px', paddingTop: '16px', borderTop: overviewDivider }}>
                                    <div style={{ fontSize: '0.68rem', color: overviewBotQuiet, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: '4px' }}>Bot Status</div>
                                    <div style={{ fontSize: '0.82rem', fontWeight: 800, color: botStatusColor === overviewBotMuted ? overviewQuietText : botStatusColor }}>
                                        {botStatusLabel}
                                    </div>
                                </div>
                            </div>
                        );
                    })}
                </div>
            )}
        </div>
    );
};
