/**
 * P0-5 smoke test — MonitorService.getMonitors / getMonitorsForDashboard
 * inject WHERE userId = ctx.userId for non-admins.
 *
 * Run: npx tsx scripts/smoke/p0-5-monitor-scope.ts
 *
 * Offline-safe: monkey-patches the prisma client to capture call args,
 * then asserts the WHERE clauses the service builds for admin vs non-admin.
 */
import { ok, fail } from './_lib';

const calls: Record<string, unknown[][]> = {};
function spyResolves<T>(name: string, value: T) {
    return (...args: unknown[]) => {
        calls[name] = calls[name] ?? [];
        calls[name].push(args);
        return Promise.resolve(value);
    };
}

const prismaMod = require('../../src/lib/prisma') as { prisma: Record<string, unknown> };
prismaMod.prisma.monitor = {
    findMany: spyResolves('monitor.findMany', []),
    count: spyResolves('monitor.count', 0),
} as unknown;
prismaMod.prisma.country = {
    findFirst: spyResolves('country.findFirst', null),
    findMany: spyResolves('country.findMany', []),
} as unknown;
prismaMod.prisma.user = {
    findUnique: spyResolves('user.findUnique', { id: 42, countries: [] }),
} as unknown;
prismaMod.prisma.heartbeat = {
    findFirst: spyResolves('heartbeat.findFirst', null),
} as unknown;
prismaMod.prisma.$transaction = (ops: Promise<unknown>[]) => Promise.all(ops);

const { MonitorService } = require('../../src/lib/services/monitor.service') as typeof import('../../src/lib/services/monitor.service');

async function main(): Promise<void> {
    // Reset capture per scenario for clean assertions.

    // 1. Non-admin getMonitors → where.userId = 42
    delete calls['monitor.count'];
    await MonitorService.getMonitors(42, false);
    const c1 = calls['monitor.count']?.[0]?.[0] as { where: { userId?: number; deletedAt?: unknown } } | undefined;
    if (!c1) fail('P0-5 viewer getMonitors', 'monitor.count was not called');
    if (c1!.where.userId !== 42) {
        fail('P0-5 viewer getMonitors', `expected userId=42, got ${JSON.stringify(c1!.where)}`);
    }
    ok('Non-admin getMonitors restricts WHERE.userId to 42');

    // 2. Admin getMonitors → no userId
    delete calls['monitor.count'];
    await MonitorService.getMonitors(1, true);
    const c2 = calls['monitor.count']?.[0]?.[0] as { where: { userId?: number } };
    if (c2.where.userId !== undefined) {
        fail('P0-5 admin getMonitors', `expected no userId, got userId=${c2.where.userId}`);
    }
    ok('Admin getMonitors omits userId filter');

    // 3. Non-admin getMonitorsForDashboard → where.userId = 42
    delete calls['monitor.findMany'];
    await MonitorService.getMonitorsForDashboard(42, false, { page: 1, limit: 10 });
    const c3 = calls['monitor.findMany']?.[0]?.[0] as { where: { userId?: number } };
    if (c3.where.userId !== 42) {
        fail('P0-5 viewer dashboard', `expected userId=42, got ${JSON.stringify(c3.where)}`);
    }
    ok('Non-admin getMonitorsForDashboard restricts WHERE.userId to 42');

    // 4. Admin getMonitorsForDashboard → no userId
    delete calls['monitor.findMany'];
    await MonitorService.getMonitorsForDashboard(1, true, { page: 1, limit: 10 });
    const c4 = calls['monitor.findMany']?.[0]?.[0] as { where: { userId?: number } };
    if (c4.where.userId !== undefined) {
        fail('P0-5 admin dashboard', `expected no userId, got userId=${c4.where.userId}`);
    }
    ok('Admin getMonitorsForDashboard omits userId filter');

    ok('P0-5 monitor-scope', 'all read paths scope by userId for non-admins');
}

main().catch((err) => fail('P0-5 monitor-scope', String(err)));
