/**
 * Smoke test: buildSystemPrompt injects "## Subscribed Notes" when the
 * job owner has inject-mode subscriptions, and omits it when they don't.
 */
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import Database from 'better-sqlite3';
import { mkdtempSync, rmSync } from 'fs';
import { tmpdir } from 'os';
import { join } from 'path';
import { runMigrations } from '../db/migrate.js';
import { NotesRepository } from '../notes/notes-repository.js';
import { NotesService } from '../notes/notes-service.js';
import { buildSystemPrompt, type NotesInjectContext, type Movement } from './agent-loop.js';
import { DEFAULT_NOTES_INJECT } from '../config.js';

function makeMovement(): Movement {
  return {
    name: 'investigate',
    persona: 'investigator',
    instruction: 'do the thing',
    rules: [{ condition: 'done', next: 'plan' }],
    allowedTools: [],
    edit: false,
  };
}

describe('buildSystemPrompt — notes inject section', () => {
  let tmpRoot: string;
  let db: Database.Database;
  let service: NotesService;

  const aliceUser = {
    id: 'alice',
    role: 'user' as const,
    orgIds: [] as string[],
    email: 'alice@example.com',
    name: 'Alice',
    avatarUrl: null,
    status: 'active' as const,
    defaultVisibility: 'private' as const,
    defaultVisibilityOrgId: null,
  };

  const bobPublisher = { id: 'bob', role: 'user' as const, orgIds: [] as string[] };

  beforeEach(() => {
    tmpRoot = mkdtempSync(join(tmpdir(), 'al-notes-test-'));
    db = new Database(join(tmpRoot, 'test.db'));
    runMigrations(db);
    db.prepare(
      `INSERT INTO users (id, email, name) VALUES ('alice','alice@example.com','Alice'),('bob','bob@example.com','Bob')`
    ).run();
    const repo = new NotesRepository(db);
    service = new NotesService({
      db,
      repo,
      userFolderRoot: tmpRoot,
      getUserOrgIds: () => [],
    });
  });

  afterEach(() => {
    db.close();
    rmSync(tmpRoot, { recursive: true, force: true });
  });

  it('omits ## Subscribed Notes when user has no inject subscriptions', () => {
    const prompt = buildSystemPrompt(
      makeMovement(),
      1, 5, [], undefined, null,
      'alice', undefined, undefined, null, undefined,
      undefined, // no notesCtx
    );
    expect(prompt).not.toContain('## Subscribed Notes');
  });

  it('includes ## Subscribed Notes when inject subscription exists', () => {
    // alice publishes a public note
    service.writeNote({
      ownerId: 'alice',
      folder: 'runbooks',
      fileName: 'deploy.md',
      content: '---\nvisibility: public\n---\nDeploy checklist step 1',
    });
    // bob subscribes to alice's note in inject mode — alice is the consumer here
    // Actually let's have alice subscribe to bob's note:
    service.writeNote({
      ownerId: 'bob',
      folder: 'tips',
      fileName: 'shortcuts.md',
      content: '---\nvisibility: public\n---\nUseful shortcuts: Ctrl+C',
    });
    service.upsertSubscription({
      consumerUser: aliceUser as Express.User,
      publisherUserId: 'bob',
      folder: 'tips',
      mode: 'inject',
      enabled: 1,
    });

    const notesCtx: NotesInjectContext = {
      service,
      config: DEFAULT_NOTES_INJECT,
      user: aliceUser,
    };

    const prompt = buildSystemPrompt(
      makeMovement(),
      1, 5, [], undefined, null,
      'alice', undefined, undefined, null, undefined,
      notesCtx,
    );
    expect(prompt).toContain('## Subscribed Notes');
    expect(prompt).toContain('shortcuts.md');
    expect(prompt).toContain('Useful shortcuts: Ctrl+C');
  });

  it('does not include section when notesCtx is provided but subscriptions are empty', () => {
    const notesCtx: NotesInjectContext = {
      service,
      config: DEFAULT_NOTES_INJECT,
      user: aliceUser,
    };

    const prompt = buildSystemPrompt(
      makeMovement(),
      1, 5, [], undefined, null,
      'alice', undefined, undefined, null, undefined,
      notesCtx,
    );
    expect(prompt).not.toContain('## Subscribed Notes');
  });
});
