<?php
/**
 * Plugin activation and uninstall helpers.
 *
 * @package WPR_Translate
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}
/**
 * Run during plugin activation.
 */
function wpr_translate_activate_plugin() {
    // Create required tables before storing any plugin settings.
    wpr_translate_activator_create_tables();

    // Track the plugin version so upgrades can be detected later.
    add_option( 'wpr_translate_version', WPR_TRANSLATE_VERSION );

    // Seed languages and ensure core defaults are stored.
    $default_language = wpr_translate_activator_install_languages();
    wpr_translate_activator_ensure_default_settings( $default_language );

    // Refresh rewrite rules so language routes are registered.
    flush_rewrite_rules();
}
/**
 * Run during plugin uninstall.
 */
function wpr_translate_uninstall_plugin() {
    // Remove plugin options that should not persist after uninstall.
    delete_option( 'wpr_translate_version' );
    delete_option( 'wpr_translate_languages' );
    delete_option( 'wpr_translate_language_catalog' );
    delete_option( 'wpr_translate_settings' );
}
/**
 * Create required database tables for the translation system.
 */
function wpr_translate_activator_create_tables() {
    global $wpdb;

    // Load the dbDelta helper for safe table creation.
    require_once ABSPATH . 'wp-admin/includes/upgrade.php';

    // Respect the current database charset/collation.
    $charset_collate = $wpdb->get_charset_collate();

    // Prepare table names using the active WordPress prefix.
    $translations_table = $wpdb->prefix . 'wpestate_translation_translations';
    $strings_table      = $wpdb->prefix . 'wpestate_translation_strings';
    $slugs_table        = $wpdb->prefix . 'wpestate_translation_slugs';
    $glossary_table     = $wpdb->prefix . 'wpestate_translation_glossary';
    $memory_table       = $wpdb->prefix . 'wpestate_translation_memory';
    $languages_table    = $wpdb->prefix . 'wpestate_translation_languages';

    // Create the core translations table.
    $sql = "CREATE TABLE {$translations_table} (
        translation_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
        element_type VARCHAR(45) NOT NULL,
        element_id BIGINT(20) UNSIGNED NOT NULL,
        trid BIGINT(20) UNSIGNED NOT NULL,
        language_code VARCHAR(7) NOT NULL,
        source_language_code VARCHAR(7) NULL,
        post_status VARCHAR(20) NOT NULL DEFAULT 'publish',
        translator_id BIGINT(20) UNSIGNED NULL,
        original TINYINT(1) NOT NULL DEFAULT 0,
        needs_update TINYINT(1) NOT NULL DEFAULT 0,
        last_updated DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (translation_id),
        KEY trid (trid),
        KEY element (element_id, element_type),
        KEY language (language_code)
    ) {$charset_collate};";

    dbDelta( $sql );

    // Create the strings table for theme/plugin string translations.
    $sql = "CREATE TABLE {$strings_table} (
        string_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
        context VARCHAR(255) NOT NULL,
        name VARCHAR(255) NOT NULL,
        value TEXT NOT NULL,
        language_code VARCHAR(7) NOT NULL,
        translation TEXT DEFAULT NULL,
        status TINYINT(3) UNSIGNED NOT NULL DEFAULT 0,
        processed TINYINT(1) UNSIGNED NOT NULL DEFAULT 0,
        translator_id BIGINT(20) UNSIGNED NULL,
        updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        md5 CHAR(32) DEFAULT NULL,
        PRIMARY KEY (string_id),
        UNIQUE KEY uniq_string (context, name, language_code),
        KEY language (language_code)
    ) {$charset_collate};";

    dbDelta( $sql );

    // Create the slug translation table for translated permalinks.
    $sql = "CREATE TABLE {$slugs_table} (
        id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
        element_id BIGINT(20) UNSIGNED NOT NULL,
        element_type VARCHAR(45) NOT NULL,
        language_code VARCHAR(7) NOT NULL,
        slug VARCHAR(255) NOT NULL,
        old_slugs TEXT DEFAULT NULL,
        updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        UNIQUE KEY uniq_slug (element_id, language_code),
        KEY lang (language_code)
    ) {$charset_collate};";

    dbDelta( $sql );

    // Create the glossary table for term memory.
    $sql = "CREATE TABLE {$glossary_table} (
        id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
        term VARCHAR(255) NOT NULL,
        language_code VARCHAR(7) NOT NULL,
        translation VARCHAR(255) NOT NULL,
        context VARCHAR(255) DEFAULT NULL,
        updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        KEY lang (language_code)
    ) {$charset_collate};";

    dbDelta( $sql );

    // Create the translation memory table to reuse past translations.
    $sql = "CREATE TABLE {$memory_table} (
        id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
        source_text LONGTEXT NOT NULL,
        language_code VARCHAR(7) NOT NULL,
        translated_text LONGTEXT DEFAULT NULL,
        similarity_hash CHAR(32) DEFAULT NULL,
        source_language_code VARCHAR(7) DEFAULT NULL,
        updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        KEY hash (similarity_hash),
        KEY lang (language_code)
    ) {$charset_collate};";

    dbDelta( $sql );

    // Create the languages table for active language metadata.
    $sql = "CREATE TABLE {$languages_table} (
        code VARCHAR(7) NOT NULL,
        name VARCHAR(64) NOT NULL,
        locale VARCHAR(10) DEFAULT NULL,
        flag VARCHAR(255) DEFAULT NULL,
        is_default TINYINT(1) NOT NULL DEFAULT 0,
        active TINYINT(1) NOT NULL DEFAULT 1,
        display_order INT NOT NULL DEFAULT 0,
        PRIMARY KEY (code)
    ) {$charset_collate};";

    dbDelta( $sql );
}

/**
 * Install predefined languages and seed defaults on first run.
 *
 * @return array Default language payload.
 */
function wpr_translate_activator_install_languages() {
    // Load the catalog so default language matching can occur.
    $catalog = get_option( 'wpr_translate_language_catalog', array() );

    if ( empty( $catalog ) ) {
        // Seed the catalog the first time the plugin is activated.
        $catalog = wpr_translate_activator_get_predefined_languages_catalog();
        update_option( 'wpr_translate_language_catalog', $catalog );
    }

    // Reuse existing language settings when present.
    $languages = get_option( 'wpr_translate_languages', array() );

    if ( ! empty( $languages ) ) {
        // Return the stored default language if one exists.
        foreach ( $languages as $language ) {
            if ( isset( $language['is_default'] ) && $language['is_default'] ) {
                return $language;
            }
        }

        // Fall back to the first configured language.
        return array_shift( $languages );
    }

    // Match the site's locale against the catalog.
    $site_locale = get_locale();
    $default     = wpr_translate_activator_match_catalog_language( $catalog, $site_locale );

    if ( null === $default ) {
        // Build a minimal fallback language when the locale is not in the catalog.
        $default = array(
            'code'   => substr( $site_locale, 0, 2 ),
            'locale' => $site_locale,
            'name'   => $site_locale,
            'slug'   => substr( $site_locale, 0, 2 ),
            'flag'   => '',
        );
    }

    // Use a shorter label for the default English language when possible.
    $default_name = $default['name'];
    if ( '' !== $default_name && 0 === strpos( $default_name, 'English' ) ) {
        $default_name = trim( preg_replace( '/\s*\([^)]*\)\s*$/', '', $default_name ) );
    }

    $default_language = array(
        'code'        => $default['code'],
        'locale'      => $default['locale'],
        'name'        => $default_name,
        'slug'        => isset( $default['slug'] ) ? $default['slug'] : $default['code'],
        'is_default'  => true,
        'is_active'   => true,
        'flag'        => isset( $default['flag'] ) ? $default['flag'] : '',
        'date_format' => get_option( 'date_format' ),
        'time_format' => get_option( 'time_format' ),
    );

    // Store the initial language list with the default language entry.
    $languages[] = $default_language;

    update_option( 'wpr_translate_languages', $languages );

    return $default_language;
}

/**
 * Ensure default plugin settings are stored.
 *
 * @param array $default_language Default language payload.
 */
function wpr_translate_activator_ensure_default_settings( $default_language ) {
    // Load stored settings so defaults can be merged in.
    $settings = get_option( 'wpr_translate_settings', array() );

    if ( ! is_array( $settings ) ) {
        $settings = array();
    }

    // Merge defaults while preserving any existing values.
    $settings = wp_parse_args(
        $settings,
        array(
            'default_language' => isset( $default_language['code'] ) ? $default_language['code'] : 'en',
            'sync_media' => true,
            'enable_url_prefix' => true,
            'detect_browser_language' => true,
            'language_switcher_style' => 'dropdown',
        )
    );

    // Persist the merged settings.
    update_option( 'wpr_translate_settings', $settings );
}

/**
 * Match a predefined language from the catalog.
 *
 * @param array  $catalog     Available catalog languages.
 * @param string $site_locale Site locale string.
 *
 * @return array|null
 */
function wpr_translate_activator_match_catalog_language( $catalog, $site_locale ) {
    // First, attempt an exact locale match.
    foreach ( $catalog as $language ) {
        if ( isset( $language['locale'] ) && strtolower( $language['locale'] ) === strtolower( $site_locale ) ) {
            return $language;
        }
    }

    // If no locale match, fall back to matching just the language code.
    $short = substr( $site_locale, 0, 2 );

    foreach ( $catalog as $language ) {
        if ( isset( $language['code'] ) && strtolower( $language['code'] ) === strtolower( $short ) ) {
            return $language;
        }
    }

    return null;
}
/**
 * Return predefined languages bundled with the plugin.
 *
 * @return array
 */
function wpr_translate_activator_get_predefined_languages_catalog() {
    // Load the hardcoded language catalog keyed by code from the dedicated file.
    require_once plugin_dir_path( __FILE__ ) . 'language-catalog.php';

    // Re-key the catalog and return a flat list of languages.
    $catalog_by_code = wpr_translate_language_catalog_by_code();

    return array_values( $catalog_by_code );
}
