import assert from 'node:assert/strict';
import test from 'node:test';
import {
  MINISTRY_TRANSLATIONS,
  PSWG_TRANSLATIONS,
  CDCGPSF_TRANSLATIONS,
} from './index';
import { SHARED_MEETING_REQUEST_LABELS } from './shared-meeting-request-labels.seed';
import { fetchMinistryMeetingRequestDictionary } from '../../../../frontend/features/ministry/meeting-request/meeting-request-translations';
import { cdcGpsfMeetingRequestMessages } from '../../../../frontend/features/cdc-gpsf/meeting-requests/cdc-gpsf-meeting-request-i18n';
import { cdcGpsfMeetingRequestKey, resolveCdcGpsfMeetingRequestLabels } from '../../../../frontend/features/cdc-gpsf/meeting-requests/cdc-gpsf-meeting-request-translations';
import { cdcGpsfMeetingCalendarMessages, resolveCdcGpsfMeetingCalendarLabels } from '../../../../frontend/features/cdc-gpsf/meeting-calendar/cdc-gpsf-meeting-calendar-i18n';

test('every shared request/create/print/control key is seeded in the three consuming modules', () => {
  for (const [owner, items] of [
    ['ministry', MINISTRY_TRANSLATIONS],
    ['pswg', PSWG_TRANSLATIONS],
    ['cdcgpsf', CDCGPSF_TRANSLATIONS],
  ] as const) {
    const rows = items.filter((item) => item.page === 'meeting_requests');
    assert.equal(
      new Set(rows.map((item) => item.translationKey)).size,
      rows.length,
    );
    for (const [key] of SHARED_MEETING_REQUEST_LABELS) {
      const row = rows.find((item) => item.translationKey === key);
      assert.ok(row, owner + '/' + key);
      assert.ok(row.englishText.trim());
      assert.ok(row.khmerText.trim());
    }
  }
});
test('shared dictionary fetch scopes the owner, forwards abort, and requests Khmer', async () => {
  const original = globalThis.fetch;
  const signal = new AbortController().signal;
  try {
    for (const owner of ['ministry', 'pswg', 'cdcgpsf'] as const) {
      globalThis.fetch = async (input, options) => {
        const url = new URL(String(input));
        assert.equal(url.searchParams.get('module'), owner);
        assert.equal(url.searchParams.get('page'), 'meeting_requests');
        assert.equal(url.searchParams.get('language'), 'km');
        assert.equal(options?.signal, signal);
        assert.equal(options?.cache, 'no-store');
        return Response.json({ data: { translations: { page_title: owner } } });
      };
      assert.deepEqual(
        await fetchMinistryMeetingRequestDictionary('km', signal, owner),
        { page_title: owner },
      );
    }
  } finally {
    globalThis.fetch = original;
  }
});

test('CDC-GPSF request and calendar local UI labels have bilingual Admin seeds', () => {
  const request = new Map(CDCGPSF_TRANSLATIONS.filter(row => row.page === 'meeting_requests').map(row => [row.translationKey, row]));
  function check(en: unknown, km: unknown, path: string) {
    if (typeof en === 'string' && typeof km === 'string') {
      const row = request.get(cdcGpsfMeetingRequestKey(path));
      assert.ok(row, path);
      assert.equal(row.englishText, en);
      assert.equal(row.khmerText, km);
      return;
    }
    if (!en || !km || typeof en !== 'object' || typeof km !== 'object') return;
    for (const [key, value] of Object.entries(en))
      check(value, (km as Record<string, unknown>)[key], path ? `${path}.${key}` : key);
  }
  check(cdcGpsfMeetingRequestMessages.en, cdcGpsfMeetingRequestMessages.km, '');
  const calendar = new Map(CDCGPSF_TRANSLATIONS.filter(row => row.page === 'meeting_calendar').map(row => [row.translationKey, row]));
  for (const [key, englishText] of Object.entries(cdcGpsfMeetingCalendarMessages.en)) {
    const row = calendar.get(cdcGpsfMeetingRequestKey(key));
    assert.ok(row, key);
    assert.equal(row.englishText, englishText);
    assert.equal(row.khmerText, cdcGpsfMeetingCalendarMessages.km[key as keyof typeof cdcGpsfMeetingCalendarMessages.km]);
  }
  assert.equal(resolveCdcGpsfMeetingRequestLabels('km', { 'cdc_ui.meeting_title': 'Admin request' }).meetingTitle, 'Admin request');
  assert.equal(resolveCdcGpsfMeetingCalendarLabels('km', { 'cdc_ui.meeting_date': 'Admin calendar' }).meetingDate, 'Admin calendar');
});
