<?php
/**
 * Shared permalink helper functions.
 *
 * @package WPR_Translate
 */

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

require_once __DIR__ . '/permalinks-helpers.php';

/**
 * Log permalink resolution activity when debugging is enabled.
 *
 * @param string $message Message to log.
 * @param array  $context Optional context data.
 *
 * @return void
 */
function wpr_translate_permalink_log( $message, $context = array() ) {
    // Logging disabled.
    return;
}

if ( ! function_exists( 'wpr_translation_localize_url_for_language' ) ) {
    /**
     * Ensures a URL is normalised for a specific language.
     *
     * @param string       $url      Original URL.
     * @param array|string $language Language payload or identifier.
     *
     * @return string
     */
    function wpr_translation_localize_url_for_language( $url, $language ) {
        if ( empty( $url ) ) {
            // Nothing to localize.
            return $url;
        }

        // Track the original URL for comparison/logging.
        $original_url = $url;
        $language_data = null;

        if ( is_array( $language ) ) {
            // Use the provided language payload.
            $language_data = $language;
        } elseif ( is_string( $language ) && '' !== $language ) {
            // Resolve the language payload from the identifier.
            $language_data = wpr_translate_get_language( $language );

            if ( null === $language_data ) {
                // Fallback to a minimal payload when only a code is known.
                $language_data = array( 'code' => $language );
            }
        }

        if ( empty( $language_data ) || ! is_array( $language_data ) ) {
            // Invalid language data means no localization.
            return $url;
        }

        // Normalize and compute the language slug to use in the URL.
        $language_data       = wpr_translate_normalize_language( $language_data );
        $language_is_default = wpr_translate_is_default_language( $language_data );
        $slug                = wpr_translate_get_language_slug( $language_data );

        if ( '' === $slug && ! $language_is_default && ! empty( $language_data['code'] ) && function_exists( 'sanitize_title' ) ) {
            $slug = sanitize_title( $language_data['code'] );
        }

        $parts = wp_parse_url( $url );

        if ( false === $parts ) {
            // Invalid URL structure; leave unchanged.
            return $url;
        }

        // Parse the existing path for manipulation.
        $path              = isset( $parts['path'] ) ? $parts['path'] : '/';
        $has_trailing_slash = '/' === substr( $path, -1 );
        $path_segments      = array_values( array_filter( explode( '/', trim( $path, '/' ) ) ) );

        static $home_parts    = null;
        static $base_segments = null;

        if ( null === $home_parts ) {
            // Resolve home URL parts once per request.
            $raw_home = get_option( 'home' );

            if ( empty( $raw_home ) && function_exists( 'home_url' ) ) {
                $raw_home = home_url( '/' );
            }

            if ( ! empty( $raw_home ) ) {
                $home_parts = wp_parse_url( trailingslashit( $raw_home ) );
            }

            if ( null === $home_parts ) {
                // Ensure a consistent array shape.
                $home_parts = array();
            }
        }

        if ( null === $base_segments ) {
            // Cache the base path segments for the home URL.
            $base_segments = array();

            if ( ! empty( $home_parts['path'] ) ) {
                $base_segments = array_values( array_filter( explode( '/', trim( $home_parts['path'], '/' ) ) ) );
            }
        }

        $relative_segments = $path_segments;

        if ( ! empty( $base_segments ) && ! empty( $relative_segments ) ) {
            // Remove any base path segments from the URL path.
            foreach ( $base_segments as $index => $segment ) {
                if ( isset( $relative_segments[ $index ] ) && $relative_segments[ $index ] === $segment ) {
                    unset( $relative_segments[ $index ] );
                }
            }

            $relative_segments = array_values( $relative_segments );
        }

        $known_slugs    = wpr_translation_get_known_language_slugs();
        $language_slug  = wpr_translate_get_language_slug( $language_data );

        if ( '' !== $language_slug ) {
            $known_slugs[] = $language_slug;
        }

        if ( ! empty( $language_data['code'] ) && function_exists( 'sanitize_title' ) ) {
            $known_slugs[] = sanitize_title( $language_data['code'] );
        }

        $known_slugs = array_values( array_unique( array_filter( array_map( 'strtolower', $known_slugs ) ) ) );

        // Strip any existing language slug from the URL.
        while ( ! empty( $relative_segments ) && in_array( strtolower( $relative_segments[0] ), $known_slugs, true ) ) {
            array_shift( $relative_segments );
        }

        if ( '' !== $slug ) {
            // Prepend the requested language slug.
            array_unshift( $relative_segments, $slug );
        }

        // Rebuild the full path with base and relative segments.
        $new_segments = array_merge( $base_segments, $relative_segments );

        if ( empty( $new_segments ) ) {
            $new_path = '/';
        } else {
            $new_path = '/' . implode( '/', $new_segments );
        }

        if ( $has_trailing_slash ) {
            $new_path = trailingslashit( $new_path );
        } else {
            $new_path = untrailingslashit( $new_path );

            if ( '' === $new_path ) {
                $new_path = '/';
            }
        }

        $parts['path'] = $new_path;

        $localized_url = wpr_translation_build_url_from_parts( $parts );

        if ( $localized_url !== $original_url ) {
            // Log when a URL is modified for transparency during debugging.
            wpr_translate_permalink_log(
                'Localized URL for language.',
                array(
                    'language' => isset( $language_data['code'] ) ? $language_data['code'] : '',
                    'from'     => $original_url,
                    'to'       => $localized_url,
                )
            );
        }

        return $localized_url;
    }
}

if ( ! function_exists( 'wpr_translation_get_post_language_permalink' ) ) {
    /**
     * Retrieves the front-end permalink for a translated post.
     *
     * @param int    $post_id       Translation post ID.
     * @param string $language_code Target language code or slug.
     *
     * @return string Translation permalink or empty string on failure.
     */
    function wpr_translation_get_post_language_permalink( $post_id, $language_code ) {
        // Normalize input values.
        $post_id       = absint( $post_id );
        $language_code = is_string( $language_code ) ? $language_code : '';

        if ( ! $post_id ) {
            // No post ID means there is nothing to resolve.
            return '';
        }

        // Normalize the language code and attempt to resolve a language payload.
        $language_code = trim( $language_code );
        $language      = wpr_translate_get_language( $language_code );

        if ( null === $language && function_exists( 'sanitize_title' ) ) {
            // Retry with a sanitized slug when matching a language.
            $language = wpr_translate_get_language( sanitize_title( $language_code ) );
        }

        $language_is_default = false;
        $resolved_code       = $language_code;

        if ( null !== $language ) {
            // Use the known language payload to determine default status.
            $language_is_default = wpr_translate_is_default_language( $language );

            if ( isset( $language['code'] ) && '' !== $language['code'] ) {
                $resolved_code = $language['code'];
            }
        } else {
            // Use the stored default language when no payload is found.
            $default_language = wpr_translate_get_default_language();

            if ( null !== $default_language && ! empty( $default_language['code'] ) ) {
                $language_is_default = ( strtolower( sanitize_title( $default_language['code'] ) ) === strtolower( sanitize_title( $language_code ) ) );
            } elseif ( function_exists( 'wpr_translation_get_active_languages' ) && function_exists( 'wpr_translation_get_default_language_code' ) ) {
                $languages    = wpr_translation_get_active_languages();
                $default_code = wpr_translation_get_default_language_code( $languages );
                $language_is_default = ( '' !== $default_code && strtolower( sanitize_title( $default_code ) ) === strtolower( sanitize_title( $language_code ) ) );
            }
        }

        $language_payload = $language;

        if ( ! is_array( $language_payload ) ) {
            // Build a minimal payload for downstream helpers.
            $language_payload = array(
                'code'       => $resolved_code,
                'slug'       => '',
                'is_default' => $language_is_default,
            );
        } else {
            $language_payload = array_merge(
                array(
                    'code'       => $resolved_code,
                    'slug'       => isset( $language['slug'] ) ? $language['slug'] : '',
                    'is_default' => $language_is_default,
                ),
                $language
            );
        }

        $permalink = '';

        if ( null !== $language ) {
            // Temporarily switch language so get_permalink uses the correct context.
            $restore_language = wpr_translate_get_current_language();

            wpr_translate_set_current_language( $language );
            $permalink = get_permalink( $post_id );

            if ( null !== $restore_language ) {
                wpr_translate_set_current_language( $restore_language );
            } else {
                wpr_translate_set_current_language( null );
            }
        }

        if ( '' === $permalink ) {
            // Fall back to the default permalink when no language context was applied.
            $permalink = get_permalink( $post_id );
        }

        if ( ! $permalink ) {
            // Bail out when a permalink cannot be resolved.
            return '';
        }

        wpr_translate_permalink_log(
            'Resolved post language permalink.',
            array(
                'post_id'   => $post_id,
                'language'  => $resolved_code,
                'permalink' => $permalink,
            )
        );

        if ( function_exists( 'pll_current_language' ) && function_exists( 'pll_switch_language' ) ) {
            // Support Polylang by switching language during permalink lookup.
            $current_language = pll_current_language( 'slug' );
            $needs_switch     = $current_language && $current_language !== $resolved_code;

            if ( ! $current_language ) {
                $current_language = function_exists( 'pll_default_language' ) ? pll_default_language( 'slug' ) : '';
            }

            if ( $needs_switch ) {
                // Switch to the target language for permalink generation.
                pll_switch_language( $resolved_code );
                $permalink = get_permalink( $post_id );

                if ( $current_language ) {
                    pll_switch_language( $current_language );
                }

                $permalink = $permalink ? $permalink : '';

                // Localize the URL even when Polylang returns a link.
                return wpr_translation_localize_url_for_language( $permalink, $language_payload );
            }

            return wpr_translation_localize_url_for_language( $permalink, $language_payload );
        }

        if ( has_filter( 'wpml_current_language' ) || has_filter( 'wpml_permalink' ) ) {
            // Support WPML by switching or filtering permalinks.
            $current_language = apply_filters( 'wpml_current_language', null );

            if ( $current_language && $current_language !== $resolved_code ) {
                // Switch languages temporarily to generate the permalink.
                do_action( 'wpml_switch_language', $resolved_code );
                $permalink = get_permalink( $post_id );
                do_action( 'wpml_switch_language', $current_language );

                $permalink = $permalink ? $permalink : '';

                // Ensure the URL is localized for the language payload.
                return wpr_translation_localize_url_for_language( $permalink, $language_payload );
            }

            if ( $current_language !== $resolved_code && has_filter( 'wpml_permalink' ) ) {
                $permalink = apply_filters( 'wpml_permalink', $permalink, $resolved_code );
            }

            return wpr_translation_localize_url_for_language( $permalink, $language_payload );
        }

        if ( function_exists( 'pll_permalink' ) ) {
            // Use the direct Polylang permalink helper when available.
            $translated_permalink = pll_permalink( $post_id, $resolved_code );

            if ( ! empty( $translated_permalink ) ) {
                $permalink = $translated_permalink;
            }
        }

        return wpr_translation_localize_url_for_language( $permalink, $language_payload );
    }
}
