<?php
/**
 * Utility functions for STWP plugin.
 *
 * @package STWP
 * @since 1.1.0
 */

namespace STWP;

// If this file is called directly, abort.
if ( ! defined( 'ABSPATH' ) ) {
	die( 'Direct access not allowed.' );
}

/**
 * Utils class provides helper functions.
 *
 * @since 1.0.0
 */
final class Utils {

	/**
	 * Get option value with fallback default.
	 *
	 * @since 1.0.0
	 * @param string $key     Option key.
	 * @param mixed  $default Default value if option doesn't exist.
	 * @return mixed Option value or default.
	 */
	public static function get_option( $key, $default = null ) {
		$value = \get_option( $key, $default );
		return $value === null ? $default : $value;
	}

	/**
	 * Get boolean option value.
	 *
	 * @since 1.0.0
	 * @param string $key     Option key.
	 * @param bool   $default Default boolean value.
	 * @return bool Boolean option value.
	 */
	public static function bool_option( $key, $default = false ) {
		return (bool) self::get_option( $key, $default );
	}

	/**
	 * Get integer option value.
	 *
	 * @since 1.0.0
	 * @param string $key     Option key.
	 * @param int    $default Default integer value.
	 * @return int Integer option value.
	 */
	public static function int_option( $key, $default ) {
		return \absint( self::get_option( $key, $default ) );
	}

	/**
	 * Clamp integer value between min and max.
	 *
	 * @since 1.0.0
	 * @param mixed $value    Value to clamp.
	 * @param int   $min      Minimum allowed value.
	 * @param int   $max      Maximum allowed value.
	 * @param int   $fallback Fallback value if out of range.
	 * @return int Clamped integer value.
	 */
	public static function clamp_int( $value, $min, $max, $fallback ) {
		$v = \absint( $value );
		if ( $v < $min || $v > $max ) {
			return $fallback;
		}
		return $v;
	}

	/**
	 * Check if server can output WebP images.
	 *
	 * @since 1.0.0
	 * @return bool True if WebP output is supported, false otherwise.
	 */
	public static function can_output_webp() {
		// Use WordPress image editor abstraction.
		if ( ! \function_exists( 'wp_get_image_editor' ) ) {
			return false;
		}

		// Check WP output format support (available in WP 5.8+).
		if ( \function_exists( 'wp_get_image_editor_output_format_support' ) ) {
			$support = \wp_get_image_editor_output_format_support();
			if ( \is_array( $support ) ) {
				foreach ( $support as $from => $to ) {
					if ( \is_array( $to ) && ! empty( $to['image/webp'] ) ) {
						return true;
					}
				}
			}
		}

		// Fallback: Check Imagick support.
		if ( \extension_loaded( 'imagick' ) ) {
			try {
				$im   = new \Imagick();
				$fmts = $im->queryFormats( 'WEBP' );
				return ! empty( $fmts );
			} catch ( \Exception $e ) {
				// Imagick check failed, continue to GD check.
			}
		}

		// Fallback: Check GD support.
		if ( \function_exists( 'imagewebp' ) ) {
			return true;
		}

		return false;
	}

	/**
	 * Check if current screen is a media-related admin screen.
	 *
	 * @since 1.0.0
	 * @return bool True if on media screen, false otherwise.
	 */
	public static function is_admin_screen_media() {
		if ( ! \function_exists( 'get_current_screen' ) ) {
			return false;
		}
		$screen = \get_current_screen();
		if ( ! $screen ) {
			return false;
		}
		return \in_array( $screen->id, array( 'upload', 'media', 'options-media' ), true );
	}

	/**
	 * Detect if a GIF file is animated.
	 *
	 * @since 1.0.0
	 * @param string $file_path Path to GIF file.
	 * @return bool True if animated, false otherwise.
	 */
	public static function is_animated_gif( $file_path ) {
		if ( ! \is_readable( $file_path ) ) {
			return false;
		}

		// Use WP_Filesystem for file operations.
		if ( ! \function_exists( 'WP_Filesystem' ) ) {
			require_once \ABSPATH . 'wp-admin/includes/file.php';
		}
		\WP_Filesystem();
		global $wp_filesystem;

		if ( ! $wp_filesystem ) {
			return false;
		}

		// Read first ~200KB to check for animation markers.
		$chunk = $wp_filesystem->get_contents( $file_path );
		if ( false === $chunk || empty( $chunk ) ) {
			return false;
		}

		// Limit to first 200KB for performance.
		if ( \strlen( $chunk ) > 1024 * 200 ) {
			$chunk = \substr( $chunk, 0, 1024 * 200 );
		}

		// Check for NETSCAPE2.0 extension (common animation marker).
		if ( false !== \strpos( $chunk, 'NETSCAPE2.0' ) ) {
			return true;
		}
		// Count frame headers as heuristic.
		$frames = \preg_match_all( '#\x00\x21\xF9\x04#s', $chunk );
		return $frames && $frames > 1;
	}

	/**
	 * Generate safe backup path for original file.
	 *
	 * @since 1.0.0
	 * @param string $file_path Original file path.
	 * @return string Backup file path.
	 */
	public static function safe_backup_path( $file_path ) {
		$info = \pathinfo( $file_path );
		$ext  = isset( $info['extension'] ) ? '.' . $info['extension'] : '';
		return $info['dirname'] . '/' . $info['filename'] . '.stwp-backup' . $ext;
	}

	/**
	 * Safe logging for debug purposes.
	 *
	 * @since 1.0.0
	 * @param string $message Message to log.
	 * @return void
	 */
	public static function safe_log( $message ) {
		if ( \defined( 'WP_DEBUG' ) && \WP_DEBUG ) {
			// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
			\error_log( '[STWP] ' . $message );
		}
	}
}
