<?php
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}
if ( ! function_exists( 'drop_print_files_canonical_key' ) ) {
	function drop_print_files_canonical_key( string $filename ): string {
		$filename = sanitize_file_name( $filename );
		$exts     = array( '.drop' );
		if ( defined( 'DROP_PRINT_LEGACY_CONTAINER_EXTS' ) ) {
			foreach ( explode( ',', DROP_PRINT_LEGACY_CONTAINER_EXTS ) as $legacy_ext ) {
				$legacy_ext = trim( $legacy_ext );
				if ( '' !== $legacy_ext ) {
					$exts[] = $legacy_ext;
				}
			}
		} else {
			$exts[] = '.afp';
		}
		foreach ( $exts as $ext ) {
			$ext_len = strlen( $ext );
			if ( strtolower( substr( $filename, -$ext_len ) ) === $ext ) {
				return substr( $filename, 0, -$ext_len );
			}
		}
		return $filename;
	}
}
if ( ! function_exists( 'drop_print_files_normalize_raw' ) ) {
	function drop_print_files_normalize_raw( $raw ): array {
		$index = array(
			'schema_version' => 2,
			'files'          => array(),
		);
		if ( ! is_array( $raw ) ) {
			return $index;
		}
		if ( isset( $raw['schema_version'] ) && (int) $raw['schema_version'] >= 2 ) {
			$index['files'] = ( isset( $raw['files'] ) && is_array( $raw['files'] ) ) ? $raw['files'] : array();
			return $index;
		}
		foreach ( $raw as $key => $product_ids ) {
			if ( ! is_string( $key ) || '' === $key ) {
				continue;
			}
			$canonical = drop_print_files_canonical_key( $key );
			if ( '' === $canonical ) {
				continue;
			}
			$ids = is_array( $product_ids ) ? array_filter( array_map( 'absint', $product_ids ) ) : array();
			if ( ! isset( $index['files'][ $canonical ] ) ) {
				$index['files'][ $canonical ] = array( 'product_ids' => array() );
			}
			$index['files'][ $canonical ]['product_ids'] = array_values( array_unique( array_merge( $index['files'][ $canonical ]['product_ids'], $ids ) ) );
		}
		return $index;
	}
}
if ( ! function_exists( 'drop_print_files_get_index' ) ) {
	function drop_print_files_get_index(): array {
		return drop_print_files_normalize_raw( get_option( 'drop_print_files', array() ) );
	}
}
if ( ! function_exists( 'drop_print_files_save_index' ) ) {
	function drop_print_files_save_index( array $index ): void {
		$index['schema_version'] = 2;
		if ( ! isset( $index['files'] ) || ! is_array( $index['files'] ) ) {
			$index['files'] = array();
		}
		update_option( 'drop_print_files', $index );
	}
}
if ( ! function_exists( 'drop_print_files_get_record' ) ) {
	function drop_print_files_get_record( string $filename ): ?array {
		$key   = drop_print_files_canonical_key( $filename );
		$index = drop_print_files_get_index();
		return ( '' !== $key && isset( $index['files'][ $key ] ) && is_array( $index['files'][ $key ] ) ) ? $index['files'][ $key ] : null;
	}
}
if ( ! function_exists( 'drop_print_files_upsert_record' ) ) {
	function drop_print_files_upsert_record( string $filename, array $fields ): void {
		$key = drop_print_files_canonical_key( $filename );
		if ( '' === $key ) {
			return;
		}
		$index  = drop_print_files_get_index();
		$record = ( isset( $index['files'][ $key ] ) && is_array( $index['files'][ $key ] ) ) ? $index['files'][ $key ] : array( 'product_ids' => array() );
		if ( isset( $fields['product_ids'] ) && is_array( $fields['product_ids'] ) ) {
			$record['product_ids'] = array_values( array_unique( array_merge( $record['product_ids'] ?? array(), array_filter( array_map( 'absint', $fields['product_ids'] ) ) ) ) );
			unset( $fields['product_ids'] );
		}
		$index['files'][ $key ] = array_merge( $record, $fields );
		drop_print_files_save_index( $index );
	}
}
if ( ! function_exists( 'drop_print_files_add_product_ref' ) ) {
	function drop_print_files_add_product_ref( string $filename, int $product_id ): void {
		if ( ! $product_id ) {
			return;
		}
		drop_print_files_upsert_record( $filename, array( 'product_ids' => array( $product_id ) ) );
	}
}
if ( ! function_exists( 'drop_print_files_remove_product_ref' ) ) {
	function drop_print_files_remove_product_ref( string $filename, int $product_id ): bool {
		$key = drop_print_files_canonical_key( $filename );
		if ( '' === $key || ! $product_id ) {
			return true;
		}
		$index = drop_print_files_get_index();
		if ( ! isset( $index['files'][ $key ] ) || ! is_array( $index['files'][ $key ] ) ) {
			return true;
		}
		$refs = array_filter( array_map( 'absint', $index['files'][ $key ]['product_ids'] ?? array() ) );
		$refs = array_values( array_diff( $refs, array( $product_id ) ) );
		$index['files'][ $key ]['product_ids'] = $refs;
		drop_print_files_save_index( $index );
		return empty( $refs );
	}
}
if ( ! function_exists( 'drop_print_files_is_referenced' ) ) {
	function drop_print_files_is_referenced( string $filename ): bool {
		$record = drop_print_files_get_record( $filename );
		return is_array( $record ) && ! empty( $record['product_ids'] );
	}
}
if ( ! function_exists( 'drop_print_files_delete_record' ) ) {
	function drop_print_files_delete_record( string $filename ): void {
		$key   = drop_print_files_canonical_key( $filename );
		$index = drop_print_files_get_index();
		if ( '' !== $key && isset( $index['files'][ $key ] ) ) {
			unset( $index['files'][ $key ] );
			drop_print_files_save_index( $index );
		}
	}
}
if ( ! function_exists( 'drop_print_files_parse_container_header' ) ) {
	function drop_print_files_parse_container_header( string $container_path ): ?array {
		if ( ! file_exists( $container_path ) || ! is_readable( $container_path ) ) {
			return null;
		}
		$handle = @fopen( $container_path, 'rb' );
		if ( ! $handle ) {
			return null;
		}
		$result = null;
		try {
			$enc_packed = fread( $handle, 1 );
			if ( false === $enc_packed || strlen( $enc_packed ) < 1 ) {
				return null;
			}
			$encrypted    = 1 === unpack( 'C', $enc_packed )[1];
			$thumb_packed = fread( $handle, 1 );
			if ( false === $thumb_packed || strlen( $thumb_packed ) < 1 ) {
				return null;
			}
			if ( 1 === unpack( 'C', $thumb_packed )[1] ) {
				$mime_len_packed = fread( $handle, 1 );
				if ( false === $mime_len_packed || strlen( $mime_len_packed ) < 1 ) {
					return null;
				}
				$mime_len = unpack( 'C', $mime_len_packed )[1];
				if ( $mime_len <= 0 || -1 === fseek( $handle, $mime_len, SEEK_CUR ) ) {
					return null;
				}
				$thumb_len_packed = fread( $handle, 4 );
				if ( false === $thumb_len_packed || strlen( $thumb_len_packed ) < 4 ) {
					return null;
				}
				$thumb_len = unpack( 'N', $thumb_len_packed )[1];
				if ( $thumb_len <= 0 || -1 === fseek( $handle, $thumb_len, SEEK_CUR ) ) {
					return null;
				}
			}
			$hash_packed = fread( $handle, 32 );
			if ( false === $hash_packed || strlen( $hash_packed ) < 32 ) {
				return null;
			}
			$source_sha256 = bin2hex( $hash_packed );
			if ( str_repeat( '0', 64 ) === $source_sha256 ) {
				$source_sha256 = null;
			}
			$result = array(
				'encrypted'     => $encrypted,
				'source_sha256' => $source_sha256,
			);
		} finally {
			fclose( $handle );
		}
		return $result;
	}
}
