<?php

/**
 * Translation model.
 *
 * @package northmill-online-shared
 */
declare (strict_types=1);
namespace Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Modules\i18n\Models;

use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Abstract_Shared_Base;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Helpers\General_Helpers;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Modules\Loggers\Log_Level_Enum;
defined('ABSPATH') || exit;
/**
 * Translation model.
 */
abstract class Abstract_Translation_Model
{
    private const DEFAULT_TRANSLATION_PATH = 'languages';
    /**
     * Shared instance.
     *
     * @var Abstract_Shared_Base
     */
    private Abstract_Shared_Base $shared;
    /**
     * The text domain.
     *
     * @var string
     */
    protected string $textdomain;
    /**
     * The locale.
     *
     * @var string
     */
    protected string $locale;
    /**
     * The path to the dir containing mofile, relative to the package root.
     *
     * @var string
     */
    private string $path_rel;
    /**
     * The absolute path to the dir containing mofile.
     *
     * @var string
     */
    private string $path_abs;
    /**
     * The mofile name.
     *
     * @var string
     */
    protected string $mofile_name;
    /**
     * The mofile prefix.
     *
     * @var string|null
     */
    protected ?string $mofile_prefix;
    /**
     * The priority used for scheduling the translation load.
     *
     * @var int
     */
    protected int $priority;
    /**
     * Whether the text domain is for a plugin or not.
     *
     * @var bool
     */
    protected bool $is_plugin = \true;
    /**
     * Constructor.
     *
     * @param array|string $translation The translation to be added.
     *        Each array item can be either:
     *            Associative array:
     *                Key 'textdomain' (required) representing the text domain.
     *                Key 'path' (optional, defaults from class constant) representing the translation file path, relative to package root.
     *            String:
     *                Text domain. Path defaults from class constant.
     */
    public function __construct(array|string $translation)
    {
        $this->shared = Abstract_Shared_Base::base_instance();
        if (!is_array($translation)) {
            $translation = array('textdomain' => $translation, 'path' => self::DEFAULT_TRANSLATION_PATH);
        }
        if (!isset($translation['path'])) {
            $translation['path'] = self::DEFAULT_TRANSLATION_PATH;
        }
        $this->textdomain = $translation['textdomain'];
        $this->path_rel = $translation['path'];
        $this->path_abs = $this->shared->package_info->paths->get_path() . $this->path_rel;
        $this->mofile_prefix = $translation['mofile_prefix'] ?? null;
        $this->priority = General_Helpers::version_to_priority($this->shared->package_info->get_shared_version());
        $this->locale = determine_locale();
        $this->set_mofile_name();
        $this->register_translation();
    }
    /**
     * Set the mofile name.
     *
     * @return void
     */
    abstract protected function set_mofile_name(): void;
    /**
     * Set the mofile name.
     *
     * @return void
     */
    abstract protected function register_translation(): void;
    /**
     * Load the text domain.
     *
     * @return void
     */
    public function load_textdomain(): void
    {
        global $wp_textdomain_registry;
        $wp_textdomain_registry->set_custom_path($this->textdomain, $this->path_abs);
        $mofile_path = $this->path_abs . '/' . $this->mofile_name;
        $loaded = load_textdomain($this->textdomain, $mofile_path, $this->locale);
        if (!$loaded) {
            $this->maybe_log_on_error($this->textdomain, $mofile_path, $this->is_plugin);
        }
    }
    /**
     * Log warning on text domain load error.
     *
     * @param string $text_domain The text domain.
     * @param string $path        The path to the translation file.
     * @param bool   $is_plugin   Whether the text domain is for a plugin or not.
     *
     * @return void
     */
    protected function maybe_log_on_error(string $text_domain, string $path, bool $is_plugin): void
    {
        if ($this->shared->debug->is_on()) {
            $this->shared->logger->log('i18n', 'Failed to load text domain', array('text_domain' => $text_domain, 'path' => $path, 'is_plugin' => $is_plugin), Log_Level_Enum::WARNING);
        }
    }
    /**
     * Get the text domain.
     *
     * @return string The text domain.
     */
    public function get_textdomain(): string
    {
        return $this->textdomain;
    }
    /**
     * Get model data.
     *
     * @return array
     */
    public function get_data(): array
    {
        return array('textdomain' => $this->textdomain, 'locale' => $this->locale, 'path_rel' => $this->path_rel, 'path_abs' => $this->path_abs, 'full_path' => $this->path_abs . '/' . $this->mofile_name, 'mofile_name' => $this->mofile_name, 'mofile_prefix' => $this->mofile_prefix, 'priority' => $this->priority, 'is_plugin' => $this->is_plugin);
    }
}
