<?php
/**
 * Helper functions for article meta handling.
 *
 * @package flo-sync
 */

namespace NMFS\Sync\Items\Articles;

defined( 'ABSPATH' ) || exit;

/**
 * Class Article_Meta_Helpers
 */
class Article_Sync_Meta_Helpers {

	public const META_KEY_SYNC_STATUS         = 'mf_sync_status';
	public const META_KEY_HASH                = 'mf_hash';
	public const META_KEY_LAST_SYNC_RESPONSE  = 'mf_last_sync_response';
	public const META_KEY_SYNC_STATUS_PRIVATE = '_mf_sync_status';
	public const META_KEY_SYNC_ERROR          = '_mf_sync_error_message';
	public const META_KEY_SYNC_LAST           = '_mf_sync_last_sync';

	/**
	 * Get meta value for a product.
	 *
	 * @param int    $product_id Product ID.
	 * @param string $meta_key Meta key.
	 * @return string|null Meta value or null.
	 */
	private static function get_meta( int $product_id, string $meta_key ): ?string {
		$value = get_post_meta( $product_id, $meta_key, true );
		return is_string( $value ) ? $value : null;
	}

	/**
	 * Update meta value for a product.
	 *
	 * @param int    $product_id Product ID.
	 * @param string $meta_key Meta key.
	 * @param string $value Meta value.
	 */
	private static function update_meta( int $product_id, string $meta_key, string $value ): void {
		update_post_meta( $product_id, $meta_key, $value );
	}

	/**
	 * Get sync status meta value.
	 *
	 * @param int $product_id Product ID.
	 * @return string|null Sync status or null.
	 */
	public static function get_sync_status( int $product_id ): ?string {
		return self::get_meta( $product_id, self::META_KEY_SYNC_STATUS );
	}

	/**
	 * Update sync status meta value.
	 *
	 * @param int    $product_id Product ID.
	 * @param string $status Sync status.
	 */
	public static function update_sync_status( int $product_id, string $status ): void {
		self::update_meta( $product_id, self::META_KEY_SYNC_STATUS, $status );
	}

	/**
	 * Set sync status to 'Synced'.
	 *
	 * @param int $product_id Product ID.
	 */
	public static function set_sync_status_synced( int $product_id ): void {
		self::update_sync_status( $product_id, __( 'Synced', 'flo-sync' ) );
	}

	/**
	 * Get last sync response meta value.
	 *
	 * @param int $product_id Product ID.
	 * @return string|null Last sync response or null.
	 */
	public static function get_last_sync_response( int $product_id ): ?string {
		return self::get_meta( $product_id, self::META_KEY_LAST_SYNC_RESPONSE );
	}

	/**
	 * Update last sync response meta value.
	 *
	 * @param int    $product_id Product ID.
	 * @param string $response Sync response.
	 */
	public static function update_last_sync_response( int $product_id, string $response ): void {
		self::update_meta( $product_id, self::META_KEY_LAST_SYNC_RESPONSE, $response );
	}

	/**
	 * Get last synced SKU (ArticleNumber) from last sync response.
	 *
	 * @param int $product_id Product ID.
	 * @return string|null ArticleNumber or null.
	 */
	public static function get_last_sync_sku( int $product_id ): string|null {
		$last_sync_response = self::get_last_sync_response( $product_id );
		if ( null === $last_sync_response ) {
			return null;
		}

		$response_data = json_decode( $last_sync_response, true );
		if ( json_last_error() !== JSON_ERROR_NONE ) {
			return null;
		}

		if (
			isset( $response_data['list'][0]['ArticleNumber'] ) &&
			is_string( $response_data['list'][0]['ArticleNumber'] )
		) {
			return $response_data['list'][0]['ArticleNumber'];
		}

		return null;
	}

	/**
	 * Get hash meta value.
	 *
	 * @param int $product_id Product ID.
	 * @return string|null Hash value or null.
	 */
	public static function get_hash( int $product_id ): ?string {
		return self::get_meta( $product_id, self::META_KEY_HASH );
	}

	/**
	 * Update hash meta value.
	 *
	 * @param int    $product_id Product ID.
	 * @param string $hash Hash value.
	 */
	public static function update_hash( int $product_id, string $hash ): void {
		self::update_meta( $product_id, self::META_KEY_HASH, $hash );
	}

	/**
	 * Get private sync status meta value.
	 *
	 * @param int $product_id Product ID.
	 * @return string Private sync status or null.
	 */
	public static function get_sync_status_private( int $product_id ): string {
		return self::get_meta( $product_id, self::META_KEY_SYNC_STATUS_PRIVATE ) ?? 'ERROR';
	}

	/**
	 * Update private sync status meta value.
	 *
	 * @param int    $product_id Product ID.
	 * @param string $status Private sync status.
	 */
	public static function update_sync_status_private( int $product_id, string $status ): void {
		self::update_meta( $product_id, self::META_KEY_SYNC_STATUS_PRIVATE, $status );
	}

	/**
	 * Get sync error meta value.
	 *
	 * @param int $product_id Product ID.
	 * @return string|null Sync error or null.
	 */
	public static function get_sync_error( int $product_id ): ?string {
		return self::get_meta( $product_id, self::META_KEY_SYNC_ERROR );
	}

	/**
	 * Update sync error meta value.
	 *
	 * @param int    $product_id Product ID.
	 * @param string $error Sync error message.
	 */
	public static function update_sync_error( int $product_id, string $error ): void {
		self::update_meta( $product_id, self::META_KEY_SYNC_ERROR, $error );
	}

	/**
	 * Get last sync timestamp meta value.
	 *
	 * @param int $product_id Product ID.
	 * @return string|null Last sync timestamp or null.
	 */
	public static function get_sync_last( int $product_id ): ?string {
		return self::get_meta( $product_id, self::META_KEY_SYNC_LAST );
	}

	/**
	 * Update last sync timestamp meta value.
	 *
	 * @param int    $product_id Product ID.
	 * @param string $timestamp Last sync timestamp.
	 */
	public static function update_sync_last( int $product_id, string $timestamp ): void {
		self::update_meta( $product_id, self::META_KEY_SYNC_LAST, $timestamp );
	}
}
