<?php
/**
 * Settings_Helper
 */

namespace Ilabs\Inpost_International\Settings;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
} // Exit if accessed directly.

use Ilabs\Inpost_International\API\API;

/**
 * Settings_Helper
 */
class Settings_Helper {

	/**
	 * Auth options setting name
	 */
	const MAIN_OPTIONS = 'inpost_international_settings_auth';
	/**
	 * Api token expiration setting name
	 */
	const TOKEN_EXPIRATION = 'api_token_expiration';
	/**
	 * Refresh token expiration setting name
	 */
	const REFRESH_TOKEN_EXPIRATION = 'api_refresh_token_expiration';
	/**
	 * Refresh token setting name
	 */
	const REFRESH_TOKEN = 'api_refresh_token';
	/**
	 * Api token setting name
	 */
	const API_TOKEN = 'api_token';


	/**
	 * Allowed HTML tags and attributes for wp_kses().
	 */
	const ALLOWED_HTML = array(
		'strong'   => array(),
		'b'        => array(),
		'i'        => array(),
		'code'     => array(),
		'ul'       => array(
			'class' => true,
		),
		'ol'       => array(),
		'li'       => array(),
		'br'       => array(
			'class' => true,
		),
		'fields'   => array(),
		'fieldset' => array(),
		'label'    => array(
			'for' => true,
		),
		'select'   => array(
			'class'            => true,
			'name'             => true,
			'id'               => true,
			'disabled'         => true,
			'style'            => true,
			'data-placeholder' => true,
		),
		'option'   => array(
			'value'    => true,
			'selected' => true,
		),
		'div'      => array(
			'id'     => true,
			'style'  => true,
			'class'  => true,
			'data-w' => true,
		),
		'a'        => array(
			'id'            => true,
			'class'         => true,
			'href'          => true,
			'style'         => true,
			'title'         => true,
			'onclick'       => true,
			'target'        => true,
			'data-tab'      => true,
			'data-tab-slug' => true,
		),
		'img'      => array(
			'src'    => true,
			'width'  => true,
			'height' => true,
			'id'     => true,
			'class'  => true,
			'alt'    => true,
		),
		'p'        => array(
			'class' => true,
		),
		'h1'       => array(
			'class' => true,
		),
		'h2'       => array(
			'class' => true,
		),
		'nav'      => array(
			'class'      => true,
			'aria-label' => true,
		),
		'span'     => array(
			'class' => true,
			'style' => true,
			'id'    => true,
		),
		'table'    => array(
			'class' => true,
			'id'    => true,
		),
		'thead'    => array(
			'class' => true,
		),
		'tbody'    => array(
			'class' => true,
		),
		'tr'       => array(
			'class'      => true,
			'data-index' => true,
			'id'         => true,
		),
		'th'       => array(
			'class' => true,
		),
		'td'       => array(
			'class' => true,
			'id'    => true,
		),
		'textarea' => array(
			'name'     => true,
			'class'    => true,
			'id'       => true,
			'rows'     => true,
			'cols'     => true,
			'disabled' => true,
			'style'    => true,
		),
		'input'    => array(
			'id'               => true,
			'class'            => true,
			'type'             => true,
			'name'             => true,
			'value'            => true,
			'placeholder'      => true,
			'checked'          => true,
			'readonly'         => true,
			'disabled'         => true,
			'data-id'          => true,
			'style'            => true,
			'step'             => true,
			'min'              => true,
			'max'              => true,
			'data-placeholder' => true,
		),
		'script'   => array(
			'src'   => true,
			'async' => true,
		),
		'style'    => array(),
		'hr'       => array(),
		'button'   => array(
			'id'    => true,
			'class' => true,
		),

	);

	/**
	 * Allowed HTML tags and attributes for wp_kses().
	 */
	const ALLOWED_HTML_CUSTOM_TABLES = array(
        'div' => array(
            'class' => true,
            'id' => true,
            'style' => true,
            'data-wp-lists' => true,
            'data-product-id' => true,
            'aria-describedby' => true,
            'aria-hidden' => true,
        ),
        'h1' => array(
            'class' => true,
            'id' => true,
        ),
        'input' => array(
            'type' => true,
            'id' => true,
            'name' => true,
            'value' => true,
            'class' => true,
            'checked' => true,
            'data-id' => true,
            'data-method' => true,
            'data-product-id' => true,
            'size' => true,
            'aria-describedby' => true,
            'aria-hidden' => true,
            'style' => true,
            'placeholder' => true,
            'min' => true,
            'max' => true,
            'step' => true,
            'disabled' => true,
            'readonly' => true,
        ),
        'img' => array(
            'style' => true,
            'id' => true,
            'src' => true,
            'alt' => true,
            'class' => true,
            'data-id' => true,
            'width' => true,
            'height' => true,
        ),
        'p' => array(
            'class' => true,
            'id' => true,
            'style' => true,
        ),
        'label' => array(
            'class' => true,
            'for' => true,
            'style' => true,
            'id' => true,
        ),
        'span' => array(
            'class' => true,
            'title' => true,
            'aria-hidden' => true,
            'id' => true,
            'style' => true,
            'data-action-id' => true,
            'data-id' => true,
            'aria-describedby' => true,
            'data-method' => true,
        ),
        'select' => array(
            'style' => true,
            'id' => true,
            'name' => true,
            'class' => true,
            'multiple' => true,
            'disabled' => true,
            'required' => true,
            'data-placeholder' => true,
        ),
        'option' => array(
            'value' => true,
            'selected' => true,
            'class' => true,
            'disabled' => true,
            'data-id' => true,
            'data-postal-code' => true,
        ),
        'ul' => array(
            'class' => true,
            'data-product-id' => true,
            'id' => true,
            'style' => true,
        ),
        'li' => array(
            'class' => true,
            'id' => true,
            'style' => true,
        ),
        'br' => array(
            'class' => true,
            'clear' => true,
        ),
        'table' => array(
            'class' => true,
            'id' => true,
            'style' => true,
        ),
        'thead' => array(
            'class' => true,
            'id' => true,
            'style' => true,
        ),
        'tbody' => array(
            'id' => true,
            'data-wp-lists' => true,
            'class' => true,
            'style' => true,
        ),
        'tfoot' => array(
            'class' => true,
            'id' => true,
            'style' => true,
        ),
        'tr' => array(
            'class' => true,
            'id' => true,
            'style' => true,
        ),
        'th' => array(
            'id' => true,
            'scope' => true,
            'class' => true,
            'style' => true,
            'colspan' => true,
            'rowspan' => true,
        ),
        'td' => array(
            'id' => true,
            'class' => true,
            'data-colname' => true,
            'style' => true,
            'colspan' => true,
            'rowspan' => true,
        ),
        'a' => array(
            'href' => true,
            'class' => true,
            'aria-hidden' => true,
            'aria-describedby' => true,
            'id' => true,
            'style' => true,
            'title' => true,
            'target' => true,
            'rel' => true,
        ),
        'button' => array(
            'type' => true,
            'class' => true,
            'data-product-id' => true,
            'id' => true,
            'style' => true,
            'disabled' => true,
            'data-id' => true,
            'data-method' => true,
        ),
        // Form elements
        'form' => array(
            'action' => true,
            'method' => true,
            'id' => true,
            'class' => true,
            'style' => true,
            'enctype' => true,
        ),
        'fieldset' => array(
            'id' => true,
            'class' => true,
            'style' => true,
        ),
        'legend' => array(
            'id' => true,
            'class' => true,
            'style' => true,
        ),
        'textarea' => array(
            'id' => true,
            'name' => true,
            'class' => true,
            'style' => true,
            'rows' => true,
            'cols' => true,
            'placeholder' => true,
            'disabled' => true,
            'readonly' => true,
        ),
        // Additional elements
        'strong' => array(),
        'em' => array(),
        'b' => array(),
        'i' => array(),
        'hr' => array(
            'class' => true,
            'id' => true,
            'style' => true,
        ),
        'small' => array(
            'class' => true,
            'id' => true,
            'style' => true,
        ),
        // All data-* attributes
        'data-*' => true,
    );

	/**
	 * Sections array.
	 *
	 * @var   array
	 * @since 1.0.0
	 */
	private $sections_array = array();

	/**
	 * Fields array.
	 *
	 * @var   array
	 * @since 1.0.0
	 */
	private $fields_array = array();

	/**
	 * Constructor.
	 *
	 * @since  1.0.0
	 */
	public function __construct() {
		// Enqueue the admin scripts.
		add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) );

		add_action( 'admin_init', array( $this, 'admin_init' ) );

		// Menu.
		add_action( 'admin_menu', array( $this, 'admin_menu' ) );
	}

	/**
	 * Admin Scripts.
	 *
	 * @since 1.0.0
	 */
	public function admin_scripts() {
		// jQuery is needed.
		wp_enqueue_script( 'jquery' );

		// Color Picker.
		wp_enqueue_script(
			'iris',
			admin_url( 'js/iris.min.js' ),
			array( 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch' ),
            INPOST_INTL_PLUGIN_VERSION,
			1
		);

		// Media Uploader.
		wp_enqueue_media();
	}

	/**
	 * Set Sections.
	 *
	 * @param array $sections Section List.
	 *
	 * @since 1.0.0
	 */
	public function set_sections( $sections ) {

		if ( ! is_array( $sections ) ) {
			return false;
		}

		// Assign to the sections array.
		$this->sections_array = $sections;

		return $this;
	}

	/**
	 * Add a single section.
	 *
	 * @param array $section Section array.
	 *
	 * @since 1.0.0
	 */
	public function add_section( $section ) {

		if ( ! is_array( $section ) ) {
			return false;
		}

		// Assign the section to sections array.
		$this->sections_array[] = $section;

		return $this;
	}

	/**
	 * Set Fields.
	 *
	 * @param array $fields Fields array.
	 *
	 * @since 1.0.0
	 */
	public function set_fields( $fields ) {

		if ( ! is_array( $fields ) ) {
			return false;
		}

		// Assign the fields.
		$this->fields_array = $fields;

		return $this;
	}

	/**
	 * Add a single field.
	 *
	 * @param string $section     Section ID.
	 * @param array  $field_array Field array.
	 *
	 * @return Settings_Helper
	 * @since 1.0.0
	 */
	public function add_field( $section, $field_array ) {
		// Set the defaults.
		$defaults = array(
			'id'   => '',
			'name' => '',
			'desc' => '',
			'type' => 'text',
		);

		// Combine the defaults with user's arguments.
		$arg = wp_parse_args( $field_array, $defaults );

		// Each field is an array named against its section.
		$this->fields_array[ $section ][] = $arg;

		return $this;
	}

	/**
	 * Initialize API.
	 *
	 * Initializes and registers the settings sections and fields.
	 * Usually this should be called at `admin_init` hook.
	 *
	 * @since  1.0.0
	 */
	public function admin_init() {
		/**
		 * Register the sections.
		 *
		 * Sections array is like this:
		 *
		 * $sections_array = array (
		 *   $section_array,
		 *   $section_array,
		 *   $section_array,
		 * );
		 *
		 * Section array is like this:
		 *
		 * $section_array = array (
		 *   'id'    => 'section_id',
		 *   'title' => 'Section Title'
		 * );
		 *
		 * @since 1.0.0
		 */
		foreach ( $this->sections_array as $section ) {
			if ( false === get_option( $section['id'] ) ) {
				// Add a new field as section ID.
				add_option( $section['id'] );
			}

			// Deals with sections description.
			if ( isset( $section['desc'] ) && ! empty( $section['desc'] ) ) {
				// Build HTML.
				$section['desc'] = '<div class="inside">' . $section['desc'] . '</div>';

				// Create the callback for description.
				$callback = function () use ( $section ) {
					echo wp_kses_post( str_replace( '"', '\"', $section['desc'] ) );
				};

			} elseif ( isset( $section['callback'] ) ) {
				$callback = $section['callback'];
			} else {
				$callback = null;
			}

			/**
			 * Add a new section to a settings page.
			 *
			 * @param string $id
			 * @param string $title
			 * @param callable $callback
			 * @param string $page | Page is same as section ID.
			 *
			 * @since 1.0.0
			 */
			add_settings_section( $section['id'], $section['title'], $callback, $section['id'] );
		}

		/**
		 * Register settings fields.
		 *
		 * Fields array is like this:
		 *
		 * $fields_array = array (
		 *   $section => $field_array,
		 *   $section => $field_array,
		 *   $section => $field_array,
		 * );
		 *
		 *
		 * Field array is like this:
		 *
		 * $field_array = array (
		 *   'id'   => 'id',
		 *   'name' => 'Name',
		 *   'type' => 'text',
		 * );
		 *
		 * @since 1.0.0
		 */
		foreach ( $this->fields_array as $section => $field_array ) {
			foreach ( $field_array as $field ) {
				// ID.
				$id = isset( $field['id'] ) ? $field['id'] : false;

				// Type.
				$type = isset( $field['type'] ) ? $field['type'] : 'text';

				// Name.
				$name = isset( $field['name'] ) ? $field['name'] : 'No Name Added';

				// Label for.
				$label_for = "{$section}[{$field['id']}]";

				// Description.
				$description = isset( $field['desc'] ) ? $field['desc'] : '';

				// Size.
				$size = isset( $field['size'] ) ? $field['size'] : null;

				// Options.
				$options = isset( $field['options'] ) ? $field['options'] : '';

				// Standard default value.
				$default = isset( $field['default'] ) ? $field['default'] : '';

				// Standard default placeholder.
				$placeholder = isset( $field['placeholder'] ) ? $field['placeholder'] : '';

				$disabled = isset( $field['disabled'] ) && 1 === $field['disabled'] ? true : false;

				// Sanitize Callback.
				$sanitize_callback = isset( $field['sanitize_callback'] ) ? $field['sanitize_callback'] : '';

				$args = array(
					'id'                => $id,
					'type'              => $type,
					'name'              => $name,
					'label_for'         => $label_for,
					'desc'              => $description,
					'section'           => $section,
					'size'              => $size,
					'options'           => $options,
					'std'               => $default,
					'placeholder'       => $placeholder,
					'disabled'          => $disabled,
					'sanitize_callback' => $sanitize_callback,
				);

				/**
				 * Add a new field to a section of a settings page.
				 *
				 * @param string $id
				 * @param string $title
				 * @param callable $callback
				 * @param string $page
				 * @param string $section = 'default'
				 * @param array $args = array()
				 *
				 * @since 1.0.0
				 */

				// @param string     $id
				$field_id = $section . '[' . $field['id'] . ']';

				add_settings_field(
					$field_id,
					$name,
					array( $this, 'callback_' . $type ),
					$section,
					$section,
					$args
				);
			}
		}

		// Creates our settings in the fields table.
		foreach ( $this->sections_array as $section ) {
			/**
			 * Registers a setting and its sanitization callback.
			 *
			 * @param string $field_group | A settings group name.
			 * @param string $field_name | The name of an option to sanitize and save.
			 * @param callable $sanitize_callback = ''
			 *
			 * @since 1.0.0
			 */
			$args = array( $this, 'sanitize_fields' );
			register_setting( $section['id'], $section['id'], $args );
		}
	}

	/**
	 * Sanitize callback for Settings API fields.
	 *
	 * @param array $fields Fields array.
	 *
	 * @return mixed
	 * @since 1.0.0
	 */
	public function sanitize_fields( $fields ) {
		foreach ( $fields as $field_slug => $field_value ) {
			$sanitize_callback = $this->get_sanitize_callback( $field_slug );

			// If callback is set, call it.
			if ( $sanitize_callback ) {
				$fields[ $field_slug ] = call_user_func( $sanitize_callback, $field_value );
				continue;
			}
		}

		return $fields;
	}

	/**
	 * Get sanitization callback for given option slug
	 *
	 * @param string $slug option slug.
	 *
	 * @return mixed string | bool false
	 * @since  1.0.0
	 */
	public function get_sanitize_callback( $slug = '' ) {
		if ( empty( $slug ) ) {
			return false;
		}

		// Iterate over registered fields and see if we can find proper callback.
		foreach ( $this->fields_array as $section => $field_array ) {
			foreach ( $field_array as $field ) {
				if ( $field['name'] !== $slug ) {
					continue;
				}

				// Return the callback name.
				return isset( $field['sanitize_callback'] ) && is_callable( $field['sanitize_callback'] ) ? $field['sanitize_callback'] : false;
			}
		}

		return false;
	}

	/**
	 * Get field description for display
	 *
	 * @param array $args Settings field args.
	 */
	public function get_field_description( $args ) {
		if ( ! empty( $args['desc'] ) ) {
			$desc = sprintf(
				'<p class="description">%s</p>',
				is_callable( $args['desc'] )
					? call_user_func( $args['desc'] )
					: $args['desc']
			);
		} else {
			$desc = '';
		}

		return $desc;
	}

	/**
	 * Displays a title field for a settings field
	 *
	 * @param array $args Settings field args.
	 */
	public function callback_title( $args ): void {
		echo '';
	}

	/**
	 * Displays a text field for a settings field
	 *
	 * @param array $args Settings field args.
	 */
	public function callback_text( $args ) {

		$value    = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'], $args['placeholder'] ) );
		$size     = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';
		$type     = isset( $args['type'] ) ? $args['type'] : 'text';
		$disabled = ! empty( $args['disabled'] ) ? 'disabled' : '';

		$html  = sprintf( '<input type="%1$s" class="%2$s-text" id="%3$s[%4$s]" name="%3$s[%4$s]" value="%5$s" placeholder="%6$s" %7$s />', $type, $size, $args['section'], $args['id'], $value, $args['placeholder'], $disabled );
		$html .= $this->get_field_description( $args );

		echo wp_kses( $html, self::ALLOWED_HTML );
	}


	/**
	 * Displays a text field for a settings field
	 *
	 * @param array $args Settings field args.
	 */
	public function callback_email_input( $args ) {

		$value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'], $args['placeholder'] ) );
		$size  = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';
		$type  = 'email';

		$html  = sprintf( '<input type="%1$s" class="%2$s-text" id="%3$s[%4$s]" name="%3$s[%4$s]" value="%5$s" placeholder="%6$s"/>', $type, $size, $args['section'], $args['id'], $value, $args['placeholder'] );
		$html .= $this->get_field_description( $args );

		echo wp_kses( $html, self::ALLOWED_HTML );
	}


	/**
	 * Displays an url field for a settings field
	 *
	 * @param array $args Settings field args.
	 */
	public function callback_url( $args ) {
		$this->callback_text( $args );
	}

	/**
	 * Displays a number field for a settings field
	 *
	 * @param array $args Settings field args.
	 */
	public function callback_number( $args ) {
		$this->callback_text( $args );
	}

	/**
	 * Displays a checkbox for a settings field
	 *
	 * @param array $args Settings field args.
	 */
	public function callback_checkbox( $args ) {

		$value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );

		$html  = '<fieldset>';
		$html .= sprintf( '<label for="inpost_intl-%1$s[%2$s]">', $args['section'], $args['id'] );
		$html .= sprintf( '<input type="hidden" name="%1$s[%2$s]" value="off" />', $args['section'], $args['id'] );
		$html .= sprintf( '<input type="checkbox" class="checkbox" id="inpost_intl-%1$s[%2$s]" name="%1$s[%2$s]" value="on" %3$s />', $args['section'], $args['id'], checked( $value, 'on', false ) );
		$html .= sprintf( '%1$s</label>', $args['desc'] );
		$html .= '</fieldset>';

		echo wp_kses( $html, self::ALLOWED_HTML );
	}




	/**
	 * Displays a multi-checkbox settings field
	 *
	 * @param array $args Settings field args.
	 */
	public function callback_multicheck( $args ) {

		$value = $this->get_option( $args['id'], $args['section'], $args['std'] );

		$html = '<fieldset>';
		foreach ( $args['options'] as $key => $label ) {
			$checked = isset( $value[ $key ] ) ? $value[ $key ] : '0';
			$html   .= sprintf( '<label for="inpost_intl-%1$s[%2$s][%3$s]">', $args['section'], $args['id'], $key );
			$html   .= sprintf( '<input type="checkbox" class="checkbox" id="inpost_intl-%1$s[%2$s][%3$s]" name="%1$s[%2$s][%3$s]" value="%3$s" %4$s />', $args['section'], $args['id'], $key, checked( $checked, $key, false ) );
			$html   .= sprintf( '%1$s</label><br>', $label );
		}
		$html .= $this->get_field_description( $args );
		$html .= '</fieldset>';

		echo wp_kses( $html, self::ALLOWED_HTML );
	}

	/**
	 * Displays a radio settings field
	 *
	 * @param array $args Settings field args.
	 */
	public function callback_radio( $args ) {

		$value = $this->get_option( $args['id'], $args['section'], $args['std'] );

		$html = '<fieldset>';
		foreach ( $args['options'] as $key => $label ) {
			$html .= sprintf( '<label for="inpost_intl-%1$s[%2$s][%3$s]">', $args['section'], $args['id'], $key );
			$html .= sprintf( '<input type="radio" class="radio" id="inpost_intl-%1$s[%2$s][%3$s]" name="%1$s[%2$s]" value="%3$s" %4$s />', $args['section'], $args['id'], $key, checked( $value, $key, false ) );
			$html .= sprintf( '%1$s</label><br>', $label );
		}
		$html .= $this->get_field_description( $args );
		$html .= '</fieldset>';

		echo wp_kses( $html, self::ALLOWED_HTML );
	}

	/**
	 * Displays a select for settings field
	 *
	 * @param array $args Settings field args.
	 */
	public function callback_select( $args ) {

		$value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
		$size  = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';

		$disabled = ! empty( $args['disabled'] ) ? 'disabled' : '';

		$html = sprintf( '<select class="%1$s" name="%2$s[%3$s]" id="%2$s[%3$s]" %4$s>', $size, $args['section'], $args['id'], $disabled );
		foreach ( $args['options'] as $key => $label ) {
			$html .= sprintf( '<option value="%s" %s>%s</option>', $key, selected( $value, $key, false ), $label );
		}
		$html .= '</select>';
		$html .= $this->get_field_description( $args );

		echo wp_kses( $html, self::ALLOWED_HTML );
	}

	/**
	 * Displays a textarea for settings field
	 *
	 * @param array $args Settings field args.
	 */
	public function callback_textarea( $args ) {

		$value = esc_textarea( $this->get_option( $args['id'], $args['section'], $args['std'] ) );

		$size     = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';
		$disabled = ! empty( $args['disabled'] ) ? 'disabled' : '';

		$html  = sprintf( '<textarea rows="5" cols="55" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s]" %4$s >%5$s</textarea>', $size, $args['section'], $args['id'], $disabled, $value );
		$html .= $this->get_field_description( $args );

		echo wp_kses( $html, self::ALLOWED_HTML );
	}

	/**
	 * Displays html for settings field
	 *
	 * @param array $args Settings field args.
	 *
	 * @return void
	 */
	public function callback_html( $args ) {
		echo wp_kses( $this->get_field_description( $args ), self::ALLOWED_HTML );
	}

	/**
	 * Displays a rich text textarea for settings field
	 *
	 * @param array $args Settings field args.
	 */
	public function callback_wysiwyg( $args ) {

		$value = $this->get_option( $args['id'], $args['section'], $args['std'] );
		$size  = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : '500px';

		echo '<div style="max-width: ' . esc_attr( $size ) . ';">';

		$editor_settings = array(
			'teeny'         => true,
			'textarea_name' => $args['section'] . '[' . $args['id'] . ']',
			'textarea_rows' => 10,
		);
		if ( isset( $args['options'] ) && is_array( $args['options'] ) ) {
			$editor_settings = array_merge( $editor_settings, $args['options'] );
		}

		wp_editor( $value, $args['section'] . '-' . $args['id'], $editor_settings );

		echo '</div>';

		echo wp_kses( $this->get_field_description( $args ), self::ALLOWED_HTML );
	}

	/**
	 * Displays a file upload field for settings field
	 *
	 * @param array $args Settings field args.
	 */
	public function callback_file( $args ) {

		$value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
		$size  = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';
		$id    = $args['section'] . '[' . $args['id'] . ']';
		$label = $args['options']['button_label'] ?? esc_html__( 'Choose File', 'inpost-international' );

		$html  = sprintf( '<input type="text" class="%1$s-text inpost_intl_customsett-url" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s"/>', $size, $args['section'], $args['id'], $value );
		$html .= '<input type="button" class="button inpost_intl_customsett-browse" value="' . $label . '" />';
		$html .= $this->get_field_description( $args );

		echo wp_kses( $html, self::ALLOWED_HTML );
	}

	/**
	 * Displays an image upload field with a preview
	 *
	 * @param array $args Settings field args.
	 */
	public function callback_image( $args ) {

		$value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
		$size  = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';
		$id    = $args['section'] . '[' . $args['id'] . ']';
		$label = $args['options']['button_label'] ?? esc_html__( 'Choose Image', 'inpost-international' );

		$html  = sprintf( '<input type="text" class="%1$s-text inpost_intl_customsett-url" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s"/>', $size, $args['section'], $args['id'], $value );
		$html .= '<input type="button" class="button inpost_intl_customsett-browse" value="' . $label . '" />';
		$html .= $this->get_field_description( $args );
		$html .= '<p class="inpost_intl_customsett-image-preview"><img alt="" src=""/></p>';

		echo wp_kses( $html, self::ALLOWED_HTML );
	}

	/**
	 * Displays a password field for a settings field
	 *
	 * @param array $args Settings field args.
	 */
	public function callback_password( $args ) {

		$value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
		$size  = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';

		$html  = sprintf( '<input type="password" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s"/>', $size, $args['section'], $args['id'], $value );
		$html .= $this->get_field_description( $args );

		echo wp_kses( $html, self::ALLOWED_HTML );
	}

	/**
	 * Displays a color picker field for a settings field
	 *
	 * @param array $args Settings field args.
	 */
	public function callback_color( $args ) {

		$value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'], $args['placeholder'] ) );
		$size  = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';

		$html  = sprintf( '<input type="text" class="%1$s-text color-picker" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s" data-default-color="%5$s" placeholder="%6$s" />', $size, $args['section'], $args['id'], $value, $args['std'], $args['placeholder'] );
		$html .= $this->get_field_description( $args );

		echo wp_kses( $html, self::ALLOWED_HTML );
	}

	/**
	 * Displays a separator field for a settings field
	 *
	 * @param array $args Settings field args.
	 */
	public function callback_separator( $args ) {
		$type = isset( $args['type'] ) ? $args['type'] : 'separator';

		$html  = '';
		$html .= '<div class="inpost_intl_customsett-settings-separator"></div>';

		echo wp_kses( $html, self::ALLOWED_HTML );
	}

	/**
	 * Get the value of a settings field
	 *
	 * @param string $option settings field name.
	 * @param string $section the section name this field belongs to.
	 * @param string $default default text if it's not found.
	 *
	 * @return string
	 */
	public function get_option( $option, $section, $default = '' ): string {

		if ( 'inpost_international_settings_geowidget' === $section ) {
			$maybe_prod_geowidget_key = get_option( 'easypack_geowidget_production_token' );
			$maybe_test_geowidget_key = get_option( 'easypack_geowidget_sandbox_token' );
			if ( 'geowidget_production_token' === $option && ! empty( $maybe_prod_geowidget_key ) ) {
				$default = $maybe_prod_geowidget_key;
			} elseif ( 'geowidget_sandbox_token' === $option && ! empty( $maybe_test_geowidget_key ) ) {
				$default = $maybe_test_geowidget_key;
			}
		}

		if ( 'inpost_international_settings_webhook' === $section ) {
			if ( 'webhook_url' === $option ) {
				$default = home_url() . '/wp-json/inpost_webhook/v1/order/update';
			} elseif ( 'webhook_sandbox_rsa' === $option ) {
				$default = 'test key .....';
			} elseif ( 'webhook_production_rsa' === $option ) {
				$default = 'prod key .....';
			}
		}

		$options = get_option( $section );

		if ( isset( $options[ $option ] ) ) {
			return $options[ $option ];
		}

		return $default;
	}

	/**
	 * Add submenu page to the Settings main menu.
	 *
	 * @return void
	 */
	public function admin_menu() {

		global $menu;
		$menu_pos = 55;
		while ( isset( $menu[ $menu_pos ] ) ) {
			++$menu_pos;
		}

		$capability = 'view_woocommerce_reports';

		$icon_svg = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgd2lkdGg9IjI0Ni45OTk5OTk5OTk5OTk5NyIgaGVpZ2h0PSIyMjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiA8Zz4KICA8dGl0bGU+TGF5ZXIgMTwvdGl0bGU+CiAgPGcgaWQ9InN2Z18xIiBzdHJva2U9Im51bGwiPgogICA8cGF0aCBpZD0ic3ZnXzciIGQ9Im0xMDEuNTYxMDQsMTEwLjY3NDkyYzAsMCAtMTEuNjQ2MzcsNC41MDMxIC0yNi4wMTU5LDQuNTAzMWMtMTQuMzY4MTQsMCAtMjYuMDE1OSwtNC41MDMxIC0yNi4wMTU5LC00LjUwMzFzMTEuNjQ3NzUsLTQuNTAwMzMgMjYuMDE1OSwtNC41MDAzM2MxNC4zNjk1MywwIDI2LjAxNTksNC41MDAzMyAyNi4wMTU5LDQuNTAwMzMiIGZpbGw9IiNGRkNDMDAiIHN0cm9rZT0ibnVsbCIvPgogICA8cGF0aCBpZD0ic3ZnXzgiIGQ9Im0xMzcuNTM0NjUsNDQuNDYwM2MwLDAgLTEwLjMyMDA2LC02Ljk0OTY1IC0xOC4zNTM5OSwtMTguNjI3ODNjLTguMDMzOTQsLTExLjY3NjggLTEwLjc0MDUsLTIzLjY1OTI0IC0xMC43NDA1LC0yMy42NTkyNHMxMC4zMTg2OCw2Ljk0ODI3IDE4LjM1Mzk5LDE4LjYyNTA3YzguMDMzOTQsMTEuNjc5NTYgMTAuNzQwNSwyMy42NjIwMSAxMC43NDA1LDIzLjY2MjAxIiBmaWxsPSIjRkZDQzAwIiBzdHJva2U9Im51bGwiLz4KICAgPHBhdGggaWQ9InN2Z185IiBkPSJtMTExLjE4NjgzLDczLjAzMjAxYzAsMCAtMTIuNDM4ODQsLTEuMzg1NzggLTI1LjEyNTI0LC03Ljk5OTM2Yy0xMi42ODY0LC02LjYxMjIgLTIwLjgxNDM4LC0xNS45NDc1NSAtMjAuODE0MzgsLTE1Ljk0NzU1czEyLjQzODg0LDEuMzg1NzggMjUuMTI1MjQsNy45OTkzNmMxMi42ODY0LDYuNjEyMiAyMC44MTQzOCwxNS45NDc1NSAyMC44MTQzOCwxNS45NDc1NSIgZmlsbD0iI0ZGQ0MwMCIgc3Ryb2tlPSJudWxsIi8+CiAgIDxwYXRoIGlkPSJzdmdfMTAiIGQ9Im0xMzUuNzU4ODYsMTMwLjc2ODc1YzcuNTI5MTMsLTIuMjg0NzQgMTMuOTA0ODMsLTUuNjE5MTkgMTMuOTA0ODMsLTUuNjE5MTlzLTE3LjczNTc5LC00LjkzMDQ1IC0xNi40MzU3NSwtMjMuNDU0NTVjNC4wNzI5OCwtMzAuMzk3MjkgMjguNjgzNzQsLTU0LjI2MTIyIDU5LjQ5NDU1LC01OC4xMDMyM2MtMy4yNjgwNiwtMC40NTA4NiAtNi42MDUyOCwtMC42ODczNiAtMTAuMDAxOTcsLTAuNjcyMTVjLTM4LjEwODk4LDAuMTY4NzMgLTY4Ljg2MzA5LDMwLjU5NTA2IC02OC42OTE2LDY3Ljk1NzIyYzAuMTcwMTEsMzcuMzYwNzcgMzEuMjA0OTcsNjcuNTEwNSA2OS4zMTI1Nyw2Ny4zNDMxNmMzLjE3ODE3LC0wLjAxMzgzIDYuMzAxMDIsLTAuMjU3MjQgOS4zNjMwMSwtMC42Nzc2OGMtMjcuMDQwNzEsLTMuMzc4NzEgLTQ5LjA1MDAyLC0yMi4wNzE1NCAtNTYuOTQ1NjUsLTQ2Ljc3MzU3bDAuMDAwMDEsLTAuMDAwMDF6IiBmaWxsPSIjRkZDQzAwIi8+CiAgIDxwYXRoIGlkPSJzdmdfMTEiIGQ9Im0xMzcuNTM0NjUsMTc2LjYzMjNjMCwwIC0xMC4zMjAwNiw2Ljk0OTY1IC0xOC4zNTM5OSwxOC42MjkyMWMtOC4wMzM5NCwxMS42NzU0MSAtMTAuNzQwNSwyMy42NjA2MiAtMTAuNzQwNSwyMy42NjA2MnMxMC4zMTg2OCwtNi45NDk2NSAxOC4zNTM5OSwtMTguNjI3ODNjOC4wMzM5NCwtMTEuNjc2OCAxMC43NDA1LC0yMy42NjIwMSAxMC43NDA1LC0yMy42NjIwMSIgZmlsbD0iI0ZGQ0MwMCIgc3Ryb2tlPSJudWxsIi8+CiAgIDxwYXRoIGlkPSJzdmdfMTIiIGQ9Im0xMTEuMTg2ODMsMTQ4LjA2MTk3YzAsMCAtMTIuNDM4ODQsMS4zODU3OCAtMjUuMTI1MjQsNy45OTkzNmMtMTIuNjg2NCw2LjYxMDgxIC0yMC44MTQzOCwxNS45NDYxNyAtMjAuODE0MzgsMTUuOTQ2MTdzMTIuNDM4ODQsLTEuMzg1NzggMjUuMTI1MjQsLTcuOTk3OThzMjAuODE0MzgsLTE1Ljk0NzU1IDIwLjgxNDM4LC0xNS45NDc1NSIgZmlsbD0iI0ZGQ0MwMCIgc3Ryb2tlPSJudWxsIi8+CiAgPC9nPgogPC9nPgo8L3N2Zz4=';

		global $admin_page_hooks;

		if ( ! isset( $admin_page_hooks['inpost-international-api'] ) ) {
			add_menu_page(
				esc_html__( 'InPost International', 'inpost-international' ),
				esc_html_x( 'InPost International', 'Menu item', 'inpost-international' ),
				$capability,
				'inpost-international-api',
				array( $this, 'plugin_page' ),
				$icon_svg,
				$menu_pos
			);
		}

		add_submenu_page(
			'inpost-international-api',
			esc_html__( 'InPost API International', 'inpost-international' ),
			esc_html__( 'InPost API International', 'inpost-international' ),
			'manage_options',
			'inpost-international-settings',
			array( $this, 'plugin_page' )
		);

		remove_submenu_page( 'inpost-international-api', 'inpost-international-settings' );
	}

	/**
	 * Render plugin page and show current version in a setting's header
	 *
	 * @return void
	 */
	public function plugin_page() {
		echo '<div class="wrap">';
		echo '<h1>' . esc_html__( 'InPost API International', 'inpost-international' ) . ' <span style="font-size:50%;">v' . esc_html( INPOST_INTL_PLUGIN_VERSION ) . '</span></h1>';
		$this->show_navigation();
		$this->show_forms();
		echo '</div>';
	}

	/**
	 * Show navigations as tab
	 *
	 * Shows all the settings section labels as tab
	 */
	public function show_navigation() {
		$html = '<nav class="nav-tab-wrapper">';

		$nav_tab_index = 1;
		foreach ( $this->sections_array as $tab ) {

			$setting_id = explode( '_', $tab['id'] );
			$tab_slug   = '';
			if ( is_array( $setting_id ) ) {
				$tab_slug = end( $setting_id );
			}

			$html .= sprintf( '<a href="#%1$s" class="nav-tab" data-tab="%2$s" data-tab-slug="%3$s" id="%1$s-tab">%4$s%5$s</a>', $tab['id'], $nav_tab_index, $tab_slug, $tab['icon'], $tab['title'] );
			++$nav_tab_index;
		}

		$html .= '</nav>';

		echo wp_kses( $html, self::ALLOWED_HTML );
	}

	/**
	 * Show the section settings forms
	 *
	 * This function displays every section in a different form
	 */
	public function show_forms() {
		?>
		<div class="metabox-holder">
			<?php
			$content_tab_index = 1;

			static $settings_updated_alert = false;
			static $connection_alert       = false;
			foreach ( $this->sections_array as $form ) {
				// output settings form inside tabs.
				if ( $form['need_to_save'] ) {
					?>
					<!-- style="display: none;" -->
					<div id="<?php echo esc_attr( $form['id'] ); ?>" style="display:none;" class="group <?php echo esc_attr( $form['id'] ); ?>" data-tab="<?php echo esc_attr( $content_tab_index ); ?>">
						<form method="post" action="<?php echo esc_url( admin_url( 'options.php' ) ); ?>">
							<?php
							do_action( 'inpost_intl_settings_form_top_' . $form['id'], $form );

							$woo_shipping_settings_url = admin_url( 'admin.php?page=wc-settings&tab=shipping' );
							printf(
								'<p class="inpost_intl_before_setting_description inpost_intl_padding_20"><a href="%s" target="_blank">%s</a></p>',
								esc_url( $woo_shipping_settings_url ),
								esc_html__( 'WooCommerce Shipping Settings', 'inpost-international' )
							);

							if ( isset( $_GET['page'] ) && 'inpost-international-api' === $_GET['page'] ) {
								if ( isset( $_GET['settings-updated'] ) && 'true' === $_GET['settings-updated'] ) {
									if ( ! $settings_updated_alert ) {
										$settings_updated_alert = true;
										echo '<div class="inpost_intl notice notice-success is-dismissible"><p>' . esc_html__( 'Settings updated', 'inpost-international' ) . '</p></div>';
									}
								}

								if ( isset( $_GET['auth'] ) && ! $connection_alert ) {
									if ( 'success' === $_GET['auth'] ) {
										$connection_alert = true;
										echo '<div class="inpost_intl notice notice-success is-dismissible">
												<p>' . esc_html__( 'Connection to API is successful', 'inpost-international' ) . '</p>
											  </div>';
									}

									if ( 'failed' === $_GET['auth'] ) {
										$connection_alert = true;
										if ( ! empty( $_GET['details'] ) ) {
											echo '<div class="inpost_intl notice notice-error is-dismissible">
													<p>' . esc_html__( 'Error during to connection to API:', 'inpost-international' ) . '</p>
													<p>' . esc_html( sanitize_text_field( wp_unslash( $_GET['details'] ) ) ) . '</p>
												  </div>';
										} else {
											echo '<div class="inpost_intl notice notice-error is-dismissible">
													<p>' . esc_html__( 'Error during to connection to API', 'inpost-international' ) . '</p>
												  </div>';
										}
									}
								}
							}

							settings_fields( $form['id'] );
							do_settings_sections( $form['id'] );
							do_action( 'inpost_intl_settings_form_bottom_' . $form['id'], $form );
							?>
							<div style="padding-left: 10px">
								<?php submit_button( null, 'primary', 'submit_' . $form['id'] ); ?>
							</div>
							<?php
							// debug, show saved plugin settings.
							if ( ! empty( $_GET['page'] ) && 'inpost-international-api' === $_GET['page'] ) {

								if ( ( ! empty( $_COOKIE['inpost_intl_show_settings'] ) )
									|| ( isset( $_GET['inpost_intl_debug_settings'] ) && 'true' === $_GET['inpost_intl_debug_settings'] )
								) {

									if ( isset( $_GET['tab'] ) ) {
										if ( 'shipments' !== $_GET['tab'] || 'products' !== $_GET['tab'] ) {
											echo '<pre>' . esc_html( $form['id'] ) . '</pre>';
											echo '<pre>' . esc_html( print_r( get_option( $form['id'] ), true ) ) . '</pre>';
										}
									} else {
										echo '<pre>' . esc_html( $form['id'] ) . '</pre>';
										echo '<pre>' . esc_html( print_r( get_option( $form['id'] ), true ) ) . '</pre>';
									}
								}
							}
							?>
						</form>
					</div>

				<?php } else { ?>
					<div id="<?php echo esc_attr( $form['id'] ); ?>" style="display:none;" class="group <?php echo esc_attr( $form['id'] ); ?>" data-tab="<?php echo esc_attr( $content_tab_index ); ?>">

						<?php echo wp_kses( $this->show_special_settings_html( $form['id'] ), self::ALLOWED_HTML_CUSTOM_TABLES ); ?>
					</div>
					<?php
				}
				++$content_tab_index;
			}
			?>
		</div>
		<?php
	}


	/**
	 * Show custom tables
	 *
	 * @param string $setting_section_id $setting_section_id.
	 *
	 * @return false|string
	 */
	private function show_special_settings_html( $setting_section_id ) {

		switch ( $setting_section_id ) {
			case 'inpost_international_settings_products':
				return $this->output_products_settings_table_html();
			case 'inpost_international_settings_shipments':
				return $this->output_shipments_settings_table_html();
			case 'inpost_international_settings_help':
				return $this->output_help_section_html();
			default:
				return '';
		}
	}


	/**
	 * Output Shipments products table
	 *
	 * @return false|string
	 */
	private function output_shipments_settings_table_html() {
		$shipments_table = new Manage_Shipments_Table();
		\ob_start();
		?>
		<div class="inpost_intl_shipments_settings_wrap">
			<?php $shipments_table::render_custom_shipments_settings_page(); ?>
		</div>
		<?php
		$output = \ob_get_contents();
		\ob_end_clean();
		return $output;
	}


	/**
	 * Output Manage products table
	 *
	 * @return false|string
	 */
	private function output_products_settings_table_html() {
		$product_table = new Manage_Products_Table();
		\ob_start();
		?>
		<div class="inpost_intl_product_settings_wrap">
			<?php $product_table::render_custom_product_settings_page(); ?>
		</div>
		<?php
		$output = \ob_get_contents();
		\ob_end_clean();
		return $output;
	}


	/**
	 * Output Manage products table
	 *
	 * @return false|string
	 */
	private function output_help_section_html() {
		$logo = inpost_intl_core()->get_plugin_images_url() . '/yellow.png';
		\ob_start();
		?>
		<div class="inside inpost_intl_helpul_section" style="display: block;margin-right: 12px;">
			<img
				src="<?php echo esc_url( $logo ); ?>"
				title="Inpost International Support form"
				width="150"
				height="auto"
				style="margin-right: 30px; float:left;"
			>
			<p><?php echo esc_html__( 'Please contact us via the form.', 'inpost-international' ); ?></p>
			<p>
				<?php
				printf(
				/* translators: %1$s and %2$s are HTML line breaks */
					esc_html__( 'After entering the form, simply select the "Customer Support" option from the list,%1$s select the "InPost International" module category,%1$s and in the "Please enter the module name" field, enter: "WooCommerce".', 'inpost-international' ),
					PHP_EOL
				);
				?>
			</p>
			<br>
			<a target="_blank" id="inpost_help_form" href="https://inpost.pl/formularz-wsparcie" title="<?php esc_attr_e( 'Inpost International Support form', 'inpost-international' ); ?>">
				<?php echo esc_html__( 'Go to form', 'inpost-international' ); ?>
			</a>
			<div style="clear:both;"></div>
		</div>
		<?php
		$output = \ob_get_contents();
		\ob_end_clean();
		return $output;
	}

	/**
	 * Delete plugin option
	 *
	 * @param string $key $key.
	 *
	 * @return bool
	 */
	private function delete_plugin_option( $key ) {

		$settings = get_option( self::MAIN_OPTIONS );

		unset( $settings[ $key ] );

		return update_option( self::MAIN_OPTIONS, $settings, true );
	}
}
