<?php

namespace FleekDash\Services;

defined('ABSPATH') || exit;

if (!\function_exists('fleekdash_log_debug')) {
    require_once FLEEKDASH_PLUGIN_DIR . 'includes/Core/debug-helpers.php';
}

/**
 * Keeps WordPress native locale in sync when FleekDash user locale changes.
 */
class WordPressLocaleSyncService
{
    private const ENGLISH_LOCALE = 'en_US';

    /**
     * @return array{
     *   core_language_pack: bool,
     *   site_language_synced: bool,
     *   core_language_pack_error?: string
     * }
     */
    public function syncAfterUserLocaleChange(string $locale, int $userId): array
    {
        $corePackResult = $this->ensureCoreLanguagePackInstalled($locale);
        $siteSynced = $this->syncSiteLanguageIfAllowed($locale, $userId);

        $result = [
            'core_language_pack' => $corePackResult['installed'],
            'site_language_synced' => $siteSynced,
        ];

        if (isset($corePackResult['error'])) {
            $result['core_language_pack_error'] = $corePackResult['error'];
        }

        fleekdash_log_debug(
            '[LocaleSync] User ' . $userId . ' locale sync result: '
            . \wp_json_encode($result)
        );

        return $result;
    }

    /**
     * @return array{installed: bool, error?: string}
     */
    private function ensureCoreLanguagePackInstalled(string $locale): array
    {
        $result = ['installed' => true];

        if (!$this->isEnglishLocale($locale)) {
            $this->loadTranslationInstallDependencies();

            if (!\function_exists('wp_download_language_pack')) {
                $result = [
                    'installed' => false,
                    'error' => 'WordPress translation installer is unavailable',
                ];
            } elseif (!$this->isCoreLanguagePackInstalled($locale)) {
                $downloadResult = \wp_download_language_pack($locale);
                $installed = $downloadResult === true
                    || $this->isCoreLanguagePackInstalled($locale);

                if ($installed) {
                    \wp_cache_delete('translations', 'core');
                } else {
                    $errorMessage = $downloadResult instanceof \WP_Error
                        ? $downloadResult->get_error_message()
                        : 'Failed to install WordPress core language pack';

                    $result = [
                        'installed' => false,
                        'error' => $errorMessage,
                    ];
                }
            }
        }

        return $result;
    }

    private function isEnglishLocale(string $locale): bool
    {
        return $locale === self::ENGLISH_LOCALE || $locale === 'en';
    }

    private function loadTranslationInstallDependencies(): void
    {
        if (!\function_exists('WP_Filesystem')) {
            require_once ABSPATH . 'wp-admin/includes/file.php';
        }

        if (!\function_exists('wp_download_language_pack')) {
            require_once ABSPATH . 'wp-admin/includes/translation-install.php';
        }
    }

    private function isCoreLanguagePackInstalled(string $locale): bool
    {
        $languageDir = WP_CONTENT_DIR . '/languages';
        $candidates = [
            $languageDir . '/' . $locale . '.mo',
            $languageDir . '/admin-' . $locale . '.mo',
            $languageDir . '/' . $locale . '.po',
        ];

        foreach ($candidates as $path) {
            if (\file_exists($path)) {
                return true;
            }
        }

        if (\function_exists('wp_get_installed_translations')) {
            $installed = \wp_get_installed_translations('core');

            return isset($installed[$locale]);
        }

        return false;
    }

    private function syncSiteLanguageIfAllowed(string $locale, int $userId): bool
    {
        if (!\user_can($userId, 'manage_options')) {
            return false;
        }

        $siteLocale = $this->isEnglishLocale($locale) ? '' : $locale;
        \update_option('WPLANG', $siteLocale);
        \wp_cache_delete('alloptions', 'options');

        return \get_option('WPLANG') === $siteLocale;
    }
}
