<?php

declare(strict_types=1);

namespace Signocore\Multilanguage\Features;

if (!defined('ABSPATH')) {
	exit;
}

use Signocore\Multilanguage\Application\Constants;
use Signocore\Multilanguage\Infrastructure\Traits\Singleton;
use Signocore\Multilanguage\Support\FlagHelper;

/**
 * Translates site options (blogname, blogdescription) per language.
 */
final class OptionsTranslation
{
	use Singleton;

	/** @var string[] Options that can be translated. */
	private const TRANSLATABLE_OPTIONS = [
		'blogname',
		'blogdescription',
	];

	protected function init(): void
	{
		add_filter('pre_option_blogname', [$this, 'filterBlogname'], 10, 0);
		add_filter('pre_option_blogdescription', [$this, 'filterBlogdescription'], 10, 0);

		if (is_admin()) {
			add_action('admin_init', [$this, 'registerSettings']);
		}
	}

	/**
	 * Filter blogname to return language-specific value.
	 *
	 * @return string|false False to use the original value.
	 */
	public function filterBlogname(): string|false
	{
		return $this->getTranslatedOption('blogname');
	}

	/**
	 * Filter blogdescription to return language-specific value.
	 *
	 * @return string|false False to use the original value.
	 */
	public function filterBlogdescription(): string|false
	{
		return $this->getTranslatedOption('blogdescription');
	}

	/**
	 * Get the translated value for an option, or false to fall back to default.
	 *
	 * @return string|false
	 */
	private function getTranslatedOption(string $optionName): string|false
	{
		$currentLang = LanguageDetection::load()->getCurrentLanguage();
		$defaultLang = LanguageManager::load()->getDefaultLanguageCode();

		// Don't override for the default language
		if ($currentLang === $defaultLang) {
			return false;
		}

		$optionKey = Constants::OPTION_PREFIX . $optionName . '_' . $currentLang;
		$value = get_option($optionKey, '');

		if (!is_string($value) || $value === '') {
			return false;
		}

		return $value;
	}

	/**
	 * Register settings and render section for site options translation.
	 */
	public function registerSettings(): void
	{
		$langManager = LanguageManager::load();
		$languages = $langManager->getActiveLanguages();

		if (count($languages) < 2) {
			return;
		}

		$defaultCode = $langManager->getDefaultLanguageCode();

		// Register default language options on our settings group
		foreach (self::TRANSLATABLE_OPTIONS as $optionName) {
			register_setting('sml_settings_general', $optionName, [
				'type' => 'string',
				'sanitize_callback' => 'sanitize_text_field',
			]);
		}

		// Register secondary language options
		foreach ($languages as $lang) {
			if ($lang->code === $defaultCode) {
				continue;
			}

			foreach (self::TRANSLATABLE_OPTIONS as $optionName) {
				$optionKey = Constants::OPTION_PREFIX . $optionName . '_' . $lang->code;

				register_setting('sml_settings_general', $optionKey, [
					'type' => 'string',
					'sanitize_callback' => 'sanitize_text_field',
					'default' => '',
				]);
			}
		}

		add_settings_section(
			'sml_options_translation',
			__('Site Title & Tagline', 'signocore-multilanguage'),
			[$this, 'renderSection'],
			'sml_settings_general',
			[
				'before_section' => '<div class="sml-card"><div class="sml-card-body">',
				'after_section' => '</div></div>',
			]
		);
	}

	/**
	 * Render the pill-tab language switcher and translation fields.
	 */
	public function renderSection(): void
	{
		$langManager = LanguageManager::load();
		$languages = $langManager->getActiveLanguages();
		$defaultCode = $langManager->getDefaultLanguageCode();

		// Reorder so default language is first
		$ordered = [];
		if (isset($languages[$defaultCode])) {
			$ordered[$defaultCode] = $languages[$defaultCode];
		}
		foreach ($languages as $code => $lang) {
			if ($code !== $defaultCode) {
				$ordered[$code] = $lang;
			}
		}

		// Temporarily remove our translation filters so get_option() returns raw DB values
		remove_filter('pre_option_blogname', [$this, 'filterBlogname'], 10);
		remove_filter('pre_option_blogdescription', [$this, 'filterBlogdescription'], 10);

		// Pill tabs
		echo '<div class="sml-lang-pills">';
		$isFirst = true;
		foreach ($ordered as $code => $lang) {
			$activeClass = $isFirst ? ' active' : '';
			printf(
				'<a class="sml-lang-pill%s" data-lang="%s" href="#">%s %s</a>',
				$activeClass,
				esc_attr($code),
				FlagHelper::getFlagImg($code, 20, 15, $lang->name),
				esc_html($lang->native_name)
			);
			$isFirst = false;
		}
		echo '</div>';

		// Language panels
		$isFirst = true;
		foreach ($ordered as $code => $lang) {
			$isDefault = $code === $defaultCode;
			$activeClass = $isFirst ? ' active' : '';
			$style = $isFirst ? '' : ' style="display:none"';

			printf('<div class="sml-lang-panel%s" data-lang="%s"%s>', $activeClass, esc_attr($code), $style);

			foreach (self::TRANSLATABLE_OPTIONS as $optionName) {
				if ($isDefault) {
					$inputName = $optionName;
					$value = get_option($optionName, '');
				} else {
					$inputName = Constants::OPTION_PREFIX . $optionName . '_' . $code;
					$value = get_option($inputName, '');
				}

				echo '<div class="sml-field-row">';
				printf(
					'<label for="%s">%s</label>',
					esc_attr($inputName),
					esc_html($this->getOptionLabel($optionName))
				);
				printf(
					'<input type="text" id="%s" name="%s" value="%s" class="regular-text">',
					esc_attr($inputName),
					esc_attr($inputName),
					esc_attr(is_string($value) ? $value : '')
				);
				echo '</div>';
			}

			echo '</div>';
			$isFirst = false;
		}

		// Re-add translation filters
		add_filter('pre_option_blogname', [$this, 'filterBlogname'], 10, 0);
		add_filter('pre_option_blogdescription', [$this, 'filterBlogdescription'], 10, 0);
	}

	/**
	 * Get the human-readable label for an option name.
	 */
	private function getOptionLabel(string $optionName): string
	{
		return match ($optionName) {
			'blogname' => __('Site Title', 'signocore-multilanguage'),
			'blogdescription' => __('Tagline', 'signocore-multilanguage'),
			default => $optionName,
		};
	}
}
