<?php declare(strict_types=1);
namespace Newland\Toubiz\Common\Neos\ViewHelpers;

use Neos\Flow\Annotations as Flow;
use Neos\Flow\I18n;
use Neos\Flow\I18n\Xliff\Service\XliffReader;
use Neos\FluidAdaptor\Core\ViewHelper\AbstractViewHelper;

class AllTranslationsViewHelper extends AbstractViewHelper
{

    /**
     * @Flow\Inject
     * @var XliffReader
     */
    protected $xliffReader;

    /**
     * @var I18n\Service
     * @Flow\Inject
     */
    protected $localizationService;

    /** @param string|string[] $source */
    public function render($source, string $package): array
    {
        $source = (array) $source;
        $labels = [ [] ];
        foreach ($source as $s) {
            $labels[] = $this->getLanguageLabels($s, $package);
        }
        return array_replace_recursive(...$labels) ?? [];
    }

    private function getLanguageLabels(string $source, string $package): array
    {
        $filename = $this->getXliffFileName($source, $package);
        if (!$filename) {
            return [];
        }

        $node = $this->readXliff($filename);
        if (!$node) {
            return [];
        }

        return $this->extractTranslations($node);
    }

    private function getXliffFileName(string $source, string $package): ?string
    {
        [ $filename ] = $this->localizationService->getXliffFilenameAndPath(
            sprintf('resource://%s/Private/Translations', $package),
            $source
        );

        return $filename ?: null;
    }

    private function readXliff(string $filename): ?\DOMElement
    {
        $node = null;
        $this->xliffReader->readFiles(
            $filename,
            function (\XMLReader $reader) use (&$node) {
                $node = $reader->expand();
            }
        );

        return ($node instanceof \DOMElement) ? $node : null;
    }

    private function extractTranslations(\DOMElement $node): array
    {
        $translations = [];
        foreach ($node->getElementsByTagName('trans-unit') as $transUnit) {
            /** @var \DOMElement $transUnit */
            $id = $transUnit->getAttribute('id');
            $content = '';
            foreach ($transUnit->childNodes as $child) {
                if ($child->nodeName === 'source' || $child->nodeName === 'target') {
                    $content = $child->textContent;
                    break;
                }
            }

            $translations[$id] = $content;
        }

        return $translations;
    }
}
