<?php
/**
 * Plugin-wide translation loading + admin language override.
 *
 * Two jobs:
 *  1. Register the bundled languages/ folder so the .mo files ship with the
 *     plugin actually load on self-hosted installs (wp.org language packs
 *     don't exist for this plugin — without load_plugin_textdomain() the
 *     bundled translations are never consulted).
 *  2. Apply the admin language choice (Dashboard → Plugin language). The
 *     choice is stored in the same option the onboarding wizard uses
 *     (shieldforge_onboarding_locale), so wizard and dashboard selector
 *     stay in sync. Empty option = follow the WordPress site/user locale.
 *
 * The override is admin-only on purpose: front-end output (footer badge)
 * and visitor-facing strings keep following the site locale.
 *
 * @package Brainwerk Security Suite
 */

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

class Shieldforge_I18n {

    /**
     * Short onboarding codes -> full WP locales we ship .mo files for.
     */
    const LOCALE_MAP = array(
        'de' => 'de_DE',
        'en' => 'en_US',
        'fr' => 'fr_FR',
        'it' => 'it_IT',
        'es' => 'es_ES',
        'pl' => 'pl_PL',
    );

    public static function register( Shieldforge_Loader $loader ) {
        // WP 6.7 warns when textdomains load before 'init' — hook exactly there.
        $loader->add_action( 'init', __CLASS__, 'load_textdomains', 1 );
    }

    public static function load_textdomains() {
        // No load_plugin_textdomain() here: since WordPress 4.6 the core
        // just-in-time loader auto-loads the plugin's bundled catalog (by slug
        // + Domain Path header) the moment a string is translated. The explicit
        // per-locale overrides below use load_textdomain() directly.
        if ( ! is_admin() ) {
            return;
        }
        $choice = self::admin_language();
        if ( '' === $choice || ! isset( self::LOCALE_MAP[ $choice ] ) ) {
            // No override. The plugin's source strings are mixed EN/DE, so an
            // English admin still needs the en_US catalog (it carries the
            // English translations of the German source strings). WP's JIT
            // loader skips en_US entirely — load it ourselves.
            $locale = function_exists( 'determine_locale' ) ? determine_locale() : get_locale();
            if ( 0 === strpos( (string) $locale, 'en' ) ) {
                self::force_locale( 'en_US' );
            }
            return;
        }
        self::force_locale( self::LOCALE_MAP[ $choice ] );
    }

    /**
     * The stored admin language choice ('de', 'fr', …) or '' when the
     * plugin should follow the WordPress locale.
     */
    public static function admin_language() {
        if ( ! class_exists( 'Shieldforge_Onboarding_I18n' ) ) {
            return '';
        }
        $stored = is_multisite()
            ? get_site_option( Shieldforge_Onboarding_I18n::OPTION_KEY, '' )
            : get_option( Shieldforge_Onboarding_I18n::OPTION_KEY, '' );

        return ( $stored && Shieldforge_Onboarding_I18n::is_supported( $stored ) ) ? (string) $stored : '';
    }

    /**
     * Persist the admin language choice. '' / 'auto' clears the override.
     */
    public static function set_admin_language( $choice ) {
        $choice = (string) $choice;
        if ( '' === $choice || 'auto' === $choice ) {
            if ( is_multisite() ) {
                delete_site_option( Shieldforge_Onboarding_I18n::OPTION_KEY );
            } else {
                delete_option( Shieldforge_Onboarding_I18n::OPTION_KEY );
            }
            return true;
        }
        return Shieldforge_Onboarding_I18n::set_locale( $choice );
    }

    /**
     * Swap the loaded translations of both plugin textdomains to $locale,
     * regardless of the site/user locale. The unload (non-reloadable) blocks
     * WP's just-in-time loader from pulling the site locale back in; the
     * explicit load_textdomain pins our bundled catalog. en_US is loaded
     * like any other locale — it carries the English translations of the
     * plugin's German source strings.
     */
    private static function force_locale( $locale ) {
        $domains = array(
            'brainwerk-security-suite' => SHIELDFORGE_PATH . 'languages/brainwerk-security-suite-',
        );
        if ( defined( 'SHIELDFORGE_PRO_PATH' ) ) {
            $domains['brainwerk-security-suite-premium'] = SHIELDFORGE_PRO_PATH . 'languages/brainwerk-security-suite-premium-';
        }

        foreach ( $domains as $domain => $base ) {
            unload_textdomain( $domain );
            $mofile = $base . $locale . '.mo';
            if ( file_exists( $mofile ) ) {
                load_textdomain( $domain, $mofile, $locale );
            }
        }
    }

    /**
     * Choices for the dashboard selector: '' = follow WordPress, then the
     * six shipped languages with native labels.
     */
    public static function choices() {
        $choices = array(
            '' => __( 'WordPress default (automatic)', 'brainwerk-security-suite' ),
        );
        if ( class_exists( 'Shieldforge_Onboarding_I18n' ) ) {
            foreach ( Shieldforge_Onboarding_I18n::locales() as $code => $label ) {
                $choices[ $code ] = $label;
            }
        }
        return $choices;
    }
}
