<?php

namespace idoit\Module\Synetics_jdisc\Console\Command;

use idoit\Console\Command\AbstractCommand;
use isys_module_synetics_jdisc;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

class CheckTranslationsCommand extends AbstractCommand
{
    const NAME = 'jdisc:check-translations';
    const REQUIRES_LOGIN = false;
    const HIDE_COMMAND = true;
    const PROGRESS_BAR_STEPS = 4;

    public function getCommandDescription()
    {
        return 'Checks for missing or untranslated strings in translation files.';
    }

    public function getCommandName()
    {
        return self::NAME;
    }

    public function getCommandDefinition()
    {
        return new InputDefinition([]);
    }

    public function isConfigurable()
    {
        return false;
    }

    public function getCommandUsages()
    {
        return [];
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);
        $io->title('Comparing translation files...');

        $progressBar = new ProgressBar($output, self::PROGRESS_BAR_STEPS);
        $progressBar->start();

        $jdiscPath = isys_module_synetics_jdisc::getPath();
        $dePath = $jdiscPath . '/lang/de/default.json';
        $enPath = $jdiscPath . '/lang/en/default.json';

        $deJson = file_get_contents($dePath);
        $enJson = file_get_contents($enPath);
        $progressBar->advance();

        if ($deJson === false || $enJson === false) {
            $io->error('Error reading translation files.');
            return Command::FAILURE;
        }

        $deData = json_decode($deJson, true);
        $enData = json_decode($enJson, true);

        if (json_last_error() !== JSON_ERROR_NONE) {
            $io->error('Error parsing JSON: ' . json_last_error_msg());
            return Command::FAILURE;
        }
        $progressBar->advance();

        $deKeys = $this->getAllKeys($deData);
        $enKeys = $this->getAllKeys($enData);

        $missingInEn = array_diff($deKeys, $enKeys);
        $missingInDe = array_diff($enKeys, $deKeys);
        $progressBar->advance();

        $untranslatedKeys = $this->findUntranslated($deData, $enData);
        $progressBar->finish();
        $io->newLine(2);

        $io->section('Translation Key Comparison');

        if (empty($missingInEn) && empty($missingInDe)) {
            $io->success('OK: All keys are present in both language files.');
        } else {
            if (!empty($missingInEn)) {
                $io->error('Keys missing in en/default.json (but present in de/default.json):');
                $io->listing($missingInEn);
            }
            if (!empty($missingInDe)) {
                $io->error('Keys missing in de/default.json (but present in en/default.json):');
                $io->listing($missingInDe);
            }
        }

        if (!empty($untranslatedKeys)) {
            $io->section('Potential Untranslated Strings');
            $io->warning('The following keys have the same value in both files, suggesting they might not be translated:');
            $io->listing($untranslatedKeys);
        }

        $io->newLine();
        $io->text('Comparison finished.');

        return Command::SUCCESS;
    }

    private function getAllKeys(array $array, string $parentKey = ''): array
    {
        $keys = [];
        foreach ($array as $key => $value) {
            $newKey = $parentKey ? $parentKey . '.' . $key : $key;
            $keys[] = $newKey;
            if (is_array($value)) {
                $keys = array_merge($keys, $this->getAllKeys($value, $newKey));
            }
        }
        return $keys;
    }

    private function findUntranslated(array $arr1, array $arr2, string $parentKey = ''): array
    {
        $untranslated = [];
        $exceptions = ['ID', 'JDisc', 'CMDB', 'MAC', 'FQDN', 'HTML', 'CSS', 'GraphQL', 'API', 'URL', 'JDisc Server', 'Filter', 'Discovery', 'Host', 'Port', 'Logs', 'Dashboard', 'Actions', 'Status', 'Name', 'Database'];

        foreach ($arr1 as $key => $v1) {
            if (isset($arr2[$key])) {
                $v2 = $arr2[$key];
                $newPath = $parentKey ? $parentKey . '.' . $key : $key;

                if (is_array($v1) && is_array($v2)) {
                    $untranslated = array_merge($untranslated, $this->findUntranslated($v1, $v2, $newPath));
                } elseif (is_string($v1) && is_string($v2) && $v1 === $v2 && trim($v1) !== '' && !preg_match('/\{\{.*\}\}/', $v1)) {
                    if (!in_array($v1, $exceptions) && !in_array($key, $exceptions)) {
                        $untranslated[] = $newPath;
                    }
                }
            }
        }
        return $untranslated;
    }
}