/**
 * verifyChatCopilotContract.ts
 *
 * Static contract checks for the chat copilot surface.
 * Verifies the supported action set, runtime-context prompt contract,
 * and safe quick-link guidance without starting the backend server.
 */

import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const apiServerSource = readFileSync(join(__dirname, 'src/services/apiServer.ts'), 'utf8');

function assertSourceIncludes(fragment: string, message: string) {
    assert.ok(apiServerSource.includes(fragment), message);
}

function assertSourceMatches(pattern: RegExp, message: string) {
    assert.match(apiServerSource, pattern, message);
}

function testChatRouteRequiresAuth() {
    assertSourceMatches(
        /this\.app\.post\('\/api\/chat',\s*this\.requireAuth,/,
        '/api/chat must be protected by requireAuth',
    );
    console.log('[PASS] /api/chat requires authenticated requests.');
}

function testChatActionContract() {
    for (const action of [
        'create_profile',
        'update_profile',
        'recommend_profile_change',
        'recommend_trade_plan',
        'recommend_reconciliation_followup',
        'review_recent_trades',
        'explain',
        'explain_position',
        'explain_waiting',
        'explain_blocker',
        'summarize_reconciliation',
    ]) {
        assertSourceIncludes(`'${action}'`, `chat copilot must support ${action}`);
    }

    assertSourceIncludes(
        '"action": "create_profile" | "update_profile" | "recommend_profile_change" | "recommend_trade_plan" | "recommend_reconciliation_followup" | "review_recent_trades" | "explain" | "explain_position" | "explain_waiting" | "explain_blocker" | "summarize_reconciliation"',
        'chat prompt contract must document the full action enum',
    );
    console.log('[PASS] chat action contract is documented and supported.');
}

function testQuickLinkContract() {
    assertSourceIncludes(
        `"insights": string[] (optional concise evidence or key facts)`,
        'chat prompt contract must document structured insights',
    );
    assertSourceIncludes(
        `"quickLinks": [{ kind: "portfolio" | "plans" | "settings", ... }] (optional safe in-app destinations)`,
        'chat prompt contract must document quickLinks',
    );
    assertSourceIncludes(
        'Include safe "insights", "nextActions", and "quickLinks" whenever they would help the user move to the right app surface.',
        'chat prompt rules must require safe insights/nextActions/quickLinks guidance',
    );
    assertSourceIncludes(
        "{ kind: 'plans', label: 'Manage in Plans'",
        'chat copilot must be able to deep-link into Trade Plans',
    );
    assertSourceIncludes(
        "{ kind: 'settings', label: 'Open Admin Panel', section: 'Admin Panel' }",
        'chat copilot must be able to deep-link into the admin panel',
    );
    assertSourceIncludes(
        "{ kind: 'portfolio', label: 'Open Portfolio'",
        'chat copilot must be able to deep-link into Portfolio',
    );
    console.log('[PASS] quick-link contract is covered.');
}

function testRuntimeCopilotFallbacks() {
    assertSourceIncludes(
        'this.buildTradePlanRecommendation(message, context)',
        'local fallback must support trade-plan recommendations',
    );
    assertSourceIncludes(
        'return this.buildReconciliationFollowup(context);',
        'local fallback must support reconciliation follow-up guidance',
    );
    assertSourceIncludes(
        'this.buildRecentTradeReview(context)',
        'local fallback must support recent-trade review guidance',
    );
    console.log('[PASS] runtime copilot fallback intents are covered.');
}

function main() {
    testChatRouteRequiresAuth();
    testChatActionContract();
    testQuickLinkContract();
    testRuntimeCopilotFallbacks();
    console.log('Chat copilot contract checks passed');
}

main();
