<?php
/**
 * PromoTimeWidgetRepository class.
 *
 * Provides access to PromoTimeWidget CPT instances.
 *
 * @package Ilabs\Firevert\Modules\PromoTimeWidget\Services\Repository
 */

declare( strict_types=1 );

namespace Ilabs\Firevert\Modules\PromoTimeWidget\Services\Repository;

use Ilabs\Firevert\Core\Repository\Cache\CacheRepository;
use Ilabs\Firevert\Core\Repository\AbstractWidgetRepository;
use Ilabs\Firevert\Modules\PromoTimeWidget\Services\Type\ModuleType;
use Ilabs\Firevert\Modules\PromoTimeWidget\Services\Form\ProductsFormHandler;
use WP_Post;
use Ilabs\Firevert\Modules\PromoTimeWidget\Services\Form\AppearanceFormHandler;
use Ilabs\Firevert\Modules\PromoTimeWidget\Services\Form\SettingsFormHandler;

/**
 * Class PromoTimeWidgetRepository
 */
final class PromoTimeWidgetRepository extends AbstractWidgetRepository {

	/**
	 * Cache group identifier for PromoTimeWidget data.
	 *
	 * Used to bulk-invalidate widget caches when widget settings are updated.
	 *
	 * @var string
	 */
	public const PROMO_TIME_WIDGET_CACHE_GROUP = ModuleType::MODULE_SLUG;

	/**
	 * Cache repository instance.
	 *
	 * @var CacheRepository
	 */
	private CacheRepository $cache;

	/**
	 * Constructor.
	 *
	 * @param CacheRepository $cache The cache repository.
	 */
	public function __construct( CacheRepository $cache ) {
		$this->cache = $cache;
	}

	/**
	 * Returns the custom post type used by the widget.
	 *
	 * This defines the post_type for queries and creation.
	 *
	 * @return string Widget custom post type name.
	 */
	protected function get_post_type(): string {
		return ModuleType::MODULE_CPT;
	}

	/**
	 * Returns the default post title used when creating the widget.
	 *
	 * Used when no PromoTimeWidget instance exists.
	 *
	 * @return string Default title for the widget post.
	 */
	protected function get_default_post_title(): string {
		return 'Main Promo Time Widget';
	}

	/**
	 * Returns all widget settings and appearance data.
	 *
	 * @param WP_Post     $post PromoTimeWidget CPT post.
	 * @param string|null $lang Passed lang value ('pl', 'en', 'fr' format).
	 *
	 * @return array<string, mixed> Widget data array.
	 */
	public function get_widget_data( WP_Post $post, ?string $lang = null ): array {
		$cache_key   = "promo_time_widget_data_{$post->ID}" . ( $lang ? "_{$lang}" : '' );
		$cached_data = $this->cache->get( $cache_key );
		if ( false !== $cached_data ) {
			return $cached_data;
		}

		$settings   = new SettingsFormHandler( $post );
		$appearance = new AppearanceFormHandler( $post );
		$products   = new ProductsFormHandler( $post );

		$settings_data   = $this->extract_fields( $post, $settings, $lang );
		$appearance_data = $this->extract_fields( $post, $appearance, $lang );
		$products_data   = $this->extract_fields( $post, $products, $lang );

		$image_id = (int) ( $appearance_data['firevert_promo_time_widget_image'] ?? 0 );

		$appearance_data['firevert_promo_time_widget_image_id']  = $image_id;
		$appearance_data['firevert_promo_time_widget_image_url'] = $image_id
			? wp_get_attachment_image_url( $image_id, 'medium' )
			: '';

		$widget_data = array_merge(
			$settings_data,
			$appearance_data,
			$products_data
		);

		$this->cache->set( $cache_key, $widget_data, HOUR_IN_SECONDS, self::PROMO_TIME_WIDGET_CACHE_GROUP );

		return $widget_data;
	}

	/**
	 * Returns the display position setting for the main widget.
	 *
	 * @return string|null
	 */
	public function get_display_position(): ?string {
		$post = $this->get_or_create_main();

		$cache_key = "promo_time_widget_position_{$post->ID}";

		$cached_value = $this->cache->get( $cache_key );
		if ( false !== $cached_value ) {
			return $cached_value;
		}

		$value = get_post_meta( $post->ID, 'firevert_promo_time_widget_display_position', true );

		$result = is_string( $value ) && '' !== $value ? $value : null;

		$this->cache->set( $cache_key, $result, HOUR_IN_SECONDS, self::PROMO_TIME_WIDGET_CACHE_GROUP );

		return $result;
	}
}
