<?php
declare( strict_types=1 );

namespace FiboFilters\Shortcodes;

use FiboFilters\Filtering\Front;
use FiboFilters\Util\FilterUtil;
use FiboFilters\Util\TemplateUtil;

/**
 * FiboFilters class
 */
class FiboFilters {
	/** @var Front */
	protected $front;

	/** @var string Shortcode tag. */
	private $tag = 'fibofilters';

	public function __construct( Front $front ) {
		$this->front = $front;
	}

	public function init(): void {
		add_shortcode( $this->tag, [ $this, 'render' ] );
	}

	/**
	 * Render a FiboFilters shortcode.
	 *
	 * @param mixed  $atts List of user attributes.
	 * @param string $content User content. We don't use it.
	 * @param string $tag Shortcode tag.
	 */
	public function render( $atts, string $content, string $tag ): string {
		$min_screen = 0;
		$max_screen = 0;

		$shortcode_atts = shortcode_atts(
			[
				'layout'      => 'vertical',
				'min_screen'  => $min_screen,
				'max_screen'  => $max_screen,
				'all_screens' => '',
				'classname'   => '',
				'include'     => '',
				'exclude'     => '',
			],
			$atts,
			$tag
		);

		$layout_whitelist = [ 'vertical', 'horizontal', 'mobile' ];

		// Validate layout attribute.
		if ( ! in_array( $shortcode_atts['layout'], $layout_whitelist, true ) ) {
			$shortcode_atts['layout'] = $layout_whitelist[0];
		}

		if ( $shortcode_atts['all_screens'] === '1' ) {
			$shortcode_atts['min_screen'] = 1;
			$shortcode_atts['max_screen'] = 99999;
		}

		$min_max_screen            = $this->front->get_breakpoints( $shortcode_atts['layout'] );
		[$min_screen, $max_screen] = array_map(
			function ( string $key ) use ( $shortcode_atts, $min_max_screen ): int {
				$val = $shortcode_atts[ $key ] ?? null;

				if ( ! empty( $val ) && is_numeric( $val ) ) {
					return max( absint( $val ), 1 );
				}

				return max( absint( $min_max_screen[ $key ] ), 1 );
			},
			[ 'min_screen', 'max_screen' ]
		);

		$skeleton_html = TemplateUtil::render_skeleton(
			$shortcode_atts['layout'],
			$min_screen,
			$max_screen
		);

		// Classname.
		$classname = 'fibofilters-' . $shortcode_atts['layout'] . '-filters-container';
		if ( ! empty( trim( $shortcode_atts['classname'] ) ) ) {
			$classnames = explode( ' ', $shortcode_atts['classname'] );
			$classnames = array_map( 'sanitize_html_class', $classnames );
			$classname .= ' ' . implode( ' ', $classnames );
		}

		// Data attributes.
		$data  = sprintf( ' data-min-screen="%d"', $min_screen );
		$data .= sprintf( ' data-max-screen="%d"', $max_screen );

		if ( ! empty( trim( $shortcode_atts['include'] ) ) ) {
			$included = explode( ',', $shortcode_atts['include'] );
			$included = array_map( [ FilterUtil::class, 'sanitize_value' ], $included );
			$data    .= ' data-include="' . esc_attr( implode( ',', $included ) ) . '"';
		} elseif ( ! empty( trim( $shortcode_atts['exclude'] ) ) ) {
			$excluded = explode( ',', $shortcode_atts['exclude'] );
			$excluded = array_map( [ FilterUtil::class, 'sanitize_value' ], $excluded );
			$data    .= ' data-exclude="' . esc_attr( implode( ',', $excluded ) ) . '"';
		}

		return '<div class="' . $classname . '"' . $data . '>' . $skeleton_html . '</div>';
	}
}
