<?php

namespace TotalThemeCore\WPBakery\Params;

defined( 'ABSPATH' ) || exit;

/**
 * WPBakery Param => Select.
 */
final class Select {

	/**
	 * Returns true or false if the current select value exists as an option.
	 */
	protected static $value_exists;

	/**
	 * Renders the custom param field.
	 */
	public static function output( $settings = [], $value = '' ) {
		self::$value_exists = false; // must reset every time
		$param_name         = $settings['param_name'];
		$type               = $settings['choices'] ?? $param_name ?? []; // get the select choice type
		$value              = self::parse_value( $value, $type ); // !! must go before TotalThemeCore\Vcex\Setting_Choices !!
		$refresh_choices    = ! empty( $settings['refresh_choices'] ) || in_array( $type, [ 'template', 'card_style' ], true );

		if ( ( '' === $value || null === $value ) && isset( $settings['std'] ) ) {
			$value = $settings['std'];
		}

		if ( ! empty( $settings['choices_callback'] ) ) {
			$choices = is_callable( $settings['choices_callback'] ) ? call_user_func( $settings['choices_callback'] ) : [];
		} elseif ( class_exists( 'TotalThemeCore\Vcex\Setting_Choices' ) ) {
			$choices = (new \TotalThemeCore\Vcex\Setting_Choices( $type, $settings ))->get_choices();
		}

		// If we don't have any choices return a text field with the value
		// This is important to prevent issues where the choices is empty but we had a value saved.
		if ( empty( $choices ) ) {
			return '<input name="' . esc_attr( $param_name ) . '" class="' . esc_attr( "wpb_vc_param_value wpb-textinput {$param_name} {$settings['type']}" ) . '" type="text" value="' . esc_attr( $value ) . '">';
		}

		$select_class = "wpb_vc_param_value wpb-input wpb-select {$param_name} {$settings['type']}";

		if ( 'card_style' === $type || ( isset( $settings['chosen_select'] ) && true === $settings['chosen_select'] ) ) {
			$select_class .= ' vcex-chosen';
		}

		// Render select field
		$select = '<select name="' . esc_attr( $param_name ) . '" class="' . esc_attr( $select_class ) .'">';
			$options_out = self::render_options( $choices, $value );
			// If value isn't part of the choices we add it anyway to the select so it can be saved
			if ( $value && ! self::$value_exists ) {
				$option_name = $value;
				if ( 'template' === $type ) {
					$option_name = get_the_title( $value ) ?: $value;
				}
				$options_out = '<option value="' . esc_attr( $value )  . '" ' . selected( $value, $value, false ) . '>' . esc_html__( $option_name ) . '</option>' . $options_out;
			}
		$select .= $options_out;
		$select .= '</select>';

		if ( $refresh_choices ) {
			$output = '<div class="vcex-param-w-button">' . $select . '<button type="button" class="vcex-refresh-choices" aria-label="' . esc_attr__( 'Refresh Choices', 'total-theme-core' ) . '" title="' . esc_attr__( 'Refresh Choices', 'total-theme-core' ) . '" data-vcex-refresh-choices="' . esc_attr( $type ) . '" data-vcex-nonce="' . wp_create_nonce( 'vcex_params_ajax' ) . '"><svg class="vcex-param-toggle-icon" height="18" width="18" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M10.25 1.02c5.1 0 8.75 4.04 8.75 9s-3.65 9-8.75 9c-3.2 0-6.02-1.59-7.68-3.99l2.59-1.52c1.1 1.5 2.86 2.51 4.84 2.51 3.3 0 6-2.79 6-6s-2.7-6-6-6c-1.97 0-3.72 1-4.82 2.49L7 8.02l-6 2v-7L2.89 4.6c1.69-2.17 4.36-3.58 7.36-3.58z"/></g></svg></button></div>';
		} else {
			$output = $select;
		}

		// Show a create template/card link
		if ( in_array( $type, [ 'acf_repeater_templates', 'template', 'card_style' ], true ) ) {
			$template_post_type = 'card_style' === $type ? 'wpex_card' : 'wpex_templates';
			if ( current_user_can( "publish_{$template_post_type}" ) && post_type_exists( $template_post_type ) ) { 
				$new_template_text = 'card_style' === $type
					/* translators: link to create new card, close link */
					? esc_html__( '%sCreate new custom card%s', 'total' )
					/* translators: link to create new template, close link */
					: esc_html__( '%sCreate new template%s', 'total' );
				$new_template_url_params = [
					'post_type'          => $template_post_type,
					'wpb-backend-editor' => 1,
				];
				if ( 'wpex_templates' == $template_post_type ) {
					if ( 'modal_template' === $param_name ) {
						$new_template_url_params['wpex_template_type'] = 'modal';
					} else {
						$new_template_url_params['wpex_template_type'] = 'acf_repeater_templates' === $type ? 'acf_repeater' : 'part';
					}
				}
				$description = sprintf(
					$new_template_text,
					'<a class="vcex-create-template-link" href="' . esc_url( add_query_arg( $new_template_url_params, admin_url( 'post-new.php' ) ) ) . '" target="_blank" rel="noopener noreferrer">',
					'</a>',
				);
			}
		}

		// Display notice
		if ( ! empty( $settings['notice'] ) ) {
			$description = $settings['notice'];
		}

		// Display inline description
		if ( ! empty( $description ) ) {
			$allowed_html = [
				'span' => [
					'class' => [],
				],
				'a' => [
					'href' => [],
					'rel' => [],
					'target' => [],
					'data-vcex-refresh-choices' => [],
					'data-vcex-nonce' => [],
					'class' => [],
				],
			];
			$output .= '<div class="vc_description vcex-param-description">' . wp_kses( $description, $allowed_html ) . '</div>';
		}

		// Return param HTML
		return $output;
	}

	/**
	 * Render select options.
	 */
	protected static function render_options( $choices = [], $selected = '' ): string {
		$html = '';
		foreach ( $choices as $choice_k => $choice_v ) {
			if ( is_array( $choice_v ) ) {
				$sub_choices = $choice_v['choices'] ?? $choice_v['options'] ?? [];
				if ( $sub_choices ) {
					$html .= '<optgroup label="' . esc_attr( $choice_v['label'] ?? '' ) . '">';
						$html .= self::render_options( $sub_choices, $selected );
					$html .= '</optgroup>';
				}
			} else {
				// @note we use a loose check to support numbers
				if ( $selected && ! self::$value_exists && $choice_k == $selected ) {
					self::$value_exists = true;
				}
				$html .= '<option value="' . esc_attr( $choice_k )  . '" ' . selected( $selected, $choice_k, false ) . '>' . esc_attr( $choice_v ) . '</option>';
			}
		}
		return $html;
	}

	/**
	 * Parses the field value.
	 */
	protected static function parse_value( $value, $choices ) {
		if ( $value ) {
			switch ( $choices ) {
				case 'visibility':
					$value = str_replace( '-portrait', '', $value );
					$value = str_replace( '-landscape', '', $value );
					break;
				case 'font_weight':
					if ( function_exists( 'vcex_parse_font_weight' ) ) {
						$value = vcex_parse_font_weight( $value );
					}
					break;
			}
		}
		return $value;
	}

}
