<?php

declare(strict_types=1);

namespace Signocore\Multilanguage\UI\Metaboxes;

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

use Signocore\Multilanguage\Application\Constants;
use Signocore\Multilanguage\Features\LanguageManager;
use Signocore\Multilanguage\Infrastructure\Database\TranslationRepository;
use Signocore\Multilanguage\Infrastructure\Traits\Singleton;
use Signocore\Multilanguage\Support\FlagHelper;
use Signocore\Multilanguage\Support\TaxonomyHelper;
use Signocore\Multilanguage\Support\TranslationHelper;
use Signocore\Multilanguage\Support\UrlHelper;

final class TaxonomyTranslation
{
	use Singleton;

	private const NONCE_ACTION = 'sml_term_translation_save';

	private const NONCE_FIELD = 'sml_term_translation_nonce';

	protected function init(): void
	{
		add_action('admin_init', [$this, 'registerFields']);
		add_action('admin_enqueue_scripts', [$this, 'enqueueAssets']);
	}

	/**
	 * Load admin CSS on taxonomy edit screens.
	 */
	public function enqueueAssets(string $hookSuffix): void
	{
		if ($hookSuffix !== 'term.php' && $hookSuffix !== 'edit-tags.php') {
			return;
		}

		wp_enqueue_style(
			'signocore-ml-admin-css',
			plugins_url('assets/css/admin.css', SIGNOCORE_ML_FILE),
			[],
			Constants::$pluginVersion
		);
	}

	/**
	 * Register translation fields for all translatable taxonomies.
	 */
	public function registerFields(): void
	{
		foreach (TaxonomyHelper::getTranslatableTaxonomies() as $taxonomy) {
			add_action("{$taxonomy}_edit_form_fields", [$this, 'renderEditFields'], 10, 2);
			add_action("{$taxonomy}_add_form_fields", [$this, 'renderAddFields']);
			add_action("edited_{$taxonomy}", [$this, 'handleSave'], 10, 2);
			add_action("created_{$taxonomy}", [$this, 'handleSave'], 20, 2);
		}
	}

	/**
	 * Render translation fields on the term edit screen.
	 *
	 * @param \WP_Term $term
	 * @param string $taxonomy
	 */
	public function renderEditFields(\WP_Term $term, string $taxonomy): void
	{
		$languages = array_filter(
			LanguageManager::load()->getActiveLanguages(),
			fn (object $lang): bool => UrlHelper::isLanguageReachable($lang->code)
		);
		$elementType = TranslationHelper::resolveTermElementType($term->term_id, $taxonomy);
		$currentLang = TranslationHelper::getElementLanguage($term->term_id, $elementType);
		$translations = TranslationRepository::getTranslationsForTerm($term->term_id, $taxonomy);

		wp_nonce_field(self::NONCE_ACTION, self::NONCE_FIELD);

		?>
		<tr class="form-field">
			<td colspan="2">
				<div class="postbox sml-settings">
					<div class="inside">
						<h2><?php echo esc_html__('Translations', 'signocore-multilanguage'); ?></h2>

						<table class="form-table sml-settings-table">
							<tr>
								<th scope="row">
									<label for="sml_term_language"><?php echo esc_html__('Language', 'signocore-multilanguage'); ?></label>
								</th>
								<td>
									<select name="sml_term_language" id="sml_term_language" class="sml-metabox__select">
										<?php foreach ($languages as $code => $lang) :
											$isLinked = isset($translations[$code]) && $code !== $currentLang;
										?>
											<option value="<?php echo esc_attr($code); ?>" <?php selected($currentLang, $code); ?> <?php disabled($isLinked); ?>>
												<?php echo esc_html($lang->name . ' (' . $code . ')'); ?>
											</option>
										<?php endforeach; ?>
									</select>
								</td>
							</tr>
							<tr>
								<th scope="row"><?php echo esc_html__('Translations', 'signocore-multilanguage'); ?></th>
								<td>
									<table class="sml-metabox__table">
										<tbody>
											<?php foreach ($languages as $code => $lang) : ?>
												<?php if ($code === $currentLang) {
													continue;
												} ?>
												<?php
												$translationId = $translations[$code] ?? null;
												$statusLabel = __('Not translated', 'signocore-multilanguage');
												$statusClass = '';

												if ($translationId !== null) {
													$record = TranslationRepository::findByElementAndLanguage($translationId, $elementType, $code);
													if ($record !== null && $record->status === Constants::STATUS_PUBLISHED) {
														$statusLabel = __('Published', 'signocore-multilanguage');
														$statusClass = 'sml-metabox__status--published';
													} else {
														$statusLabel = __('Draft', 'signocore-multilanguage');
														$statusClass = 'sml-metabox__status--draft';
													}
												}
												?>
												<tr class="sml-metabox__row">
													<td class="sml-metabox__flag">
														<?php echo FlagHelper::getFlagImg($code, 16, 12, $lang->name); ?>
													</td>
													<td class="sml-metabox__info">
														<strong><?php echo esc_html($lang->name); ?></strong>
														<span class="sml-metabox__status <?php echo esc_attr($statusClass); ?>">
															(<?php echo esc_html($statusLabel); ?>)
														</span>
													</td>
													<td class="sml-metabox__actions">
														<?php if ($translationId !== null) : ?>
															<a href="<?php echo esc_url(get_edit_term_link($translationId, $taxonomy) ?? ''); ?>" class="button button-small">
																<?php echo esc_html__('Edit', 'signocore-multilanguage'); ?>
															</a>
															<a href="<?php echo esc_url(wp_nonce_url(
																admin_url(sprintf(
																	'admin-ajax.php?action=sml_unlink_term_translation&term_id=%d&taxonomy=%s&lang=%s',
																	$translationId,
																	$taxonomy,
																	$code
																)),
																Constants::AJAX_NONCE
															)); ?>" class="button button-small button-link-delete" onclick="return confirm('<?php echo esc_js(__('Remove translation link?', 'signocore-multilanguage')); ?>');">
																<?php echo esc_html__('Unlink', 'signocore-multilanguage'); ?>
															</a>
														<?php else : ?>
															<a href="<?php echo esc_url(wp_nonce_url(
																admin_url(sprintf(
																	'admin-ajax.php?action=sml_create_term_translation&source_id=%d&taxonomy=%s&lang=%s',
																	$term->term_id,
																	$taxonomy,
																	$code
																)),
																Constants::AJAX_NONCE
															)); ?>" class="button button-small button-primary">
																<?php echo esc_html__('Create', 'signocore-multilanguage'); ?>
															</a>
														<?php endif; ?>
													</td>
												</tr>
											<?php endforeach; ?>
										</tbody>
									</table>
								</td>
							</tr>
						</table>
					</div>
				</div>
			</td>
		</tr>
		<?php
	}

	/**
	 * Render language field on the add term form.
	 *
	 * @param string $taxonomy
	 */
	public function renderAddFields(string $taxonomy): void
	{
		$languages = array_filter(
			LanguageManager::load()->getActiveLanguages(),
			fn (object $lang): bool => UrlHelper::isLanguageReachable($lang->code)
		);
		$defaultCode = LanguageManager::load()->getDefaultLanguageCode();

		wp_nonce_field(self::NONCE_ACTION, self::NONCE_FIELD);

		?>
		<div class="form-field">
			<label for="sml_term_language"><?php echo esc_html__('Language', 'signocore-multilanguage'); ?></label>
			<select name="sml_term_language" id="sml_term_language">
				<?php foreach ($languages as $code => $lang) : ?>
					<option value="<?php echo esc_attr($code); ?>" <?php selected($defaultCode, $code); ?>>
						<?php echo esc_html($lang->name . ' (' . $code . ')'); ?>
					</option>
				<?php endforeach; ?>
			</select>
			<p><?php echo esc_html__('Select the language for this term.', 'signocore-multilanguage'); ?></p>
		</div>
		<?php
	}

	/**
	 * Handle language assignment on term save.
	 *
	 * @param int $termId
	 * @param int $ttId
	 */
	public function handleSave(int $termId, int $ttId): void
	{
		if (!isset($_POST[self::NONCE_FIELD]) || !wp_verify_nonce($_POST[self::NONCE_FIELD], self::NONCE_ACTION)) {
			return;
		}

		if (!current_user_can('manage_categories')) {
			return;
		}

		$langCode = sanitize_text_field($_POST['sml_term_language'] ?? '');
		if ($langCode === '') {
			return;
		}

		$langManager = LanguageManager::load();
		if (!$langManager->isActiveLanguage($langCode)) {
			return;
		}

		$term = get_term($termId);
		if ($term === null || is_wp_error($term)) {
			return;
		}

		$taxonomy = $term->taxonomy;
		$elementType = TranslationHelper::resolveTermElementType($termId, $taxonomy);
		$existing = TranslationRepository::findByElement($termId, $elementType);

		if ($existing !== null) {
			if ($existing->language_code !== $langCode) {
				TranslationRepository::update((int) $existing->id, [
					'language_code' => $langCode,
				]);
			}
		} else {
			\Signocore\Multilanguage\Features\TaxonomyTranslation::load()->assignLanguage($termId, $taxonomy, $langCode);
		}
	}
}
