import assert from 'node:assert/strict';
import { ApiServer } from './src/services/apiServer.js';

type ChatContext = Parameters<any>[1];

function createServerHarness() {
    return Object.create(ApiServer.prototype) as any;
}

function buildContext(): ChatContext {
    return {
        profiles: [
            {
                id: 'p1',
                name: 'High Risk Scalper',
                allocated_capital: 1000,
                risk_per_trade_percent: 1.25,
                symbols: 'BTC/USDT',
                is_active: true,
                strategy_config: {
                    rules: [{ ruleId: 'TrendBiasRule', enabled: true }],
                    riskLimits: { maxDailyLossUsd: 50, maxOpenTrades: 2, maxConsecutiveLosses: 2 },
                    execution: { orderType: 'market', cooldownMinutes: 20, entryMode: 'both' }
                }
            }
        ],
        runtime: {
            positions: [
                {
                    symbol: 'BTC/USDT',
                    side: 'BUY',
                    entryPrice: 60000,
                    currentPrice: 61500,
                    unrealizedPnl: 375,
                    unrealizedPnlPercent: 2.5,
                    size: 0.25,
                    profileId: 'p1',
                    profileName: 'High Risk Scalper',
                    tradeId: 'trade-1',
                    takeProfit: 63000,
                    stopLoss: 58500,
                }
            ],
            signalContexts: [
                {
                    symbol: 'BTC/USDT',
                    profileId: 'p1',
                    profileName: 'High Risk Scalper',
                    signal: 'BUY',
                    passed: false,
                    reason: 'Waiting for stronger rule alignment.',
                    executionStatus: 'SKIPPED',
                    executionCode: 'rule_ratio_not_met',
                    executionReason: 'Only 2 of 4 voting rules passed.',
                    orderId: 'ord-1',
                }
            ],
            recentOrders: [],
            recentHistory: [
                { symbol: 'BTC/USDT', side: 'BUY', pnl: 125, reason: 'Simple target hit', tradeId: 'h1' },
                { symbol: 'ETH/USDT', side: 'BUY', pnl: -40, reason: 'Stop loss', tradeId: 'h2' },
            ],
            orderFailures: [
                {
                    symbol: 'BTC/USDT',
                    side: 'BUY',
                    qty: 0.1,
                    reason: 'Duplicate entry request blocked',
                    tradeId: 'trade-1',
                    timestamp: Date.now(),
                }
            ],
            operationalEvents: [
                {
                    id: 'evt-1',
                    type: 'RECONCILIATION_ALERT',
                    severity: 'WARN',
                    message: 'Reconciliation mismatch detected for BTC/USDT',
                    symbol: 'BTC/USDT',
                    profileId: 'p1',
                    tradeId: 'trade-1',
                    timestamp: Date.now(),
                }
            ],
            accountSnapshot: null,
            health: {
                tradingLoopHealthy: true,
                orderSyncHealthy: true,
                reconciliationLoopHealthy: false,
                reconciliationMismatchCount: 2,
                reconciliationMissingFromExchange: 1,
                reconciliationMissingInDb: 0,
                reconciliationNoGoTrades: 1,
                reconciliationParityQuarantinedTrades: 1,
                reconciliationParityAutoClosedTrades: 0,
                reconciliationIntegrityWatchdogTriggered: false,
                lockContentionCount: 0,
                reconciliationLockContentionCount: 0,
            },
            settings: {
                executionMode: 'paper',
                totalCapital: 1000,
                riskPerTrade: 1.25,
                maxOpenTrades: 2,
                isAlgoEnabled: true,
            }
        }
    };
}

function testTradePlanRecommendation() {
    const server = createServerHarness();
    const response = server.buildLocalChatFallback('Recommend a trade plan for my BTC position', buildContext());
    assert.equal(response.action, 'recommend_trade_plan');
    assert.ok(Array.isArray(response.insights) && response.insights.length > 0, 'trade-plan recommendation must include insights');
    assert.ok(response.quickLinks?.some((link: any) => link.kind === 'plans'), 'trade-plan recommendation must include a plans link');
    console.log('[PASS] chat fallback builds trade-plan recommendation.');
}

function testReconciliationFollowup() {
    const server = createServerHarness();
    const response = server.buildLocalChatFallback('What should I do about reconciliation right now?', buildContext());
    assert.equal(response.action, 'recommend_reconciliation_followup');
    assert.ok(response.quickLinks?.some((link: any) => link.kind === 'settings'), 'reconciliation follow-up must include settings/admin quick link');
    assert.ok(response.insights?.some((entry: string) => entry.includes('Mismatch count')), 'reconciliation follow-up must include mismatch insights');
    console.log('[PASS] chat fallback builds reconciliation follow-up.');
}

function testRecentTradeReview() {
    const server = createServerHarness();
    const response = server.buildLocalChatFallback('Review my recent trades', buildContext());
    assert.equal(response.action, 'review_recent_trades');
    assert.ok(response.insights?.some((entry: string) => entry.includes('BTC/USDT')), 'recent trade review must include trade evidence');
    console.log('[PASS] chat fallback builds recent-trade review.');
}

function testWaitingExplanation() {
    const server = createServerHarness();
    const response = server.buildLocalChatFallback('Why did no trade fire for BTC?', buildContext());
    assert.equal(response.action, 'explain_waiting');
    assert.ok(response.insights?.some((entry: string) => entry.includes('Execution code')), 'waiting explanation must include execution insight');
    console.log('[PASS] chat fallback builds waiting explanation.');
}

function main() {
    testTradePlanRecommendation();
    testReconciliationFollowup();
    testRecentTradeReview();
    testWaitingExplanation();
    console.log('Chat copilot fallback checks passed');
}

main();
