<?php
/**
 * Design service implementation.
 *
 * @package PDFDraft
 */

namespace PDFDraft\Services;

use PDFDraft\Contracts\Repositories\DesignRepositoryInterface;
use PDFDraft\Contracts\Cache\CacheInterface;
use PDFDraft\Contracts\Log\LoggerInterface;
use PDFDraft\Contracts\Services\DesignServiceInterface;

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

/**
 * Service for managing design data with caching.
 */
class DesignService implements DesignServiceInterface {

	/**
	 * Default cache TTL in seconds.
	 *
	 * @var int
	 */
	private const DEFAULT_CACHE_TTL = 3600;

	/**
	 * Design repository instance.
	 *
	 * @var DesignRepositoryInterface
	 */
	private DesignRepositoryInterface $repository;

	/**
	 * Cache instance.
	 *
	 * @var CacheInterface
	 */
	private CacheInterface $cache;

	/**
	 * Logger instance.
	 *
	 * @var LoggerInterface
	 */
	private LoggerInterface $logger;

	/**
	 * Constructor.
	 *
	 * @param DesignRepositoryInterface $repository Design repository.
	 * @param CacheInterface            $cache      Cache implementation.
	 * @param LoggerInterface           $logger     Logger implementation.
	 */
	public function __construct(
		DesignRepositoryInterface $repository,
		CacheInterface $cache,
		LoggerInterface $logger
	) {
		$this->repository = $repository;
		$this->cache      = $cache;
		$this->logger     = $logger;
	}

	/**
	 * Get cache TTL in seconds.
	 *
	 * @return int Cache TTL in seconds.
	 */
	private function getCacheTtl(): int {
		/**
		 * Filter the cache TTL for design data.
		 *
		 * @param int $ttl Cache TTL in seconds. Default: 3600 (1 hour).
		 */
		return (int) apply_filters( 'pdfdraft:design:cache:ttl', self::DEFAULT_CACHE_TTL ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores -- backwards compatibility
	}

	/**
	 * Get design by ID.
	 *
	 * @param int $design_id Design ID to look up.
	 * @return array|null Design data or null if not found.
	 */
	public function getById( int $design_id ): ?array {
		$cacheKey = "design:{$design_id}";
		$cached   = $this->cache->get( $cacheKey );

		if ( $cached ) {
			$this->logger->debug( 'Design retrieved from cache', array( 'id' => $design_id ) );
			return $cached;
		}

		$this->logger->info( 'Fetching design', array( 'id' => $design_id ) );

		$design = $this->repository->findById( $design_id );

		if ( ! $design ) {
			$this->logger->warning( 'Design not found', array( 'id' => $design_id ) );
			return null;
		}

		$this->cache->set( $cacheKey, $design, $this->getCacheTtl() );

		return $design;
	}

	/**
	 * Get design by slug.
	 *
	 * @param string $slug Design slug to look up.
	 * @return array|null Design data or null if not found.
	 */
	public function getBySlug( string $slug ): ?array {
		$cacheKey = "design:slug:{$slug}";
		$cached   = $this->cache->get( $cacheKey );

		if ( $cached ) {
			$this->logger->debug( 'Design retrieved from cache', array( 'slug' => $slug ) );
			return $cached;
		}

		$this->logger->info( 'Fetching design by slug', array( 'slug' => $slug ) );

		$design = $this->repository->findBySlug( $slug );

		if ( ! $design ) {
			$this->logger->warning( 'Design not found', array( 'slug' => $slug ) );
			return null;
		}

		$this->cache->set( $cacheKey, $design, $this->getCacheTtl() );

		return $design;
	}
}
