<?php
/**
 * Sanitization and validation helper functions.
 *
 * @package Awesomemotive\Rewardswp\Helpers
 * @since 1.0.0
 */

namespace Awesomemotive\Rewardswp\Helpers;

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

/**
 * Return the sanitized float value.
 *
 * @since 1.0.0
 *
 * @param $amount mixed The amount to be sanitized.
 *
 * @return float The sanitized float number.
 */
function sanitize_float( $amount ): float {
	return (float) filter_var( $amount, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION );
}

/**
 * Sanitizes an array of values to ensure they are integers.
 *
 * Applies absint to all values of the array to sanitize them as integers.
 *
 * @since 1.0.0
 *
 * @param array $array The array of values to sanitize.
 *
 * @return array The sanitized array containing only integers.
 */
function sanitize_array_to_int( array $array ): array {
	return array_filter( array_map( 'absint', $array ) );
}

/**
 * Return the kses for svgs.
 *
 * @since 1.0.0
 *
 * @return array The SVG kses available.
 */
function svg_kses(): array {
	return [
		'svg'      => [
			'viewbox'         => true,
			'class'           => true,
			'x-bind:class'    => true,
			'x-show'          => true,
			'x-cloak'         => true,
			'stroke'          => true,
			'stroke-width'    => true,
			'style'           => true,
			'height'          => true,
			'width'           => true,
			'd'               => true,
			'xmlns'           => true,
			'fill'            => true,
			'fill-rule'       => true,
			'stroke-linecap'  => true,
			'stroke-linejoin' => true,
		],
		'path'     => [
			'class'             => true,
			'stroke'            => true,
			'stroke-width'      => true,
			'stroke-linecap'    => true,
			'stroke-linejoin'   => true,
			'stroke-miterlimit' => true,
			'd'                 => true,
			'fill'              => true,
			'fill-rule'         => true,
			'style'             => true,
			'opacity'           => true,
		],
		'g'        => [
			'clip-path'         => true,
			'stroke-width'      => true,
			'transform'         => true,
			'fill'              => true,
			'stroke'            => true,
			'stroke-linecap'    => true,
			'stroke-linejoin'   => true,
			'stroke-miterlimit' => true,
		],
		'defs'     => [],
		'desc'     => [],
		'clippath' => [
			'id' => true,
		],
		'rect'     => [
			'x'            => true,
			'y'            => true,
			'width'        => true,
			'height'       => true,
			'rx'           => true,
			'ry'           => true,
			'fill'         => true,
			'opacity'      => true,
			'transform'    => true,
			'stroke-width' => true,
		],
		'style'    => true,
		'circle'   => [
			'class'        => true,
			'cx'           => true,
			'cy'           => true,
			'r'            => true,
			'opacity'      => true,
			'transform'    => true,
			'fill'         => true,
			'stroke'       => true,
			'stroke-width' => true,
		],
		'ellipse'  => [
			'cx'      => true,
			'cy'      => true,
			'rx'      => true,
			'ry'      => true,
			'fill'    => true,
			'opacity' => true,
		],
		'lineargradient' => [
			'id'            => true,
			'x1'            => true,
			'y1'            => true,
			'x2'            => true,
			'y2'            => true,
			'gradientunits' => true,
		],
		'stop'     => [
			'offset'       => true,
			'stop-color'   => true,
			'stop-opacity' => true,
		],
	];
}

/**
 * Return the kses for RewardsWP with Alpine.js support.
 *
 * @since 1.0.0
 *
 * @param array $additional_kses Any additional kses to allowlist.
 *
 * @return array The kses available.
 */
function kses( array $additional_kses = [] ): array {
	$common_attributes = [
		'x-data'                           => true,
		'x-init'                           => true,
		'x-ref'                            => true,
		'x-model'                          => true,
		'x-modelable'                      => true,
		'x-html'                           => true,
		'x-text'                           => true,
		'x-show'                           => [],
		'x-collapse'                       => true,
		'x-transition'                     => true,
		'x-if'                             => [],
		'x-for'                            => true,
		'x-cloak'                          => true,
		'x-bind'                           => true,
		'x-bind:id'                        => true,
		'x-bind:href'                      => true,
		'x-bind:class'                     => true,
		'x-bind:name'                      => true,
		'x-bind:value'                     => true,
		'x-bind:placeholder'               => true,
		'x-bind:key'                       => true,
		'x-bind:for'                       => true,
		'x-bind:hidden'                    => true,
		'x-bind:disabled'                  => true,
		'x-bind:aria-checked'              => true,
		'x-bind:aria-label'                => true,
		'x-bind:aria-expanded'             => true,
		'x-bind:style'                     => true,
		'x-bind:title'                     => true,
		'x-bind:href'                      => true,
		'x-bind:src'                       => true,
		'x-on:click'                       => true,
		'x-on:input'                       => true,
		'x-on:input.debounce.200ms'        => true,
		'x-on:change'                      => true,
		'x-on:focus'                       => true,
		'x-on:blur'                        => true,
		'x-on:mouseleave'                  => true,
		'x-on:mouseenter'                  => true,
		'x-on:click.prevent'               => true,
		'x-on:click.self'                  => true,
		'x-on:click.outside'               => true,
		'x-on:click.stop'                  => true,
		'x-on:submit'                      => true,
		'x-on:submit.prevent'              => true,
		'x-on:update-panel.window'         => true,
		'x-on:show-launcher.window'        => true,
		'x-on:toggle-rewards-panel.window' => true,
		'x-on:toggle-widget.window'        => true,
		'x-on:close-member-modal.window'   => true,
		'x-on:open-add-member-modal.window' => true,
		'x-on:show-activity.window'        => true,
		'x-on:keydown.escape.window'       => true,
		'x-on:keydown.arrow-down.prevent'  => true,
		'x-on:keydown.arrow-up.prevent'    => true,
		'x-on:keydown.enter.prevent'       => true,
		'x-on:keydown.space.prevent'       => true,
		'x-on:resize.window'               => true,
		'x-on:scroll'                      => true,
		'x-sort'                           => true,
		'x-sort.ghost'                     => true,
		'x-sort:item'                      => true,
		'x-sort:handle'                    => [
			'valueless' => 'y',
		],
		'x-sort:ignore'                    => [
			'valueless' => 'y',
		],
		'x-sort:config'                    => true,
		'x-transition:enter'               => true,
		'x-transition:enter-start'         => true,
		'x-transition:enter-end'           => true,
		'x-transition:leave'               => true,
		'x-transition:leave-start'         => true,
		'x-transition:leave-end'           => true,
		'class'                            => true,
		'x-on:license-updated.window'      => true,
		'x-model.number'                   => true,
		'data-highlight'                   => true,
		'data-id'                          => true,
		'data-tippy-content'               => true,
		'data-tippy-initialized'           => true,
		'data-coloris'                     => true,
		'style'                            => true,
		'id'                               => true,
		'role'                             => true,
		'aria-label'                       => true,
		'aria-labelledby'                  => true,
		'aria-describedby'                 => true,
		'inputmode'                        => true,
		'pattern'                          => true,
	];

	$default_kses = [
		'address'    => [],
		'a'          => [
			'href'     => true,
			'class'    => true,
			'rel'      => true,
			'rev'      => true,
			'name'     => true,
			'target'   => true,
			'download' => [
				'valueless' => 'y',
			],
		],
		'abbr'       => [],
		'acronym'    => [],
		'area'       => [
			'alt'    => true,
			'coords' => true,
			'href'   => true,
			'nohref' => true,
			'shape'  => true,
			'target' => true,
		],
		'article'    => [
			'align' => true,
		],
		'aside'      => [
			'align' => true,
		],
		'audio'      => [
			'autoplay' => true,
			'controls' => true,
			'loop'     => true,
			'muted'    => true,
			'preload'  => true,
			'src'      => true,
		],
		'b'          => [],
		'bdo'        => [],
		'big'        => [],
		'blockquote' => [
			'cite' => true,
		],
		'br'         => [],
		'button'     => [
			'disabled'   => true,
			'name'       => true,
			'type'       => true,
			'value'      => true,
			'aria-label' => true,
		],
		'caption'    => [
			'align' => true,
		],
		'cite'       => [],
		'code'       => [],
		'col'        => [
			'align'   => true,
			'char'    => true,
			'charoff' => true,
			'span'    => true,
			'valign'  => true,
			'width'   => true,
		],
		'colgroup'   => [
			'align'   => true,
			'char'    => true,
			'charoff' => true,
			'span'    => true,
			'valign'  => true,
			'width'   => true,
		],
		'del'        => [
			'datetime' => true,
		],
		'dd'         => [],
		'dfn'        => [],
		'details'    => [
			'align' => true,
			'open'  => true,
		],
		'div'        => [
			'align' => true,
		],
		'dl'         => [],
		'dt'         => [],
		'em'         => [],
		'fieldset'   => [],
		'figure'     => [
			'align' => true,
		],
		'figcaption' => [
			'align' => true,
		],
		'font'       => [
			'color' => true,
			'face'  => true,
			'size'  => true,
		],
		'footer'     => [
			'align' => true,
		],
		'form'       => [
			'id'     => true,
			'class'  => true,
			'action' => true,
			'method' => true,
		],
		'h1'         => [
			'align' => true,
		],
		'h2'         => [
			'align' => true,
		],
		'h3'         => [
			'align' => true,
		],
		'h4'         => [
			'align' => true,
		],
		'h5'         => [
			'align' => true,
		],
		'h6'         => [
			'align' => true,
		],
		'header'     => [
			'align' => true,
		],
		'hgroup'     => [
			'align' => true,
		],
		'hr'         => [
			'align'   => true,
			'noshade' => true,
			'size'    => true,
			'width'   => true,
		],
		'i'          => [],
		'img'        => [
			'alt'      => true,
			'align'    => true,
			'border'   => true,
			'height'   => true,
			'hspace'   => true,
			'loading'  => true,
			'longdesc' => true,
			'vspace'   => true,
			'src'      => true,
			'usemap'   => true,
			'width'    => true,
		],
		'ins'        => [
			'datetime' => true,
			'cite'     => true,
		],
		'input'      => [
			'name'             => true,
			'type'             => true,
			'id'               => true,
			'min'              => true,
			'max'              => true,
			'class'            => true,
			'value'            => true,
			'placeholder'      => true,
			'aria-describedby' => true,
			'readonly'         => true,
			'required'         => true,
			'aria-label'       => true,
			'checked'          => true,
			'disabled'         => true,
		],
		'kbd'        => [],
		'label'      => [
			'for' => true,
		],
		'legend'     => [
			'align' => true,
		],
		'li'         => [
			'align' => true,
			'value' => true,
			'class' => true,
		],
		'main'       => [
			'align' => true,
		],
		'map'        => [
			'name' => true,
		],
		'mark'       => [],
		'menu'       => [
			'type' => true,
		],
		'nav'        => [
			'align' => true,
		],
		'object'     => [
			'data' => [
				'required'       => true,
				'value_callback' => '_wp_kses_allow_pdf_objects',
			],
			'type' => [
				'required' => true,
				'values'   => [ 'application/pdf' ],
			],
		],
		'p'          => [
			'align' => true,
		],
		'pre'        => [
			'width' => true,
		],
		'q'          => [
			'cite' => true,
		],
		'rb'         => [],
		'rp'         => [],
		'rt'         => [],
		'rtc'        => [],
		'ruby'       => [],
		's'          => [],
		'samp'       => [],
		'span'       => [
			'align' => true,
			'class' => true,
		],
		'section'    => [
			'align' => true,
		],
		'select'     => [
			'name'  => true,
			'id'    => true,
			'class' => true,
			'value' => true,
		],
		'option'     => [
			'name'     => true,
			'id'       => true,
			'class'    => true,
			'value'    => true,
			'selected' => true,
		],
		'small'      => [],
		'strike'     => [],
		'strong'     => [],
		'style'      => [
			'type' => true,
		],
		'sub'        => [],
		'summary'    => [
			'align' => true,
		],
		'sup'        => [],
		'table'      => [
			'align'       => true,
			'bgcolor'     => true,
			'border'      => true,
			'cellpadding' => true,
			'cellspacing' => true,
			'rules'       => true,
			'summary'     => true,
			'width'       => true,
		],
		'tbody'      => [
			'align'   => true,
			'char'    => true,
			'charoff' => true,
			'valign'  => true,
		],
		'td'         => [
			'abbr'    => true,
			'align'   => true,
			'axis'    => true,
			'bgcolor' => true,
			'char'    => true,
			'charoff' => true,
			'colspan' => true,
			'headers' => true,
			'height'  => true,
			'nowrap'  => true,
			'rowspan' => true,
			'scope'   => true,
			'valign'  => true,
			'width'   => true,
		],
		'template'   => $common_attributes,
		'textarea'   => [
			'cols'     => true,
			'rows'     => true,
			'disabled' => true,
			'name'     => true,
			'readonly' => true,
		],
		'tfoot'      => [
			'align'   => true,
			'char'    => true,
			'charoff' => true,
			'valign'  => true,
		],
		'th'         => [
			'abbr'    => true,
			'align'   => true,
			'axis'    => true,
			'bgcolor' => true,
			'char'    => true,
			'charoff' => true,
			'colspan' => true,
			'headers' => true,
			'height'  => true,
			'nowrap'  => true,
			'rowspan' => true,
			'scope'   => true,
			'valign'  => true,
			'width'   => true,
		],
		'thead'      => [
			'align'   => true,
			'char'    => true,
			'charoff' => true,
			'valign'  => true,
		],
		'title'      => [],
		'tr'         => [
			'align'   => true,
			'bgcolor' => true,
			'char'    => true,
			'charoff' => true,
			'valign'  => true,
		],
		'ul'         => [
			'type'  => true,
			'class' => true,
		],
		'ol'         => [
			'start'    => true,
			'type'     => true,
			'reversed' => true,
		],
	];

	$default_kses = array_merge( $default_kses, svg_kses() );

	foreach ( $default_kses as $tag => &$attributes ) {
		if ( ! is_array( $attributes ) ) {
			continue;
		}
		$attributes = array_merge( $attributes, $common_attributes );
	}

	return apply_filters(
		'rewardswp_kses',
		array_merge_recursive(
			$default_kses,
			$additional_kses
		)
	);
}

/**
 * Return the kses for email content that allows CSS styles.
 *
 * @since 1.1.0
 *
 * @return array The kses available for email content.
 */
function email_kses(): array {
	$email_kses = kses();

	// Allow style tag with CSS content
	$email_kses['style'] = [
		'type' => true,
	];

	// Allow inline styles on common elements
	$common_style_attributes = [
		'style' => true,
	];

	foreach ( $email_kses as $tag => &$attributes ) {
		if ( is_array( $attributes ) ) {
			$attributes = array_merge( $attributes, $common_style_attributes );
		}
	}

	return $email_kses;
}
