// dialog plugin — openbureau's forum/comment subsystem as a core plugin.
// Wraps the existing dialog modules (no logic change) into a plugin manifest:
// public reads + widget login, authenticated writes, self-guarding moderation /
// forum-admin sub-apps, syncLibrary on boot + after publish, and the forum
// counters merged into /api/stats. kgva does not enable this plugin.
//
// NB: this manifest exists; wiring it into index.js (and removing the hard-coded
// dialog there) is the live-tested cutover (stage 5) — see HANDOVER.
import { rateLimit } from '../../ratelimit.js';
import {
  listForums, showForum, recent, threadInfo, newThread, mod, adminForums,
} from './dialog.js';
import { listComments, createComment, deleteComment, login } from './comments.js';
import { supabase } from '../../supabase.js';
import { syncLibrary } from './dialog-store.js';

export default {
  name: 'dialog',

  routes: [
    // ── public reads (mounted before requireAuth) ──
    { method: 'get', path: '/comments', handler: listComments, public: true },
    { method: 'get', path: '/forums', handler: listForums, public: true },
    { method: 'get', path: '/forums/:slug', handler: showForum, public: true },
    { method: 'get', path: '/recent', handler: recent, public: true },
    { method: 'get', path: '/thread', handler: threadInfo, public: true },
    // widget login — brute-force throttled (10 / 5 min per IP), as in index.js
    {
      method: 'post', path: '/auth/login', handler: login, public: true,
      use: [rateLimit({ max: 10, windowMs: 5 * 60_000 })],
    },

    // ── authenticated writes (mounted after requireAuth) ──
    { method: 'post', path: '/comments', handler: createComment },
    { method: 'delete', path: '/comments/:id', handler: deleteComment },
    { method: 'post', path: '/threads', handler: newThread },

    // ── self-guarding sub-apps (requireModerator / requireAdmin inside) ──
    { path: '/mod', app: mod },
    { path: '/admin/forums', app: adminForums },
  ],

  // Mirror library posts as threads — on boot and after every publish build.
  onBoot: async () => {
    await syncLibrary().catch((e) => console.error('syncLibrary:', e?.message || e));
  },
  onPublish: async () => {
    await syncLibrary({ force: true }).catch(() => {});
  },

  // Forum/thread/comment counters, merged into /api/stats under "dialog".
  stats: async () => {
    const count = async (table, filter) => {
      try {
        let q = supabase.from(table).select('*', { count: 'exact', head: true });
        if (filter) q = filter(q);
        const { count: n } = await q;
        return n || 0;
      } catch { return 0; }
    };
    const [forums, threads, comments] = await Promise.all([
      count('forums'),
      count('threads', (q) => q.eq('deleted', false)),
      count('comments', (q) => q.eq('deleted', false)),
    ]);
    return { forums, threads, comments };
  },

  // Schema (forums/threads/comments + comment_stats view) — captured from the live
  // openbureau dev DB into migrations/001_dialog.sql (idempotent; verified to apply
  // on a fresh DB and re-apply as a no-op). The manager surfaces it; a migration
  // runner applies it on boot for a fresh instance (execution still TODO).
  migrations: ['001_dialog.sql'],
};
