import { describe, it, expect } from 'vitest';
import { PGlite } from '@electric-sql/pglite';
import { drizzle } from 'drizzle-orm/pglite';
import type { Querier } from '@platform-modules/db';
import { count, post, type CommentsSchema } from '@platform-modules/comments';
import { applyCommentsSchema } from './install.js';
import { deleteCommentsByTarget } from './comments.js';

const identity = (s: string) => s;
const guest = { kind: 'guest', name: 'Ada' } as const;

/**
 * U5 spec §6 — the U1 orphan-purge binding. A hard content delete must cascade to its comments;
 * an unrelated target's comments must survive. (count() is published-only, so assert via getById-less
 * raw presence: re-post returns a fresh id, so we count post-delete by listing both targets.)
 */
describe('deleteCommentsByTarget (U1 orphan-purge binding)', () => {
  async function setup(): Promise<Querier<CommentsSchema>> {
    const client = new PGlite();
    const db = drizzle(client) as unknown as Querier<CommentsSchema>;
    await applyCommentsSchema(db as unknown as Querier);
    return db;
  }

  it('deletes comments for the target and retains other targets', async () => {
    const db = await setup();
    const A = { type: 'content_entry', id: 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' };
    const B = { type: 'content_entry', id: 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb' };

    // Two comments on A (moderator-published so count() sees them), one on B.
    const mod = { id: 'm1', canModerate: true };
    await post(db, { target: A, author: guest, body: 'a1', initialStatus: 'published' }, mod, identity);
    await post(db, { target: A, author: guest, body: 'a2', initialStatus: 'published' }, mod, identity);
    await post(db, { target: B, author: guest, body: 'b1', initialStatus: 'published' }, mod, identity);

    expect(await count(db, A)).toBe(2);
    expect(await count(db, B)).toBe(1);

    await deleteCommentsByTarget(db, A);

    expect(await count(db, A)).toBe(0); // cascaded away
    expect(await count(db, B)).toBe(1); // unrelated target retained
  });
});
