<?php
/**
 * Helper functions supporting the admin post list translation UI.
 *
 * @package WPR_Translate
 */

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

/**
 * Returns the languages configured as active.
 *
 * @return array
 */
function wpr_translation_get_active_languages() {
    // Load stored language settings.
    $languages = get_option( 'wpr_translate_languages', array() );

    if ( empty( $languages ) || ! is_array( $languages ) ) {
        // No languages configured.
        return array();
    }

    $active = array();

    foreach ( $languages as $language ) {
        if ( empty( $language['is_active'] ) ) {
            continue;
        }

        // Normalize the subset of language data used in admin lists.
        $active[] = array(
            'code'       => isset( $language['code'] ) ? sanitize_text_field( $language['code'] ) : '',
            'name'       => isset( $language['name'] ) ? sanitize_text_field( $language['name'] ) : '',
            'is_default' => ! empty( $language['is_default'] ),
        );
    }

    // Return only entries with valid language codes.
    return array_values(
        array_filter(
            $active,
            static function( $language ) {
                return '' !== $language['code'];
            }
        )
    );
}

/**
 * Returns the element type used to store translation relationships.
 *
 * @param string $post_type Post type.
 *
 * @return string
 */
function wpr_translation_get_element_type( $post_type ) {
    return 'post_' . $post_type;
}

/**
 * Returns the element type key for taxonomy terms.
 *
 * @param string $taxonomy Taxonomy slug.
 *
 * @return string
 */
function wpr_translation_get_taxonomy_element_type( $taxonomy ) {
    return 'tax_' . $taxonomy;
}

/**
 * Retrieves translation data for the given post.
 *
 * @param int    $post_id      Post ID.
 * @param string $element_type Element type key.
 *
 * @return array
 */
function wpr_translation_get_translation_group( $post_id, $element_type ) {
    global $wpdb;

    // Query the translation group ID for this element.
    $table = $wpdb->prefix . 'wpestate_translation_translations';

    $record = $wpdb->get_row(
        $wpdb->prepare(
            "SELECT trid FROM {$table} WHERE element_id = %d AND element_type = %s LIMIT 1",
            $post_id,
            $element_type
        ),
        ARRAY_A
    );

    if ( ! $record ) {
        // No translation record exists yet.
        return array(
            'trid'            => 0,
            'translations'    => array(),
            'source_language' => '',
            'needs_update'    => array(),
        );
    }

    $trid = (int) $record['trid'];

    $rows = $wpdb->get_results(
        $wpdb->prepare(
            "SELECT element_id, language_code, source_language_code, original, needs_update FROM {$table} WHERE trid = %d AND element_type = %s",
            $trid,
            $element_type
        ),
        ARRAY_A
    );

    if ( empty( $rows ) ) {
        // No translations found for this group.
        return array(
            'trid'            => 0,
            'translations'    => array(),
            'source_language' => '',
            'needs_update'    => array(),
        );
    }

    $translations       = array();
    $source_language    = '';
    $needs_update       = array();
    $fallback_source    = '';
    $first_language_key = '';

    foreach ( $rows as $row ) {
        $language_code = isset( $row['language_code'] ) ? sanitize_key( $row['language_code'] ) : '';

        if ( '' === $language_code ) {
            continue;
        }

        if ( '' === $first_language_key ) {
            // Track the first language as a fallback.
            $first_language_key = $language_code;
        }

        $translations[ $language_code ] = (int) $row['element_id'];
        $needs_update[ $language_code ]  = ! empty( $row['needs_update'] );

        if ( empty( $fallback_source ) && ! empty( $row['source_language_code'] ) ) {
            // Record a fallback source language when provided.
            $fallback_source = sanitize_key( $row['source_language_code'] );
        }

        if ( (int) $row['original'] === 1 ) {
            // Mark the original language when flagged.
            $source_language = $language_code;
        }
    }

    if ( '' === $source_language && '' !== $fallback_source ) {
        // Fall back to the stored source language code.
        $source_language = $fallback_source;
    }

    if ( '' === $source_language && '' !== $first_language_key ) {
        // Final fallback to the first language seen.
        $source_language = $first_language_key;
    }

    return array(
        'trid'            => $trid,
        'translations'    => $translations,
        'source_language' => $source_language,
        'needs_update'    => $needs_update,
    );
}

/**
 * Determines whether a translation post is available for reuse.
 *
 * @param int $post_id Potential translation post ID.
 *
 * @return bool
 */
function wpr_translation_is_translation_post_available( $post_id ) {
    // Normalize the post ID.
    $post_id = absint( $post_id );

    if ( ! $post_id ) {
        // Invalid post ID.
        return false;
    }

    $status = get_post_status( $post_id );

    if ( false === $status || 'trash' === $status ) {
        // Do not treat trashed or missing posts as available.
        return false;
    }

    return true;
}

/**
 * Resolve the language code assigned to a post.
 *
 * @param int    $post_id   Post identifier.
 * @param string $post_type Post type slug.
 *
 * @return string
 */
function wpr_translation_resolve_post_language_code( $post_id, $post_type ) {
    // Normalize the post ID.
    $post_id = absint( $post_id );

    if ( ! $post_id ) {
        // Invalid post ID.
        return '';
    }

    $element_type = wpr_translation_get_element_type( $post_type );
    $group        = wpr_translation_get_translation_group( $post_id, $element_type );

    if ( ! empty( $group['translations'] ) ) {
        // Find the language code that maps back to this post ID.
        foreach ( $group['translations'] as $code => $translated_post_id ) {
            if ( (int) $translated_post_id === $post_id ) {
                return $code;
            }
        }
    }

    if ( ! empty( $group['source_language'] ) ) {
        // Fall back to the group's source language.
        return $group['source_language'];
    }

    return '';
}

/**
 * Formats the language badge label for edit screens.
 *
 * @param string $language_code Language code.
 *
 * @return string
 */
function wpr_translation_format_language_version_label( $language_code ) {
    // Normalize the language code.
    $language_code = strtolower( sanitize_key( $language_code ) );

    if ( '' === $language_code ) {
        // No language code to format.
        return '';
    }

    $language_name = '';

    if ( function_exists( 'wpr_translate_get_language' ) ) {
        // Use the language name when available.
        $language_data = wpr_translate_get_language( $language_code );

        if ( is_array( $language_data ) && ! empty( $language_data['name'] ) ) {
            $language_name = sanitize_text_field( $language_data['name'] );
        }
    }

    if ( '' === $language_name ) {
        // Fall back to the uppercase code.
        $language_name = strtoupper( $language_code );
    }

    /* translators: %s: language code. */
    return sprintf( __( '%s version', 'wpr-translate' ), $language_name );
}

/**
 * Formats the language badge label for post creation screens.
 *
 * @param string $language_code Language code.
 *
 * @return string
 */
function wpr_translation_format_language_creation_label( $language_code ) {
    // Normalize the language code.
    $language_code = strtolower( sanitize_key( $language_code ) );

    if ( '' === $language_code ) {
        // No language code to format.
        return '';
    }

    $language_name = '';

    if ( function_exists( 'wpr_translate_get_language' ) ) {
        // Use the language name when available.
        $language_data = wpr_translate_get_language( $language_code );

        if ( is_array( $language_data ) && ! empty( $language_data['name'] ) ) {
            $language_name = sanitize_text_field( $language_data['name'] );
        }
    }

    if ( '' === $language_name ) {
        // Fall back to the uppercase code.
        $language_name = strtoupper( $language_code );
    }

    /* translators: %s: language code. */
    return sprintf( __( 'in language %s', 'wpr-translate' ), $language_name );
}

/**
 * Generates the action name for the nonce protecting translation requests.
 *
 * @param int    $post_id  Post ID.
 * @param string $language Language code.
 *
 * @return string
 */
function wpr_translation_get_translation_nonce_action( $post_id, $language ) {
    // Build a nonce action string tied to a post and language.
    return 'wpr_add_translation_' . absint( $post_id ) . '_' . sanitize_key( $language );
}

/**
 * Generates a new translation group identifier.
 *
 * @return int
 */
function wpr_translation_generate_trid() {
    global $wpdb;

    // Find the current max translation group ID.
    $table = $wpdb->prefix . 'wpestate_translation_translations';
    $max   = (int) $wpdb->get_var( "SELECT MAX(trid) FROM {$table}" );

    // Increment for a new group ID.
    return $max + 1;
}
