<?php
/**
 * 文件名处理类：处理中文文件名，参考 Shopify 规则
 * 
 * 主要功能：
 * 1. 将中文字符转换为拼音
 * 2. 移除或替换特殊字符
 * 3. 确保文件名符合 Shopify 规范（不能以句点开头，避免特定后缀）
 */

namespace Tooto_Elementor;

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

class Filename_Sanitizer {

	/**
	 * Shopify 不允许的文件名后缀
	 * 这些后缀可能与 Shopify 的图片转换请求冲突
	 */
	private const FORBIDDEN_SUFFIXES = [
		'pico',
		'icon',
		'thumb',
		'testing',
		'small',
		'compact',
		'medium',
		'large',
		'grande',
	];

	/**
	 * 初始化文件名处理
	 */
	public static function init(): void {
		// 在上传前处理文件名
		add_filter( 'wp_handle_upload_prefilter', [ __CLASS__, 'sanitize_filename' ] );
	}

	/**
	 * 处理上传文件的文件名
	 *
	 * @param array $file 上传文件数组
	 * @return array 处理后的文件数组
	 */
	public static function sanitize_filename( $file ) {
		if ( ! isset( $file['name'] ) ) {
			return $file;
		}

		$original_name = $file['name'];
		$sanitized_name = self::process_filename( $original_name );

		// 如果文件名被修改，更新文件数组
		if ( $sanitized_name !== $original_name ) {
			$file['name'] = $sanitized_name;
		}

		return $file;
	}

	/**
	 * 处理文件名
	 *
	 * @param string $filename 原始文件名
	 * @return string 处理后的文件名
	 */
	public static function process_filename( $filename ): string {
		// 分离文件名和扩展名
		$pathinfo = pathinfo( $filename );
		$name     = isset( $pathinfo['filename'] ) ? $pathinfo['filename'] : '';
		$ext      = isset( $pathinfo['extension'] ) ? $pathinfo['extension'] : '';

		// 处理文件名部分
		$name = self::convert_chinese_to_pinyin( $name );
		$name = self::remove_special_chars( $name );
		$name = self::apply_shopify_rules( $name );

		// 确保文件名不为空
		if ( empty( $name ) ) {
			$name = 'file-' . time();
		}

		// 重新组合文件名
		$sanitized = $name . ( ! empty( $ext ) ? '.' . $ext : '' );

		// 最终清理：确保符合文件系统规范
		$sanitized = sanitize_file_name( $sanitized );

		return $sanitized;
	}

	/**
	 * 将中文字符转换为拼音
	 * 
	 * 注意：此方法使用基础转换，如果需要更准确的拼音转换，
	 * 可以集成第三方库如 Overtrue Pinyin
	 *
	 * @param string $text 包含中文的文本
	 * @return string 转换后的文本
	 */
	private static function convert_chinese_to_pinyin( string $text ): string {
		// 如果文本中没有中文字符，直接返回
		if ( ! self::contains_chinese( $text ) ) {
			return $text;
		}

		// 使用 WordPress 的 sanitize_title 作为基础处理
		// 但这会将中文转换为 URL 友好的格式，不是真正的拼音
		// 更好的方案是使用拼音库，这里先提供一个基础实现

		// 尝试使用 WordPress 的翻译功能（如果可用）
		// 或者使用基础的字符替换
		$pinyin = self::basic_chinese_to_pinyin( $text );

		return $pinyin;
	}

	/**
	 * 基础的中文转拼音实现
	 * 这是一个简化版本，建议使用专业的拼音库
	 *
	 * @param string $text 文本
	 * @return string 转换后的文本
	 */
	private static function basic_chinese_to_pinyin( string $text ): string {
		// 方案1：尝试使用 PHP 的 transliterator（如果可用，这是最准确的方法）
		if ( class_exists( 'Transliterator' ) ) {
			try {
				$transliterator = \Transliterator::create( 'Any-Latin; Latin-ASCII; Lower()' );
				if ( $transliterator ) {
					$transliterated = $transliterator->transliterate( $text );
					// 如果转换成功且结果不同，直接返回
					if ( $transliterated !== false && $transliterated !== $text && ! empty( $transliterated ) ) {
						return $transliterated;
					}
				}
			} catch ( \Exception $e ) {
				// 忽略错误，继续使用其他方法
			}
		}

		// 方案2：使用函数式 transliterator（如果可用）
		if ( function_exists( 'transliterator_transliterate' ) ) {
			$transliterated = transliterator_transliterate( 'Any-Latin; Latin-ASCII; Lower()', $text );
			if ( $transliterated !== false && $transliterated !== $text && ! empty( $transliterated ) ) {
				return $transliterated;
			}
		}

		// 方案3：将中文字符逐个转换为安全的文件名格式
		// 这里我们使用一个更实用的方法：将中文转换为安全的文件名格式
		$text = preg_replace_callback(
			'/[\x{4e00}-\x{9fa5}]+/u',
			function ( $matches ) {
				// 将中文字符转换为拼音（这里使用简化处理）
				// 实际应用中建议使用专业的拼音转换库
				return self::chinese_to_pinyin_safe( $matches[0] );
			},
			$text
		);

		return $text;
	}

	/**
	 * 将中文字符串转换为安全的文件名格式
	 * 
	 * 当 transliteration 在主方法中失败时，这里作为备用方案
	 * 生产环境建议使用专业的拼音库如：https://github.com/overtrue/pinyin
	 *
	 * @param string $chinese 中文字符串
	 * @return string 转换后的字符串
	 */
	private static function chinese_to_pinyin_safe( string $chinese ): string {
		// 使用 WordPress 的 sanitize_title（会移除中文，但保留其他字符）
		// 为了保留可读性，我们先用 sanitize_title 处理，然后添加一个基于中文的标识
		$sanitized = sanitize_title( $chinese );
		
		// 如果 sanitize_title 移除了所有内容（说明全是中文），使用哈希值
		if ( empty( $sanitized ) ) {
			// 使用短哈希确保唯一性和可读性
			// 注意：这不是真正的拼音，但能确保文件名唯一且安全
			$hash = substr( md5( $chinese ), 0, 8 );
			return 'cn-' . $hash;
		}

		return $sanitized;
	}

	/**
	 * 检查文本是否包含中文字符
	 *
	 * @param string $text 文本
	 * @return bool 是否包含中文
	 */
	private static function contains_chinese( string $text ): bool {
		return preg_match( '/[\x{4e00}-\x{9fa5}]/u', $text ) === 1;
	}

	/**
	 * 移除或替换特殊字符
	 *
	 * @param string $text 文本
	 * @return string 处理后的文本
	 */
	private static function remove_special_chars( string $text ): string {
		// 移除或替换不安全的字符
		// 保留字母、数字、连字符、下划线和空格
		$text = preg_replace( '/[^a-zA-Z0-9\-_\s]/', '-', $text );

		// 将多个连续的特殊字符替换为单个连字符
		$text = preg_replace( '/[-_\s]+/', '-', $text );

		// 移除开头和结尾的连字符
		$text = trim( $text, '-' );

		return $text;
	}

	/**
	 * 应用 Shopify 文件名规则
	 *
	 * @param string $filename 文件名（不含扩展名）
	 * @return string 处理后的文件名
	 */
	private static function apply_shopify_rules( string $filename ): string {
		// 规则1：不能以句点开头
		$filename = ltrim( $filename, '.' );

		// 规则2：检查是否以禁止的后缀结尾
		$lowercase = strtolower( $filename );
		foreach ( self::FORBIDDEN_SUFFIXES as $suffix ) {
			if ( substr( $lowercase, -strlen( $suffix ) ) === $suffix ) {
				// 如果以禁止的后缀结尾，添加一个后缀来避免冲突
				$filename .= '-file';
				break;
			}
		}

		// 确保文件名不为空
		if ( empty( $filename ) ) {
			$filename = 'file-' . time();
		}

		return $filename;
	}
}

