<?php

namespace Planaday\Platform\WordpressConfig;

use Planaday\Platform\PlatformAbstraction\LocalizationController;
use Planaday\Utility\Debug\Log\Logging;
use Planaday\Utility\PluginData;

class WPLocalizationController implements LocalizationController {
	use Logging;

	/** @var array<string, array<string, bool>> */
	protected array $sourceStrings = [];

	public function __construct(
		protected PluginData $pluginData
	) {}

	public function translate( string $stringToBeTranslated, ?string $classCausingTranslate = null ): ?string {
		if(!isset($this->sourceStrings[$stringToBeTranslated])) $this->sourceStrings[$stringToBeTranslated] = [];

		if ($classCausingTranslate  !== null) {
			$this->sourceStrings[$stringToBeTranslated][$classCausingTranslate] = true;
		} else {
			$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
			$callingClass = $backtrace[1]['class'] . ":" . ($backtrace[0]['line'] ?? "unknown");
			$this->sourceStrings[$stringToBeTranslated][$callingClass] = true;
		}

		/* translators: For abstraction this plugin is provided with its own .po files and should not be translated by
		WP as this is done by the development team of the plugin */
		return __($stringToBeTranslated, "planaday-connector");
	}

	public function logAllSourceStrings(): void {
		foreach ($this->sourceStrings as $string => $classes) {
			$this->sourceStrings[$string] = array_keys($classes);
		}

		$this->logDebug('Logging all source strings', $this->sourceStrings);

		$this->checkAndAddMissingEntries();
	}

	protected function checkAndAddMissingEntries(): void {
		$potFile        = dirname( __DIR__, 4 ) . "/languages/planaday-connector.pot";
		$potFileContent = file_get_contents( $potFile );
		$potFileContent = str_replace("\r", "", $potFileContent);

		if ( $potFileContent === false ) {
			$this->logWarning( "Could not read pot file" );
			return;
		}

		$stringsInDocument = [];

		preg_match_all('@^((?:#[^\\n]*\\n)*)msgid "([^\\n]*?)"\\nmsgstr ""@m', $potFileContent, $matches, PREG_SET_ORDER);

		foreach ($matches as $match) {
			preg_match_all('@#: ([^\\n]*)@', $match[1], $classMatches, PREG_PATTERN_ORDER);

			$stringsInDocument[$match[2]] = $classMatches[1] ?? [];
		}

		$this->logDebug("Strings in document", $stringsInDocument);

		foreach ($this->sourceStrings as $string => $classes) {
			if (empty($string)) continue;
			$string = str_replace(["\\", '"'], ['\\\\', '\\"'], $string);
			$stringAsId = 'msgid "' . $string . '"';

			if ( !array_key_exists( $string, $stringsInDocument )) {
				if ( str_contains( $potFileContent, $stringAsId ) ) {
					$this->logInfo( "String ($string) already exists in pot file assuming regex failed, returning" );
					return;
				}

				$this->logInfo( "Adding missing source string: $string" );
				$potFileContent .= "\n\n" . $stringAsId . "\n". 'msgstr ""';
			}

			foreach ($classes as $class) {
				if (empty($class)) continue;

				if ( !in_array( $class, $stringsInDocument[$string] ?? [] ) ) {
					$this->logInfo( "Adding missing source location: $class" );
					$potFileContent = str_replace( $stringAsId, "#: $class\n" . $stringAsId, $potFileContent );
				}
			}
		}

		$this->logDebug("Pot file content", $potFileContent);

		file_put_contents( $potFile, $potFileContent );
	}
}