<?php

declare(strict_types=1);

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

use Signocore\Multilanguage\Features\LanguageDetection;
use Signocore\Multilanguage\Features\LanguageManager;
use Signocore\Multilanguage\Features\LanguageSwitcher;
use Signocore\Multilanguage\Features\StringTranslation;
use Signocore\Multilanguage\Infrastructure\Database\TranslationRepository;
use Signocore\Multilanguage\Support\TranslationHelper;
use Signocore\Multilanguage\Support\UrlHelper;

/**
 * Get the current language code.
 */
function signocore_ml_get_current_language(): string
{
	return LanguageDetection::load()->getCurrentLanguage();
}

/**
 * Get the default language code.
 */
function signocore_ml_get_default_language(): string
{
	return LanguageManager::load()->getDefaultLanguageCode();
}

/**
 * Get all active languages.
 *
 * @return array<string, object>
 */
function signocore_ml_get_active_languages(): array
{
	return LanguageManager::load()->getActiveLanguages();
}

/**
 * Get the translated element ID for a given language.
 *
 * @param int $elementId Post or term ID.
 * @param string $langCode Target language code.
 * @param string $elementType 'post' or 'term'.
 */
function signocore_ml_get_translation(int $elementId, string $langCode, string $elementType = 'post'): ?int
{
	return TranslationHelper::getTranslation($elementId, $langCode, $elementType);
}

/**
 * Get all translations for an element.
 *
 * @param int $elementId Post or term ID.
 * @param string $elementType 'post' or taxonomy name (e.g. 'category', 'post_tag').
 * @return array<string, int> Language code => element ID.
 */
function signocore_ml_get_translations(int $elementId, string $elementType = 'post'): array
{
	if ($elementType === 'post' || str_starts_with($elementType, 'post_')) {
		return TranslationRepository::getTranslationsForPost($elementId);
	}

	$taxonomy = str_starts_with($elementType, 'tax_') ? substr($elementType, 4) : $elementType;

	return TranslationRepository::getTranslationsForTerm($elementId, $taxonomy);
}

/**
 * Temporarily switch the current language.
 */
function signocore_ml_switch_language(string $langCode): void
{
	LanguageDetection::load()->switchLanguage($langCode);
}

/**
 * Restore the previous language after a switch.
 */
function signocore_ml_restore_language(): void
{
	LanguageDetection::load()->restoreLanguage();
}

/**
 * Render the language switcher.
 *
 * @param array<string, mixed> $args Switcher arguments.
 */
function signocore_language_switcher(array $args = []): string
{
	return LanguageSwitcher::load()->render($args);
}

/**
 * Translate a registered string.
 *
 * @param string $context Plugin/theme slug.
 * @param string $name String identifier.
 * @param string $default Default value if no translation found.
 */
function signocore_ml_translate_string(string $context, string $name, string $default = ''): string
{
	return StringTranslation::load()->translateString($context, $name, $default);
}

/**
 * Check if the current language is the default language.
 */
function signocore_ml_is_default_language(): bool
{
	return signocore_ml_get_current_language() === signocore_ml_get_default_language();
}

/**
 * Get the language of a specific element.
 *
 * @param int $elementId Post or term ID.
 */
function signocore_ml_get_element_language(int $elementId): string
{
	return TranslationHelper::getElementLanguage($elementId);
}

/**
 * Get posts filtered by the current language.
 *
 * By default, only the main query is language-filtered.
 * Use this for secondary queries that should respect language.
 *
 * @param array<string, mixed> $args WP_Query arguments.
 * @return \WP_Post[]
 */
function signocore_ml_get_posts(array $args = []): array
{
	$args['sml_filter_language'] = true;
	$args['suppress_filters'] = false;

	return get_posts($args);
}

/**
 * Get the current page URL in a different language.
 *
 * @param string $langCode Target language code.
 * @param string|null $url URL to convert (defaults to current page).
 */
function signocore_ml_get_url_for_language(string $langCode, ?string $url = null): string
{
	return UrlHelper::getUrlForLanguage($langCode, $url);
}

/**
 * Get the permalink for a post in a specific language.
 *
 * Returns the permalink of the translated version of a post.
 * If no translation exists, returns null.
 *
 * @param int $postId Source post ID.
 * @param string $langCode Target language code.
 */
function signocore_ml_get_permalink(int $postId, string $langCode): ?string
{
	$translatedId = signocore_ml_get_translation($postId, $langCode);
	if ($translatedId === null) {
		return null;
	}

	$detection = LanguageDetection::load();
	$detection->switchLanguage($langCode);
	$permalink = get_permalink($translatedId);
	$detection->restoreLanguage();

	return $permalink !== false ? (string) $permalink : null;
}

/**
 * Check if a translation exists for an element in a given language.
 *
 * @param int $elementId Post or term ID.
 * @param string $langCode Target language code.
 * @param string $elementType 'post' or 'term'.
 */
function signocore_ml_has_translation(int $elementId, string $langCode, string $elementType = 'post'): bool
{
	return TranslationHelper::hasTranslation($elementId, $langCode, $elementType);
}
