import type { Pool } from 'pg';

import { pgAll, pgRunReturning } from '@/shared/db';
import type { SendRateConfig } from './types';

interface SendRateConfigRow {
  max_sends: number;
  window_seconds: number;
  auto_queue: boolean;
  updated_at: string;
}

/** Used only if the config row is somehow absent (the migration seeds it). */
const FALLBACK: SendRateConfig = { maxSends: 10, windowSeconds: 300, autoQueue: true, updatedAt: '' };

function mapRow(r: SendRateConfigRow): SendRateConfig {
  return {
    maxSends: r.max_sends,
    windowSeconds: r.window_seconds,
    autoQueue: r.auto_queue,
    updatedAt: r.updated_at,
  };
}

/** Current global outbound send-rate cap. */
export async function getSendRateConfig(db: Pool): Promise<SendRateConfig> {
  try {
    const rows = await pgAll<SendRateConfigRow>(
      db,
      `SELECT max_sends, window_seconds, auto_queue, updated_at FROM macsync.send_rate_config WHERE id = true`,
    );
    const row = rows[0];
    return row ? mapRow(row) : { ...FALLBACK };
  } catch (err) {
    throw new Error(
      `getSendRateConfig: failed to read send_rate_config: ${err instanceof Error ? err.message : String(err)}`,
      { cause: err },
    );
  }
}

/** Set the global outbound send-rate cap (upserts the single config row). */
export async function setSendRateConfig(
  db: Pool,
  maxSends: number,
  windowSeconds: number,
  autoQueue: boolean,
): Promise<SendRateConfig> {
  try {
    const row = await pgRunReturning<SendRateConfigRow>(
      db,
      `INSERT INTO macsync.send_rate_config (id, max_sends, window_seconds, auto_queue, updated_at)
       VALUES (true, $1, $2, $3, now())
       ON CONFLICT (id) DO UPDATE
         SET max_sends = EXCLUDED.max_sends,
             window_seconds = EXCLUDED.window_seconds,
             auto_queue = EXCLUDED.auto_queue,
             updated_at = now()
       RETURNING max_sends, window_seconds, auto_queue, updated_at`,
      [maxSends, windowSeconds, autoQueue],
    );
    return mapRow(row);
  } catch (err) {
    throw new Error(
      `setSendRateConfig: failed to update send_rate_config: ${err instanceof Error ? err.message : String(err)}`,
      { cause: err },
    );
  }
}

/** Count messages marked 'sent' for a device within the trailing window (seconds). */
export async function countSentWithin(
  db: Pool,
  deviceId: string,
  windowSeconds: number,
): Promise<number> {
  try {
    const rows = await pgAll<{ n: string }>(
      db,
      `SELECT COUNT(*)::text AS n FROM macsync.send_queue
       WHERE device_id = $1 AND status = 'sent'
         AND sent_at > now() - ($2 * interval '1 second')`,
      [deviceId, windowSeconds],
    );
    return Number(rows[0]?.n ?? '0');
  } catch (err) {
    throw new Error(
      `countSentWithin: failed to count recent sends: ${err instanceof Error ? err.message : String(err)}`,
      { cause: err },
    );
  }
}
