import pg from 'pg';
import { config } from '../config.js';

const { Client } = pg;

export type ChangelogNotification = {
  id: number;
  t: string;   // schema.table
  op: 'I' | 'U' | 'D';
  rid: string;
};

type Listener = (n: ChangelogNotification) => void;

let client: pg.Client | null = null;
const listeners = new Set<Listener>();

export async function startListener(): Promise<void> {
  if (client) return;
  client = new Client({
    host: config.pg.host,
    port: config.pg.port,
    user: config.pg.user,
    password: config.pg.password,
    database: config.pg.database,
    application_name: 'mocl-notify',
  });

  client.on('notification', msg => {
    if (msg.channel !== 'core_changelog' || !msg.payload) return;
    try {
      const parsed = JSON.parse(msg.payload) as ChangelogNotification;
      for (const fn of listeners) fn(parsed);
    } catch (e) {
      console.error('[notify] malformed payload', msg.payload, e);
    }
  });

  client.on('error', err => {
    console.error('[notify] connection error', err);
    // TODO: reconnect strategy with backoff.
  });

  await client.connect();
  await client.query('LISTEN core_changelog');
  console.log('[notify] LISTEN core_changelog');
}

export function onChangelog(fn: Listener): () => void {
  listeners.add(fn);
  return () => listeners.delete(fn);
}

export async function stopListener(): Promise<void> {
  if (!client) return;
  await client.end();
  client = null;
}
