<?php
/**
 * Utility Functions
 *
 * General utility functions for date formatting, debugging, URI handling
 *
 * @since   3.0.0
 * @package WC_Affiliate
 */

/**
 * Check if pro version is activated.
 *
 * @since 1.0.0
 * @return bool True if pro version is active and activated.
 */
function wca_has_pro(): bool {
	return array_key_exists( 'wc-affiliate-pro/wc-affiliate-pro.php', get_plugins() );
}

/**
 * Check if pro version is activated (legacy compatibility)
 *
 * @return bool True if pro version is active
 */
function wca_is_pro_activated(): bool {
	return is_plugin_active( 'wc-affiliate-pro/wc-affiliate-pro.php' );
}

/**
 * Format date according to WordPress settings.
 *
 * @since 1.0.0
 *
 * @param string $date   The date string (e.g., 'Y-m-d H:i:s').
 * @param string $format Optional. PHP date format. Defaults to WordPress date format setting.
 *
 * @return string Formatted date string.
 */
function wca_format_date( string $date, string $format = '' ): string {
	if ( empty( $format ) ) {
		$format = get_option( 'date_format' );
	}

	return date_i18n( $format, strtotime( $date ) );
}

/**
 * Print variable content for debugging purposes.
 *
 * @since 1.0.0
 *
 * @param mixed $data          The data to print.
 * @param bool  $admin_only    Should it display in wp-admin area only.
 * @param bool  $hide_adminbar Should it hide the admin bar.
 */
function wca_pri( $data, bool $admin_only = true, bool $hide_adminbar = true ) {
	if ( $admin_only && ! current_user_can( 'manage_options' ) ) {
		return;
	}

	echo wp_kses_post( '<pre>' );
	if ( is_object( $data ) || is_array( $data ) ) {
		print_r( $data );
	} else {
		var_dump( $data );
	}
	echo wp_kses_post( '</pre>' );

	if ( is_admin() && $hide_adminbar ) {
		echo '<style>#adminmenumain{display:none;}</style>';
	}
}

/**
 * Log messages to WordPress error log.
 *
 * @since 1.0.0
 *
 * @param string $message The message to log.
 * @param string $level   Log level (info, error, warning, etc.).
 */
function wca_log( string $message, string $level = 'info' ) {
	error_log( sprintf( '[WC Affiliate - %s] %s', strtoupper( $level ), $message ) );
}

/**
 * Logs messages to a specific log file.
 *
 * @since 1.0.0
 *
 * @param mixed  $message  The message to log. If not a string, it will be converted to JSON.
 * @param string $log_file The log file to write to within the wp-content directory.
 */
function wca_log_debug( $message, string $log_file = 'debug.log' ) {
	// Only run in WordPress environment.
	if ( ! defined( 'ABSPATH' ) || ABSPATH === '' ) {
		return;
	}

	global $wp_filesystem;

	if ( ! function_exists( 'WP_Filesystem' ) ) {
		require_once ABSPATH . 'wp-admin/includes/file.php';
	}

	WP_Filesystem();

	if ( ! is_string( $message ) ) {
		$message = wp_json_encode( $message );
	}

	if ( ! defined( 'WP_CONTENT_DIR' ) ) {
		return;
	}

	if ( ! file_exists( $log_path = WP_CONTENT_DIR . '/wc-affiliate-logs/' . $log_file ) ) {
		$wp_filesystem->mkdir( dirname( $log_path ) );
		$wp_filesystem->put_contents( $log_path, '', FS_CHMOD_FILE );
	}

	$log_entry = sprintf( "[%s] %s\n", time(), $message );

	$wp_filesystem->put_contents( $log_path, $log_entry, FS_CHMOD_FILE | FILE_APPEND );
}

/**
 * Get current page URI.
 *
 * @since 1.0.0
 * @return string Current URI.
 */
function wca_get_current_uri(): string {
	global $wp;

	return home_url( $wp->request );
}

/**
 * Get landing URI with query strings.
 *
 * @since 1.0.0
 * @return string Landing URI.
 */
function wca_get_landing_uri(): string {
	return home_url( add_query_arg( null, null ) );
}

/**
 * Get visitor IP address.
 *
 * @since 1.0.0
 * @return string IP address or 'UNKNOWN'.
 */
function wca_get_client_ip(): string {
	$ip_keys = array(
		'HTTP_CLIENT_IP',
		'HTTP_X_FORWARDED_FOR',
		'HTTP_X_FORWARDED',
		'HTTP_FORWARDED',
		'REMOTE_ADDR',
	);

	foreach ( $ip_keys as $key ) {
		if ( ! empty( $_SERVER[ $key ] ) ) {
			return sanitize_text_field( wp_unslash( $_SERVER[ $key ] ) );
		}
	}

	return 'UNKNOWN';
}

/**
 * Format price with currency symbol.
 *
 * @since 1.0.0
 *
 * @param float $amount Amount to format.
 *
 * @return string Formatted price.
 */
function wca_format_price( float $amount ): string {
	if ( function_exists( 'easycommerce_price' ) ) {
		return easycommerce_price( $amount );
	}

	if ( function_exists( 'wc_price' ) ) {
		return wc_price( $amount );
	}

	return number_format( $amount, 2 );
}

/**
 * Get pages options for setup wizard.
 *
 * @return array Array of page options.
 */
function wca_get_pages_options(): array {
	$pages = get_pages(
		array(
			'sort_column' => 'menu_order,post_title',
			'post_status' => 'publish',
		)
	);

	$options = array( '' => __( '- Select a page -', 'wc-affiliate' ) );

	foreach ( $pages as $page ) {
		$options[ $page->ID ] = $page->post_title;
	}

	return $options;
}

/**
 * Get posts with caching support.
 *
 * @since 1.0.0
 *
 * @param array $args         WP_Query arguments.
 * @param bool  $show_heading Whether to show default heading option.
 * @param bool  $show_cached  Whether to use cached results.
 *
 * @return array Array of posts.
 */
function wca_get_posts( array $args = array(), bool $show_heading = true, bool $show_cached = true ): array {
	$defaults = array(
		'post_type'      => 'post',
		'posts_per_page' => -1,
		'post_status'    => 'publish',
	);

	$_args = wp_parse_args( $args, $defaults );

	if ( true === $show_cached && ( $cached_posts = wp_cache_get( "wc_affiliate_{$_args['post_type']}", 'wc-affiliate' ) ) ) {
		$posts = $cached_posts;
	} else {
		$queried = new \WP_Query( $_args );

		$posts = array();
		foreach ( $queried->posts as $post ) :
			$posts[ $post->ID ] = $post->post_title;
		endforeach;

		wp_cache_add( "wc_affiliate_{$_args['post_type']}", $posts, 'wc-affiliate', 3600 );
	}

	/* Translators: %s is the post type (e.g., "post", "page"). */
	$posts = $show_heading ? array( '' => sprintf( __( '- Choose a %s -', 'wc-affiliate' ), $_args['post_type'] ) ) + $posts : $posts;

	return apply_filters( 'wc_affiliate_get_posts', $posts, $_args );
}

/**
 * Include and return template content.
 *
 * @since 1.0.0
 *
 * @param string     $slug      Template slug.
 * @param string     $base      Base directory (default: 'views').
 * @param array|null $args      Template arguments.
 * @param bool       $is_return Whether to return content or include directly.
 *
 * @return string|void Template content if $is_return is true.
 */
function wca_get_template( string $slug, string $base = 'views', array $args = array(), bool $is_return = true ) {
	// Allow theme override.
	$overwrite_template_dir = apply_filters( 'wc_affiliate_template_overwrite_dir', get_stylesheet_directory() . '/wc-affiliate/', $slug, $base, $args );

	// Default plugin template directory - use a proper constant or fallback.
	$plugin_base_dir     = defined( 'WC_AFFILIATE_PLUGIN_DIR' ) ? WC_AFFILIATE_PLUGIN_DIR : plugin_dir_path( dirname( __DIR__, 2 ) );
	$plugin_template_dir = trailingslashit( $plugin_base_dir . $base );

	// Full paths.
	$plugin_template_path    = $plugin_template_dir . $slug . '.php';
	$overwrite_template_path = $overwrite_template_dir . $slug . '.php';

	// Extract arguments for template with security checks.
	if ( ! empty( $args ) ) {
		// Sanitize array keys to prevent variable name conflicts.
		// Only allow alphanumeric keys with underscores.
		$safe_args = array_filter(
			$args,
			function ( $key ) {
				return preg_match( '/^[a-zA-Z_][a-zA-Z0-9_]*$/', $key );
			},
			ARRAY_FILTER_USE_KEY
		);
		extract( $safe_args, EXTR_SKIP ); // Use EXTR_SKIP to prevent overwriting existing variables.
	}

	if ( $is_return ) {
		ob_start();

		if ( file_exists( $overwrite_template_path ) ) {
			include $overwrite_template_path;
		} elseif ( file_exists( $plugin_template_path ) ) {
			include $plugin_template_path;
		} else {
			echo esc_html__( 'Template not found!', 'wc-affiliate' );
		}

		return ob_get_clean();
	} elseif ( file_exists( $overwrite_template_path ) ) {
		include $overwrite_template_path;
	} elseif ( file_exists( $plugin_template_path ) ) {
		include $plugin_template_path;
	} else {
		echo esc_html__( 'Template not found!', 'wc-affiliate' );
	}
}

/**
 * Get affiliate notices values and configurations
 *
 * @since 1.0.0
 * @return array Array of notice configurations with URLs
 */
function wc_affiliate_notices_values(): array {
	return array(
		'wc_affiliate_migration' => array(
			'url' => admin_url( 'admin.php?page=wc-affiliate/#/' ),
		),
		'wc_affiliate_after_sw'  => array(
			'url' => admin_url( 'admin.php?page=wc-affiliate' ),
		),
	);
}

/**
 * Get date range difference for default date filtering
 *
 * @return int Number of seconds for 30 days
 */
function wca_date_range_diff(): int {
	return 30 * DAY_IN_SECONDS;
}
