<?php
declare(strict_types=1);


if ( ! defined( 'ABSPATH' ) ) {
    exit;
}
/**
 * ProRank SEO Helper Functions
 *
 * @package ProRank
 */

// Prevent direct access
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Get plugin instance
 *
 * @return \ProRank\SEO\Plugin
 */
if (!function_exists('prorank')) {
    function prorank() {
        return \ProRank\SEO\Plugin::get_instance();
    }
}

/**
 * Get plugin version
 *
 * @return string
 */
function prorank_version(): string {
    return PRORANK_VERSION;
}

/**
 * Get plugin directory path
 *
 * @param string $path Optional path to append.
 * @return string
 */
function prorank_dir( string $path = '' ): string {
    $dir = PRORANK_PLUGIN_DIR;
    
    if ( $path ) {
        $dir .= ltrim( $path, '/\\' );
    }
    
    return $dir;
}

/**
 * Get plugin URL
 *
 * @param string $path Optional path to append.
 * @return string
 */
function prorank_url( string $path = '' ): string {
    $url = PRORANK_PLUGIN_URL;
    
    if ( $path ) {
        $url .= ltrim( $path, '/\\' );
    }
    
    return $url;
}

/**
 * Sanitize inline CSS for output.
 *
 * @param string $css
 * @return string
 */
function prorank_sanitize_inline_css(string $css): string {
    return trim(wp_strip_all_tags($css));
}

/**
 * Check if we're in development mode
 *
 * @return bool
 */
function prorank_is_dev(): bool {
    return defined( 'WP_DEBUG' ) && WP_DEBUG && defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG_DISPLAY;
}

/**
 * Safe JSON encode with error handling
 *
 * @param mixed $data Data to encode.
 * @param int   $options JSON encode options.
 * @param int   $depth Maximum depth.
 * @return string|false
 */
function prorank_json_encode( $data, int $options = 0, int $depth = 512 ) {
    $json = json_encode( $data, $options, $depth );
    
    if ( json_last_error() !== JSON_ERROR_NONE ) {
        if ( prorank_is_dev() ) {
            if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
                prorank_log( 'ProRank SEO JSON encode error: ' . json_last_error_msg() );
            }
        }
        return false;
    }
    
    return $json;
}

/**
 * Safe JSON decode with error handling
 *
 * @param string $json JSON string to decode.
 * @param bool   $associative Return associative array.
 * @param int    $depth Maximum depth.
 * @param int    $options Decode options.
 * @return mixed|null
 */
function prorank_json_decode( string $json, bool $associative = true, int $depth = 512, int $options = 0 ) {
    $data = json_decode( $json, $associative, $depth, $options );
    
    if ( json_last_error() !== JSON_ERROR_NONE ) {
        if ( prorank_is_dev() ) {
            if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
                prorank_log( 'ProRank SEO JSON decode error: ' . json_last_error_msg() );
            }
        }
        return null;
    }
    
    return $data;
}

/**
 * Get asset URL with version for cache busting
 *
 * @param string $asset Asset path relative to plugin directory.
 * @return string
 */
function prorank_asset_url( string $asset ): string {
    $url = prorank_url( $asset );
    $version = prorank_version();
    
    if ( prorank_is_dev() ) {
        $version .= '.' . time();
    }
    
    return add_query_arg( 'ver', $version, $url );
}

/**
 * Check if a module is enabled
 *
 * @param string $module Module slug.
 * @return bool
 */
function prorank_is_module_enabled( string $module ): bool {
    // Get the module manager instance if plugin is loaded
    if ( class_exists( '\ProRank\SEO\Plugin' ) ) {
        try {
            return prorank()->modules()->is_active( $module );
        } catch ( \Exception $e ) {
            // Fallback if module manager isn't ready
            return false;
        }
    }
    
    return false;
}

/**
 * Get plugin option with type safety
 *
 * @param string $option Option name.
 * @param mixed  $default Default value.
 * @return mixed
 */
function prorank_get_option( string $option, $default = null ) {
    // Get the settings manager instance if plugin is loaded
    if ( class_exists( '\ProRank\SEO\Plugin' ) ) {
        try {
            return prorank()->settings()->get( $option, $default );
        } catch ( \Exception $e ) {
            // Fallback to WordPress option
            return get_option( 'prorank_' . $option, $default );
        }
    }
    
    return get_option( 'prorank_' . $option, $default );
}

/**
 * Update plugin option with type safety
 *
 * @param string $option Option name.
 * @param mixed  $value Option value.
 * @return bool
 */
function prorank_update_option( string $option, $value ): bool {
    // Get the settings manager instance if plugin is loaded
    if ( class_exists( '\ProRank\SEO\Plugin' ) ) {
        try {
            return prorank()->settings()->update( $option, $value );
        } catch ( \Exception $e ) {
            // Fallback to WordPress option
            return update_option( 'prorank_' . $option, $value );
        }
    }
    
    return update_option( 'prorank_' . $option, $value );
}

/**
 * Log a message if in development mode
 *
 * @param string $message Message to log.
 * @param string $level Log level (error, warning, info).
 */
function prorank_log( string $message, string $level = 'info' ): void {
    if ( ! prorank_is_dev() ) {
        return;
    }
    
    $prefix = '[ProRank SEO] [' . strtoupper( $level ) . '] ';
    do_action( 'prorank_seo_log', $prefix . $message, $level );
}

/**
 * Get a sanitized server variable.
 *
 * @param string $key Server key.
 * @return string
 */
function prorank_get_server_var( string $key ): string {
    if ( ! isset( $_SERVER[ $key ] ) ) {
        return '';
    }

    return sanitize_text_field( wp_unslash( $_SERVER[ $key ] ) );
}

/**
 * Get an unslashed input value from a request source.
 *
 * @param array<string, mixed> $source  Input source.
 * @param string               $key     Input key.
 * @param mixed                $default Default value.
 * @return mixed
 */
function prorank_get_input_value( array $source, string $key, $default = '' ) {
    if ( ! isset( $source[ $key ] ) ) {
        return $default;
    }

    $value = $source[ $key ];

    if ( is_array( $value ) ) {
        return map_deep( wp_unslash( $value ), 'sanitize_text_field' );
    }

    return wp_unslash( $value );
}

/**
 * Check whether an input source contains a key.
 *
 * @param array<string, mixed> $source Input source.
 * @param string               $key    Input key.
 * @return bool
 */
function prorank_has_input( array $source, string $key ): bool {
    return array_key_exists( $key, $source );
}

/**
 * Get a sanitized query parameter.
 *
 * @param string $key Query key.
 * @return string
 */
function prorank_get_query_var( string $key ): string {
    return sanitize_text_field( (string) prorank_get_input_value( $_GET, $key, '' ) );
}

/**
 * Check whether a query parameter exists.
 *
 * @param string $key Query key.
 * @return bool
 */
function prorank_has_query_var( string $key ): bool {
    return isset( $_GET[ $key ] );
}

/**
 * Get a sanitized post parameter.
 *
 * @param string $key Post key.
 * @return string
 */
function prorank_get_post_var( string $key ): string {
    return sanitize_text_field( (string) prorank_get_input_value( $_POST, $key, '' ) );
}

/**
 * Check whether a post parameter exists.
 *
 * @param string $key Post key.
 * @return bool
 */
function prorank_has_post_var( string $key ): bool {
    return isset( $_POST[ $key ] );
}

/**
 * Get a sanitized request parameter.
 *
 * @param string $key Request key.
 * @return string
 */
function prorank_get_request_var( string $key ): string {
    return sanitize_text_field( (string) prorank_get_input_value( $_REQUEST, $key, '' ) );
}

/**
 * Check whether a request parameter exists.
 *
 * @param string $key Request key.
 * @return bool
 */
function prorank_has_request_var( string $key ): bool {
    return isset( $_REQUEST[ $key ] );
}

/**
 * Get the current request method.
 *
 * @return string
 */
function prorank_get_request_method(): string {
    return strtoupper( prorank_get_server_var( 'REQUEST_METHOD' ) );
}

/**
 * Check whether the current request has query parameters.
 *
 * @return bool
 */
function prorank_has_query_params(): bool {
    return ! empty( $_GET );
}

/**
 * Get unslashed query parameters.
 *
 * @return array<string, mixed>
 */
function prorank_get_query_params(): array {
    return isset( $_GET ) && is_array( $_GET ) ? wp_unslash( $_GET ) : [];
}

/**
 * Get the current user's license tier
 *
 * @return string
 */
function prorank_get_license_tier(): string {
    return 'free';
}

/**
 * Check if user has access to a specific tier
 *
 * @param string $tier Tier to check (core, pro, business, agency).
 * @return bool
 */
function prorank_has_tier( string $tier ): bool {
    return 'free' === $tier;
}

/**
 * Get normalized home (site root) filesystem path.
 *
 * @return string
 */
function prorank_get_home_path(): string {
    if ( ! function_exists( 'get_home_path' ) ) {
        require_once ABSPATH . 'wp-admin/includes/file.php';
    }

    return trailingslashit( wp_normalize_path( (string) get_home_path() ) );
}

/**
 * Build a file path relative to site root.
 *
 * @param string $relative Relative filename/path.
 * @return string
 */
function prorank_home_file_path(string $relative): string {
    return prorank_get_home_path() . ltrim($relative, '/\\');
}
