/**
 * Web analytics beacon code generator
 * Generates src/generated/webanalytics.ts with the analytics beacon script
 */
import { join } from 'node:path';
/**
 * Generate the web analytics files (webanalytics.ts and analytics-config.ts)
 */
export async function generateWebAnalyticsFile(options) {
    const { rootDir, logger, analytics } = options;
    const srcDir = join(rootDir, 'src');
    const generatedDir = join(srcDir, 'generated');
    const analyticsPath = join(generatedDir, 'webanalytics.ts');
    const configPath = join(generatedDir, 'analytics-config.ts');
    logger.trace(`Generating web analytics files...`);
    const analyticsEnabled = analytics !== false;
    const analyticsConfig = typeof analytics === 'object' ? analytics : {};
    // Generate the analytics config file with resolved values
    const configCode = generateAnalyticsConfigCode(analyticsEnabled, analyticsConfig);
    await Bun.write(configPath, configCode);
    // Generate the webanalytics file
    const code = analyticsEnabled ? getEnabledAnalyticsCode() : getDisabledAnalyticsCode();
    await Bun.write(analyticsPath, code);
    logger.trace(`Generated web analytics files at %s`, generatedDir);
}
function generateAnalyticsConfigCode(enabled, config) {
    return `// @generated
// Auto-generated by Agentuity
// DO NOT EDIT - This file is regenerated on every build

export interface AnalyticsConfig {
	enabled: boolean;
	requireConsent: boolean;
	trackClicks: boolean;
	trackScroll: boolean;
	trackOutboundLinks: boolean;
	trackForms: boolean;
	trackWebVitals: boolean;
	trackErrors: boolean;
	trackSPANavigation: boolean;
	sampleRate: number;
	excludePatterns: string[];
	globalProperties: Record<string, unknown>;
}

export const analyticsConfig: AnalyticsConfig = {
	enabled: ${enabled && config.enabled !== false},
	requireConsent: ${config.requireConsent ?? false},
	trackClicks: ${config.trackClicks ?? true},
	trackScroll: ${config.trackScroll ?? true},
	trackOutboundLinks: ${config.trackOutboundLinks ?? true},
	trackForms: ${config.trackForms ?? false},
	trackWebVitals: ${config.trackWebVitals ?? true},
	trackErrors: ${config.trackErrors ?? true},
	trackSPANavigation: ${config.trackSPANavigation ?? true},
	sampleRate: ${config.sampleRate ?? 1},
	excludePatterns: ${JSON.stringify(config.excludePatterns ?? [])},
	globalProperties: ${JSON.stringify(config.globalProperties ?? {})},
};
`;
}
function getDisabledAnalyticsCode() {
    return `// @generated
// Auto-generated by Agentuity
// DO NOT EDIT - This file is regenerated on every build

import { createRouter } from '@agentuity/runtime';
import type { AnalyticsConfig } from './analytics-config';

// Analytics disabled
export function injectAnalytics(html: string, _config: AnalyticsConfig): string {
	return html;
}

export function registerAnalyticsRoutes(_app: ReturnType<typeof createRouter>): void {}
`;
}
function getEnabledAnalyticsCode() {
    return `// @generated
// Auto-generated by Agentuity
// DO NOT EDIT - This file is regenerated on every build

import type { Context } from 'hono';
import {
	BEACON_SCRIPT,
	createRouter,
	createWebSessionMiddleware,
	getOrganizationId,
	getProjectId,
	isDevMode as runtimeIsDevMode,
} from '@agentuity/runtime';
import type { AnalyticsConfig } from './analytics-config';

// Inject analytics config and script into HTML
// Note: Only static config is injected (org, project, devmode, tracking options)
// Session and thread IDs are read from cookies by the beacon script
//
// In production: beacon is served from CDN as a hashed asset (injected by Vite build)
// In development: beacon is served from /_agentuity/webanalytics/analytics.js route
export function injectAnalytics(html: string, analyticsConfig: AnalyticsConfig): string {
	if (!analyticsConfig.enabled) return html;

	const orgId = getOrganizationId() || '';
	const projectId = getProjectId() || '';
	const isDevmode = runtimeIsDevMode();

	// Only include static config - session/thread come from cookies
	const pageConfig = {
		...analyticsConfig,
		orgId,
		projectId,
		isDevmode,
	};

	const configScript = \`<script>window.__AGENTUITY_ANALYTICS__=\${JSON.stringify(pageConfig)};</script>\`;
	// Session script sets cookies and window.__AGENTUITY_SESSION__ (dynamic, not cached)
	const sessionScript = '<script src="/_agentuity/webanalytics/session.js" async></script>';

	// In production, the beacon is already in HTML as a CDN asset (data-agentuity-beacon marker)
	// Inject config/session BEFORE the beacon marker so config exists when beacon runs
	const beaconMarker = '<script data-agentuity-beacon';
	if (html.includes(beaconMarker)) {
		// Production: inject config/session right before the beacon script
		const injection = configScript + sessionScript;
		return html.replace(beaconMarker, injection + beaconMarker);
	}

	// Development: beacon served from local route, inject all three scripts
	const beaconScript = '<script src="/_agentuity/webanalytics/analytics.js"></script>';
	const injection = configScript + sessionScript + beaconScript;

	// Inject before </head> or at start of <body>
	if (html.includes('</head>')) {
		return html.replace('</head>', injection + '</head>');
	}
	if (html.includes('<body')) {
		return html.replace(/<body([^>]*)>/, \`<body$1>\${injection}\`);
	}
	return injection + html;
}

// Serve analytics routes
export function registerAnalyticsRoutes(app: ReturnType<typeof createRouter>): void {
	// Dynamic thread config script - sets cookie and returns thread ID
	// Web analytics only tracks thread ID, not session ID (to avoid polluting sessions table)
	// This endpoint is NOT cached - it generates unique data per request
	app.get('/_agentuity/webanalytics/session.js', createWebSessionMiddleware(), async (c: Context) => {
		// Read from context (cookies aren't readable until the next request)
		const threadId = c.get('_webThreadId') || '';

		// Use JSON.stringify to safely escape threadId and prevent XSS/injection
		const sessionData = JSON.stringify({ threadId });
		const sessionScript = \`window.__AGENTUITY_SESSION__=\${sessionData};\`;

		return new Response(sessionScript, {
			headers: {
				'Content-Type': 'application/javascript; charset=utf-8',
				'Cache-Control': 'no-store, no-cache, must-revalidate',
			},
		});
	});

	// Dev mode only: serve beacon script from local route
	// In production, the beacon is served from CDN as a hashed asset
	if (runtimeIsDevMode()) {
		app.get('/_agentuity/webanalytics/analytics.js', async (c: Context) => {
			return new Response(BEACON_SCRIPT, {
				headers: {
					'Content-Type': 'application/javascript; charset=utf-8',
					'Cache-Control': 'no-store, no-cache, must-revalidate',
				},
			});
		});
	}
}
`;
}
//# sourceMappingURL=webanalytics-generator.js.map