<?php

declare(strict_types=1);

namespace Signocore\Multilanguage\Infrastructure\Compatibility;

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

use Signocore\Multilanguage\Features\HreflangTags;
use Signocore\Multilanguage\Features\LanguageDetection;
use Signocore\Multilanguage\Features\LanguageManager;
use Signocore\Multilanguage\Infrastructure\Database\TranslationRepository;
use Signocore\Multilanguage\Infrastructure\Traits\Singleton;
use Signocore\Multilanguage\Support\LocaleHelper;
use Signocore\Multilanguage\Support\TranslationHelper;
use Signocore\Multilanguage\Support\UrlHelper;

final class SignocoreSEO
{
	use Singleton;

	protected function init(): void
	{
		if (!defined('SIGNOCORE_SEO_FILE')) {
			return;
		}

		// Let Signocore SEO handle hreflang output
		add_filter('signocore_seo_hreflang_tags', [$this, 'provideHreflangData']);

		// Disable our own hreflang when Signocore SEO manages it
		add_filter('signocore_ml_hreflang_enabled', [$this, 'disableOwnHreflang']);

		// Provide translated SEO meta per language
		add_filter('signocore_seo_meta_title', [$this, 'filterMetaTitle'], 10, 2);
		add_filter('signocore_seo_meta_description', [$this, 'filterMetaDescription'], 10, 2);
		add_filter('signocore_seo_canonical_url', [$this, 'filterCanonicalUrl'], 10, 2);

		do_action('signocore_ml_signocore_seo_loaded');
	}

	/**
	 * Provide hreflang data to Signocore SEO.
	 *
	 * @param array<string, string> $tags
	 * @return array<string, string>
	 */
	public function provideHreflangData(array $tags): array
	{
		$languages = LanguageManager::load()->getActiveLanguages();
		$defaultLang = LanguageManager::load()->getDefaultLanguageCode();

		if (is_singular()) {
			$postId = get_queried_object_id();
			$translations = TranslationRepository::getTranslationsForPost($postId);

			foreach ($languages as $lang) {
				$hreflang = LocaleHelper::getHreflangCode($lang->code);

				if ($lang->code === TranslationHelper::getElementLanguage($postId)) {
					$permalink = get_permalink($postId);
				} elseif (isset($translations[$lang->code])) {
					$permalink = get_permalink($translations[$lang->code]);
				} else {
					continue;
				}

				if ($permalink !== false) {
					$tags[$hreflang] = $permalink;
				}
			}
		} else {
			foreach ($languages as $lang) {
				$hreflang = LocaleHelper::getHreflangCode($lang->code);
				$tags[$hreflang] = UrlHelper::getUrlForLanguage($lang->code);
			}
		}

		// Add x-default
		if (isset($tags[LocaleHelper::getHreflangCode($defaultLang)])) {
			$tags['x-default'] = $tags[LocaleHelper::getHreflangCode($defaultLang)];
		}

		return $tags;
	}

	/**
	 * Disable our own hreflang output when Signocore SEO handles it.
	 */
	public function disableOwnHreflang(bool $enabled): bool
	{
		return false;
	}

	/**
	 * Filter meta title to use the translated post's SEO title.
	 *
	 * @param string $title
	 * @param int|null $postId
	 */
	public function filterMetaTitle(string $title, ?int $postId): string
	{
		if ($postId === null) {
			return $title;
		}

		$currentLang = LanguageDetection::load()->getCurrentLanguage();
		$postLang = TranslationHelper::getElementLanguage($postId);

		if ($postLang === $currentLang) {
			return $title;
		}

		$translatedId = TranslationHelper::getTranslation($postId, $currentLang);
		if ($translatedId !== null) {
			$translatedTitle = get_post_meta($translatedId, '_signocore_seo_title', true);
			if (is_string($translatedTitle) && $translatedTitle !== '') {
				return $translatedTitle;
			}
		}

		return $title;
	}

	/**
	 * Filter meta description to use the translated post's SEO description.
	 *
	 * @param string $description
	 * @param int|null $postId
	 */
	public function filterMetaDescription(string $description, ?int $postId): string
	{
		if ($postId === null) {
			return $description;
		}

		$currentLang = LanguageDetection::load()->getCurrentLanguage();
		$postLang = TranslationHelper::getElementLanguage($postId);

		if ($postLang === $currentLang) {
			return $description;
		}

		$translatedId = TranslationHelper::getTranslation($postId, $currentLang);
		if ($translatedId !== null) {
			$translatedDesc = get_post_meta($translatedId, '_signocore_seo_description', true);
			if (is_string($translatedDesc) && $translatedDesc !== '') {
				return $translatedDesc;
			}
		}

		return $description;
	}

	/**
	 * Filter canonical URL to point to the correct language version.
	 *
	 * @param string $url
	 * @param int|null $postId
	 */
	public function filterCanonicalUrl(string $url, ?int $postId): string
	{
		if ($postId === null) {
			return $url;
		}

		$currentLang = LanguageDetection::load()->getCurrentLanguage();
		$postLang = TranslationHelper::getElementLanguage($postId);

		if ($postLang === $currentLang) {
			return $url;
		}

		$translatedId = TranslationHelper::getTranslation($postId, $currentLang);
		if ($translatedId !== null) {
			return get_permalink($translatedId) ?: $url;
		}

		return $url;
	}
}
