<?php

namespace MintyPHP\Tests\Architecture;

use PHPUnit\Framework\TestCase;

/**
 * GR-UI-015: Every key in i18n/default_de.json MUST exist in
 * i18n/default_en.json and vice versa.
 */
class I18nKeyCompletenessContractTest extends TestCase
{
    use ProjectFileAssertionSupport;

    public function testTranslationFilesAreValidJson(): void
    {
        $deContent = $this->readProjectFile('i18n/default_de.json');
        $enContent = $this->readProjectFile('i18n/default_en.json');

        $this->assertIsArray(json_decode($deContent, true), 'i18n/default_de.json is not valid JSON');
        $this->assertIsArray(json_decode($enContent, true), 'i18n/default_en.json is not valid JSON');
    }

    public function testAllGermanKeysExistInEnglish(): void
    {
        $de = $this->loadTranslationKeys('i18n/default_de.json');
        $en = $this->loadTranslationKeys('i18n/default_en.json');

        $missingInEn = array_values(array_diff($de, $en));

        $this->assertSame(
            [],
            $missingInEn,
            "Keys in default_de.json missing from default_en.json (GR-UI-015):\n"
            . implode("\n", $missingInEn)
        );
    }

    public function testAllEnglishKeysExistInGerman(): void
    {
        $de = $this->loadTranslationKeys('i18n/default_de.json');
        $en = $this->loadTranslationKeys('i18n/default_en.json');

        $missingInDe = array_values(array_diff($en, $de));

        $this->assertSame(
            [],
            $missingInDe,
            "Keys in default_en.json missing from default_de.json (GR-UI-015):\n"
            . implode("\n", $missingInDe)
        );
    }

    public function testTranslationValuesAreNonEmpty(): void
    {
        $deContent = $this->readProjectFile('i18n/default_de.json');
        $enContent = $this->readProjectFile('i18n/default_en.json');

        $de = json_decode($deContent, true);
        $en = json_decode($enContent, true);

        $this->assertIsArray($de);
        $this->assertIsArray($en);

        $emptyDe = array_keys(array_filter($de, static fn ($v): bool => trim((string) $v) === ''));
        $emptyEn = array_keys(array_filter($en, static fn ($v): bool => trim((string) $v) === ''));

        $this->assertSame([], $emptyDe, "Empty values in default_de.json:\n" . implode("\n", $emptyDe));
        $this->assertSame([], $emptyEn, "Empty values in default_en.json:\n" . implode("\n", $emptyEn));
    }

    /**
     * @return list<string>
     */
    private function loadTranslationKeys(string $path): array
    {
        $content = $this->readProjectFile($path);
        $data = json_decode($content, true);
        $this->assertIsArray($data, $path . ' is not valid JSON');

        $keys = array_keys($data);
        sort($keys, SORT_STRING);

        return $keys;
    }
}
