<?php
/**
 * BookiFlex Core
 *
 * @package    BookiFlex
 * @subpackage Core
 * @author     BookiFlex
 * @copyright  Copyright (c) 2025 BookiFlex
 * @license    GPL-2.0-or-later
 *
 * @link       https://bookiflex.com
 */

declare(strict_types=1);

namespace BookiFlex\Core\I18n;

defined('ABSPATH') || exit;

/**
 * Loads JED JSON translation files for script modules.
 *
 * wp_set_script_translations() only works with handles registered via wp_enqueue_script().
 * Script modules (wp_enqueue_script_module) need a custom loader that reads the same
 * JSON files and injects wp.i18n.setLocaleData() via inline script.
 */
class TranslationLoader
{
    private string $pluginDir;
    private string $textDomain;

    public function __construct(string $pluginDir, string $textDomain = 'bookiflex')
    {
        $this->pluginDir = $pluginDir;
        $this->textDomain = $textDomain;
    }

    /**
     * Generate inline JS that calls wp.i18n.setLocaleData() with merged translations
     * for the given script file paths.
     *
     * @param string[] $scriptRelativePaths Paths relative to plugin dir (e.g. "assets/free/admin/index.HASH.js")
     * @return string JavaScript code, or empty string if no translations found
     */
    public function getInlineScript(array $scriptRelativePaths, ?string $locale = null): string
    {
        $locale ??= determine_locale();
        if ($locale === 'en_US') {
            return '';
        }

        $merged = [];
        $pluralForms = null;

        foreach ($scriptRelativePaths as $relativePath) {
            if (empty($relativePath)) {
                continue;
            }

            $messages = $this->loadJsonTranslation($locale, $relativePath);
            if ($messages !== null) {
                if ($pluralForms === null && isset($messages['']['plural-forms'])) {
                    $pluralForms = $messages['']['plural-forms'];
                }
                unset($messages['']);
                $merged = array_merge($merged, $messages);
            }
        }

        if (empty($merged)) {
            return '';
        }

        $header = [
            'domain' => $this->textDomain,
            'lang'   => $locale,
        ];
        if ($pluralForms !== null) {
            $header['plural-forms'] = $pluralForms;
        }
        $merged[''] = $header;

        return sprintf(
            'wp.i18n.setLocaleData(%s, %s);',
            wp_json_encode($merged),
            wp_json_encode($this->textDomain)
        );
    }

    /**
     * Load a JSON translation file for a specific JS file path.
     *
     * Replicates WordPress md5 lookup: {domain}-{locale}-{md5 of relative path}.json
     * Checks plugin languages dir first, then WP global languages dir.
     *
     * Returns the full locale_data.messages array including the JED "" header
     * (which carries plural-forms). The caller is responsible for stripping it
     * before merging and rebuilding a clean header.
     *
     * @return array<string, mixed>|null locale_data.messages, or null if not found
     */
    private function loadJsonTranslation(string $locale, string $relativePath): ?array
    {
        $md5 = md5($relativePath);
        $filename = "{$this->textDomain}-{$locale}-{$md5}.json";

        $searchPaths = [
            $this->pluginDir . 'languages/' . $filename,
            WP_LANG_DIR . '/plugins/' . $filename,
        ];

        foreach ($searchPaths as $path) {
            if (!file_exists($path)) {
                continue;
            }

            $content = file_get_contents($path);
            if ($content === false) {
                continue;
            }

            $data = json_decode($content, true);
            if (!is_array($data) || empty($data['locale_data']['messages'])) {
                continue;
            }

            return $data['locale_data']['messages'];
        }

        return null;
    }
}
