<?php
/**
 * Display context for one card render.
 *
 * @package Kutby
 * @since   2.9.0
 */

declare(strict_types=1);

namespace Kutby\Cards\Support;

use WP_Post;

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

/**
 * Class CardContext
 */
final class CardContext {

	/**
	 * @param WP_Post              $post Post.
	 * @param array<string, mixed> $args Display args.
	 */
	private function __construct(
		private readonly WP_Post $post,
		private readonly array $args
	) {}

	/**
	 * @param WP_Post|int          $post Post or ID.
	 * @param array<string, mixed> $args Args.
	 * @return self|null
	 */
	public static function from_post( WP_Post|int $post, array $args = array() ): ?self {
		if ( is_int( $post ) ) {
			$loaded = get_post( $post );
			if ( ! $loaded instanceof WP_Post ) {
				return null;
			}
			$post = $loaded;
		}

		$defaults = array(
			'show_category'     => true,
			'show_meta'         => true,
			'show_author'       => true,
			'show_date'         => true,
			'show_excerpt'      => true,
			'show_read_more'    => true,
			'show_reading_time' => false,
			'show_bookmark'     => false,
			'ratio'             => '16x9',
			'heading'           => 'h3',
			'lazy'              => true,
			'class'             => '',
			'excerpt_words'     => 22,
		);

		return new self( $post, array_merge( $defaults, $args ) );
	}

	/**
	 * @return WP_Post
	 */
	public function post(): WP_Post {
		return $this->post;
	}

	/**
	 * @param string $key     Key.
	 * @param mixed  $default Default.
	 * @return mixed
	 */
	public function get( string $key, mixed $default = null ): mixed {
		return $this->args[ $key ] ?? $default;
	}

	/**
	 * @param string $key Key.
	 * @return bool
	 */
	public function bool( string $key ): bool {
		return ! empty( $this->args[ $key ] );
	}

	/**
	 * @param string $key     Key.
	 * @param string $default Default.
	 * @return string
	 */
	public function string( string $key, string $default = '' ): string {
		return (string) ( $this->args[ $key ] ?? $default );
	}

	/**
	 * Image ratio token suffix.
	 *
	 * @return string
	 */
	public function ratio(): string {
		$ratio = $this->string( 'ratio', '16x9' );
		return in_array( $ratio, array( '16x9', '4x3', '1x1', 'auto' ), true ) ? $ratio : '16x9';
	}

	/**
	 * Heading tag.
	 *
	 * @return string
	 */
	public function heading_tag(): string {
		$tag = strtolower( $this->string( 'heading', 'h3' ) );
		return in_array( $tag, array( 'h2', 'h3', 'h4' ), true ) ? $tag : 'h3';
	}

	/**
	 * Extra BEM / utility classes.
	 *
	 * @return string
	 */
	public function extra_class(): string {
		return trim( $this->string( 'class' ) );
	}
}
