<?php
/**
 * Admin utilities.
 *
 * @link  https://personalizewp.com
 * @since 2.0.0
 *
 * @package PersonalizeWP
 * @subpackage PersonalizeWP/Admin
 */

namespace PersonalizeWP\Admin;

defined( 'ABSPATH' ) || exit; // Exit if accessed directly.

/**
 * Admin utilities.
 *
 * Functions that don't have a better location
 */
class Utils {

	/**
	 * Store the used icons to output in the footer
	 *
	 * @var array
	 */
	public static $track_used_icons = [];

	/**
	 * Echos the contents of an SVG for use inline.
	 *
	 * @since 2.0.0
	 *
	 * @param  string $name The SVG Name.
	 * @return void
	 */
	public static function svg_icon( $name = '' ) {
		$icon = self::get_svg_icon( $name );
		if ( ! empty( $icon ) ) {
			// Very limited svg reference, so can sanitize.
			echo wp_kses(
				$icon,
				array(
					'svg' => array(
						'width'  => true,
						'height' => true,
					),
					'use' => array(
						'xlink:href' => true,
					),
				)
			);
		}
	}

	/**
	 * Returns the contents of an SVG for use inline.
	 *
	 * @since 2.0.0
	 *
	 * @param  string $name The SVG Name.
	 * @return string
	 */
	public static function get_svg_icon( $name = '' ) {
		// Nothing to return.
		if ( empty( $name ) ) {
			return '';
		}
		// Unknown svg, just return
		if ( isset( self::$track_used_icons[ $name ] ) && empty( self::$track_used_icons[ $name ]['icon'] ) ) {
			return '';
		}
		// Check for pre-process
		if ( empty( self::$track_used_icons[ $name ]['icon'] ) ) {
			$svg      = '';
			$svg_file = __DIR__ . '/img/' . esc_attr( $name ) . '.svg';

			// Check and suppress PHP errors for non-existent file.
			if ( ! file_exists( $svg_file ) ) {
				// Suppress further checks on non-existant icon.
				self::$track_used_icons[ $name ] = '';
				return '';
			}

			$contents = file_get_contents( $svg_file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- Reason: local file
			// Remove XML as unnessary when embedding in HTML.
			$contents = str_replace( '<?xml version="1.0" encoding="UTF-8"?>', '', $contents );

			$tags = new \WP_HTML_Tag_Processor( $contents );
			$tags->next_tag( 'svg' );
			$svg = array(
				'icon'   => $contents,
				'width'  => $tags->get_attribute( 'width' ),
				'height' => $tags->get_attribute( 'height' ),
			);
			// Store for all future uses.
			self::$track_used_icons[ $name ] = $svg;
		}

		// For now just return a SVG reference
		return sprintf(
			'<svg width="%2$s" height="%3$s"><use xlink:href="#pwp-icon-%1$s" /></svg>',
			esc_attr( sanitize_key( $name ) ),
			esc_attr( self::$track_used_icons[ $name ]['width'] ),
			esc_attr( self::$track_used_icons[ $name ]['height'] )
		);
	}

	/**
	 * Outputs the inline SVGs that have been used.
	 *
	 * @since 2.0.0
	 *
	 * @return void
	 */
	public static function output_inline_svgs() {
		if ( empty( self::$track_used_icons ) ) {
			return;
		}

		$inline_svgs = [];
		foreach ( self::$track_used_icons as $icon_name => $icon_data ) {
			if ( empty( $icon_data['icon'] ) ) {
				continue;
			}
			$symbol = $icon_data['icon'];

			// Symbols don't have height/width, so remove them.
			$symbol = str_replace(
				array(
					'<svg ',
					'</svg>',
					sprintf(
						' height="%1$s"',
						$icon_data['height']
					),
					sprintf(
						' width="%1$s"',
						$icon_data['width']
					),
				),
				array(
					sprintf(
						'<symbol id="pwp-icon-%1$s" ',
						esc_attr( sanitize_key( $icon_name ) )
					),
					'</symbol>',
					'',
					'',
				),
				$symbol
			);

			$inline_svgs[] = $symbol;
		}

		if ( empty( $inline_svgs ) ) {
			return;
		}

		// Output the HTML
		printf(
			'<!-- PersonalizeWP Icons --><svg xmlns="http://www.w3.org/2000/svg" style="display: none;">%1$s</svg>',
			implode( '', $inline_svgs ) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Reason: own svgs and no built in sanitising for svgs
		);
	}

	/**
	 * Returns the title of a form, given an ID, and the plugin type.
	 *
	 * Wrapper for all supported Form plugins.
	 *
	 * @since 3.2.0
	 *
	 * @param int    $id     Form ID
	 * @param string $plugin Plugin type
	 *
	 * @return string Form title, or empty if unknown
	 */
	public static function get_form_title( $id, $plugin ) {

		$title = __( 'Form: \'unknown\'', 'personalizewp' );
		switch ( $plugin ) {
			// Based on the unchanging plugin slugs
			case 'gravityforms':
				if ( class_exists( '\GFAPI' ) ) {
					$gf_form = \GFAPI::get_form( $id );
					if ( ! empty( $gf_form['title'] ) ) {
						$title = sprintf(
							/* translators: 1: %s form name. */
							__( 'Gravity Form: %s', 'personalizewp' ),
							$gf_form['title']
						);
					}
				} else {
					$title = sprintf(
						/* translators: 1: %d form ID. */
						__( 'Gravity Form: %d', 'personalizewp' ),
						$id
					);
				}
				break;
			case 'ninjaforms':
				if ( class_exists( '\Ninja_Forms' ) ) {
					$nf_form = \Ninja_Forms()->form( $id )->get();
					if ( ! empty( $nf_form ) ) {
						$nf_title = $nf_form->get_setting( 'title' );
						if ( ! empty( $nf_title ) ) {
							$title = sprintf(
								/* translators: 1: %s form name. */
								__( 'Ninja Form: %s', 'personalizewp' ),
								$nf_title
							);
						}
					}
				} else {
					$title = sprintf(
						/* translators: 1: %d form ID. */
						__( 'Ninja Form: %d', 'personalizewp' ),
						$id
					);
				}
				break;
			case 'wsform':
				if ( class_exists( '\WS_Form' ) ) {
					$wsf_title = wsf_form_get_label_by_id( $id );
					if ( ! empty( $wsf_title ) ) {
						$title = sprintf(
							/* translators: 1: %s form name. */
							__( 'WS Form: %s', 'personalizewp' ),
							$wsf_title
						);
					}
				} else {
					$title = sprintf(
						/* translators: 1: %u form ID. */
						__( 'WS Form: %u', 'personalizewp' ),
						$id
					);
				}
				break;
		}

		return $title;
	}

	/**
	 * Returns the edit link for a form, given an ID, and the plugin type.
	 *
	 * Wrapper for all supported Form plugins.
	 *
	 * @since 3.2.0
	 *
	 * @param int    $id     Form ID
	 * @param string $plugin Plugin type
	 *
	 * @return string The edit form link for the given form. Null if the form type does not exist
	 *                     or does not allow an editing UI.
	 */
	public static function get_edit_form_link( $id, $plugin ) {

		$link = null;
		switch ( $plugin ) {
			// Based on the unchanging plugin slugs
			case 'gravityforms':
				$link = add_query_arg(
					array(
						'page' => 'gf_edit_forms',
						'id'   => $id,
					),
					'admin.php'
				);

				break;
			case 'ninjaforms':
				$link = add_query_arg(
					array(
						'page'    => 'ninja-forms',
						'form_id' => $id,
					),
					'admin.php'
				);
				break;
			case 'wsform':
				$link = add_query_arg(
					array(
						'page' => 'ws-form-edit',
						'id'   => $id,
					),
					'admin.php'
				);
				break;
		}

		return $link;
	}

	/**
	 * Returns the title of a Product or Product Category, given an ID, and the type.
	 *
	 * Wrapper for all supported Product plugins, e.g. WooCommerce.
	 *
	 * @since 3.2.0
	 *
	 * @param int    $id     Item ID
	 * @param string $type   Item type, e.g. product, product_cat
	 * @param string $plugin Plugin slug
	 *
	 * @return string Item title, or empty if unknown
	 */
	public static function get_product_title( $id, $type, $plugin ) {

		$title = '';
		switch ( $plugin ) {
			// Based on the unchanging plugin slugs
			case 'woocommerce':
				switch ( $type ) {
					case 'product':
						$_title = get_the_title( (int) $id );
						// Check if the product is still available.
						if ( is_wp_error( $_title ) ) {
							$title = __( 'Product: \'unknown\'', 'personalizewp' );
						} else {
							$title = sprintf(
								/* translators: 1: %s Product title */
								__( 'Prod: %s', 'personalizewp' ),
								$_title
							);
							$title = $_title;
						}
						break;

					case 'product_cat':
					case 'product_tag':
						$_title = get_term_field( 'name', (int) $id );
						// Check if the term is still available.
						if ( is_wp_error( $_title ) ) {
							$title = __( 'Category: \'unknown\'', 'personalizewp' );
						} else {
							$title = sprintf(
								/* translators: 1: %s Product category. */
								__( 'Cat: %s', 'personalizewp' ),
								$_title
							);
							$title = $_title;
						}
						break;
				} // END WooCommerce
				break;
		}

		return $title;
	}
}
