/**
 * Bulk-dismiss service: dismissAllForPort must respect the optional rule/
 * severity filter and never touch another port's alerts.
 */

import { describe, it, expect, beforeAll, vi } from 'vitest';
import { and, eq, isNull } from 'drizzle-orm';

vi.mock('@/lib/socket/server', () => ({
  emitToRoom: vi.fn(),
}));

import { db } from '@/lib/db';
import { alerts } from '@/lib/db/schema/insights';
import { user } from '@/lib/db/schema/users';
import { dismissAllForPort } from '@/lib/services/alerts.service';
import { makePort } from '../helpers/factories';

let USER_ID = '';

beforeAll(async () => {
  const [u] = await db.select({ id: user.id }).from(user).limit(1);
  if (!u) throw new Error('No user available; run pnpm db:seed first');
  USER_ID = u.id;
});

async function seedAlert(portId: string, ruleId: string, severity = 'info') {
  const [row] = await db
    .insert(alerts)
    .values({
      portId,
      ruleId,
      severity,
      title: `t-${ruleId}`,
      link: '/x',
      fingerprint: `fp-${Math.random().toString(36).slice(2)}`,
      metadata: {},
    })
    .returning({ id: alerts.id });
  return row!.id;
}

async function openCount(portId: string) {
  const rows = await db
    .select()
    .from(alerts)
    .where(and(eq(alerts.portId, portId), isNull(alerts.dismissedAt), isNull(alerts.resolvedAt)));
  return rows.length;
}

describe('dismissAllForPort', () => {
  it('dismisses only the filtered rule, scoped to the port, then all', async () => {
    const portA = await makePort();
    const portB = await makePort();
    await seedAlert(portA.id, 'interest.stale');
    await seedAlert(portA.id, 'interest.stale');
    await seedAlert(portA.id, 'document.signer_overdue', 'warning');
    await seedAlert(portB.id, 'interest.stale');

    const filtered = await dismissAllForPort(portA.id, USER_ID, { ruleId: 'interest.stale' });
    expect(filtered).toBe(2);
    expect(await openCount(portA.id)).toBe(1); // signer_overdue remains
    expect(await openCount(portB.id)).toBe(1); // other port untouched

    const rest = await dismissAllForPort(portA.id, USER_ID);
    expect(rest).toBe(1);
    expect(await openCount(portA.id)).toBe(0);
    expect(await openCount(portB.id)).toBe(1);
  });
});
