import { test } from 'node:test';
import assert from 'node:assert/strict';
import { Hono } from 'hono';

// The dialog modules import supabase.js, which exits without these; dummies are
// enough since this test only checks structure/mounting, never calls a handler.
process.env.SUPABASE_URL ||= 'http://localhost';
process.env.SUPABASE_SERVICE_KEY ||= 'x';
process.env.JWT_SECRET ||= 'x';
process.env.SITE_DIR ||= '/tmp/nosite';

const { loadPlugins } = await import('../src/plugin-manager.js');
const m = await loadPlugins(['dialog']);

test('dialog plugin loads with a valid manifest', () => {
  assert.deepEqual(m.names(), ['dialog']);
  assert.equal(m.has('dialog'), true);
});

test('dialog: route tiers as in index.js', () => {
  const routes = m.plugins[0].routes;
  const pub = routes.filter((r) => r.public).map((r) => `${r.method || 'route'} ${r.path}`);
  const priv = routes.filter((r) => !r.public).map((r) => `${r.method || 'route'} ${r.path}`);
  assert.deepEqual(pub, [
    'get /comments', 'get /forums', 'get /forums/:slug', 'get /recent', 'get /thread', 'post /auth/login',
  ]);
  assert.deepEqual(priv, [
    'post /comments', 'delete /comments/:id', 'post /threads', 'route /mod', 'route /admin/forums',
  ]);
});

test('dialog: widget login is rate-limited', () => {
  const loginRoute = m.plugins[0].routes.find((r) => r.path === '/auth/login');
  assert.equal(loginRoute.public, true);
  assert.equal(Array.isArray(loginRoute.use) && loginRoute.use.length, 1);
});

test('dialog: lifecycle hooks + stats present', () => {
  const p = m.plugins[0];
  assert.equal(typeof p.onBoot, 'function');
  assert.equal(typeof p.onPublish, 'function');
  assert.equal(typeof p.stats, 'function');
});

test('dialog: mounts into the pipeline without throwing', () => {
  const app = new Hono();
  const requireAdmin = async (c, next) => next();
  assert.doesNotThrow(() => {
    m.mountPublic(app);
    app.use('/api/*', async (c, next) => next());
    m.mountPrivate(app, '/api', requireAdmin);
  });
});
