import { describe, it, expect } from 'vitest';
import de from '../../messages/de.json';
import en from '../../messages/en.json';
import es from '../../messages/es.json';

describe('message key parity', () => {
	it('de, en, and es have identical key sets', () => {
		const deKeys = Object.keys(de).sort();
		const enKeys = Object.keys(en).sort();
		const esKeys = Object.keys(es).sort();
		expect(enKeys).toEqual(deKeys);
		expect(esKeys).toEqual(deKeys);
	});

	it('viewer navigation keys are present in all locales', () => {
		const requiredViewerKeys = [
			'viewer_previous_page',
			'viewer_next_page',
			'viewer_zoom_out',
			'viewer_zoom_in'
		];
		for (const key of requiredViewerKeys) {
			expect(de, `missing key in de: ${key}`).toHaveProperty(key);
			expect(en, `missing key in en: ${key}`).toHaveProperty(key);
			expect(es, `missing key in es: ${key}`).toHaveProperty(key);
		}
	});

	it('transcribe mark-for-training key is present in all locales', () => {
		expect(de).toHaveProperty('transcribe_mark_for_training');
		expect(en).toHaveProperty('transcribe_mark_for_training');
		expect(es).toHaveProperty('transcribe_mark_for_training');
	});

	it('layout menu open/close keys are present in all locales', () => {
		expect(de).toHaveProperty('layout_menu_open');
		expect(de).toHaveProperty('layout_menu_close');
		expect(en).toHaveProperty('layout_menu_open');
		expect(en).toHaveProperty('layout_menu_close');
		expect(es).toHaveProperty('layout_menu_open');
		expect(es).toHaveProperty('layout_menu_close');
	});

	// REQ-024: the timeline layer/life-event labels feed sr-only / aria text, so
	// they are localized per locale (the original German-only MVP decision was
	// reversed for accessibility). Pin the values so en/es can never silently
	// drift back to the German source strings.
	it('timeline layer/derived labels are localized per locale (REQ-024)', () => {
		expect(de).toMatchObject({
			timeline_layer_world: 'Weltgeschehen',
			timeline_layer_family: 'Familie',
			timeline_derived_birth: 'Geburt',
			timeline_derived_death: 'Tod',
			timeline_derived_marriage: 'Heirat'
		});
		expect(en).toMatchObject({
			timeline_layer_world: 'World events',
			timeline_layer_family: 'Family',
			timeline_derived_birth: 'Birth',
			timeline_derived_death: 'Death',
			timeline_derived_marriage: 'Marriage'
		});
		expect(es).toMatchObject({
			timeline_layer_world: 'Acontecimientos mundiales',
			timeline_layer_family: 'Familia',
			timeline_derived_birth: 'Nacimiento',
			timeline_derived_death: 'Fallecimiento',
			timeline_derived_marriage: 'Matrimonio'
		});
	});

	// #833 REQ-015: the new visual-fidelity strings (meta line, provenance token,
	// ✉ label, world-band suffix, density caption) are Paraglide keys present in
	// every locale so no surface ever falls back to a missing translation.
	it('zeitstrahl visual-fidelity keys are present in all locales (#833 REQ-015)', () => {
		const requiredKeys = [
			'timeline_provenance_derived',
			'timeline_provenance_curated',
			'timeline_bucket_show_more',
			'timeline_bucket_show_less',
			'timeline_letter_glyph_label',
			'timeline_layer_historical_suffix',
			'timeline_strip_density_caption',
			'timeline_events_count',
			'timeline_letters_count_singular',
			'timeline_events_count_singular'
		];
		for (const key of requiredKeys) {
			expect(de, `missing key in de: ${key}`).toHaveProperty(key);
			expect(en, `missing key in en: ${key}`).toHaveProperty(key);
			expect(es, `missing key in es: ${key}`).toHaveProperty(key);
		}
	});

	// #835 REQ-013: the letter chip's sr-only theme label is a Paraglide key in every
	// locale so color is never the only cue; the tag NAME is rendered as data, not translated.
	it('zeitstrahl tag-chip label key is present in all locales (#835 REQ-013)', () => {
		expect(de).toMatchObject({ timeline_tag_chip_label: 'Thema' });
		expect(en).toMatchObject({ timeline_tag_chip_label: 'Topic' });
		expect(es).toMatchObject({ timeline_tag_chip_label: 'Tema' });
	});

	// #780 REQ-010: the layer-filter strings are Paraglide keys in every locale.
	// timeline_filter_trigger (0 active) and timeline_filter_trigger_active ({count},
	// ≥1 active) are distinct keys so the trigger never reads "Filter (0 aktiv)".
	it('zeitstrahl layer-filter keys are present in all locales (#780 REQ-010)', () => {
		const requiredKeys = [
			'timeline_filter_label_layers',
			'timeline_filter_layer_personal',
			'timeline_filter_layer_historical',
			'timeline_filter_layer_letters',
			'timeline_filter_trigger',
			'timeline_filter_trigger_active',
			'timeline_filter_reset',
			'timeline_filter_empty_state'
		];
		for (const key of requiredKeys) {
			expect(de, `missing key in de: ${key}`).toHaveProperty(key);
			expect(en, `missing key in en: ${key}`).toHaveProperty(key);
			expect(es, `missing key in es: ${key}`).toHaveProperty(key);
		}
		// the active-count key carries the established {count} placeholder
		expect(de.timeline_filter_trigger_active).toContain('{count}');
		expect(en.timeline_filter_trigger_active).toContain('{count}');
		expect(es.timeline_filter_trigger_active).toContain('{count}');
	});

	// #842: the two curator-affordance CTA labels (Zeitstrahl header + person page)
	// are Paraglide keys present in every locale; the edit pencils reuse btn_edit.
	it('curator-affordance CTA keys are present in all locales (#842)', () => {
		for (const key of ['timeline_add_event', 'person_add_event']) {
			expect(de, `missing key in de: ${key}`).toHaveProperty(key);
			expect(en, `missing key in en: ${key}`).toHaveProperty(key);
			expect(es, `missing key in es: ${key}`).toHaveProperty(key);
		}
	});
});
