* @link https://tareq.co Tareq Hasan
 * @example example/oop-example.php How to use the class
 */
use Stratum\String_Encryption;
if ( !class_exists( 'WeDevs_Settings_API' ) ):
class WeDevs_Settings_API {
    /**
     * settings sections array
     *
     * @var array
     */
    protected $settings_sections = array();
    /**
     * Settings fields array
     *
     * @var array
     */
    protected $settings_fields = array();
    public function __construct() {
        add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
    }
    /**
     * Enqueue scripts and styles
     */
    function admin_enqueue_scripts() {
        wp_enqueue_style( 'wp-color-picker' );
        wp_enqueue_media();
        wp_enqueue_script( 'wp-color-picker' );
        wp_enqueue_script( 'jquery' );
    }
    /**
     * Set settings sections
     *
     * @param array   $sections setting sections array
     */
    function set_sections( $sections ) {
        $this->settings_sections = $sections;
        return $this;
    }
    /**
     * Add a single section
     *
     * @param array   $section
     */
    function add_section( $section ) {
        $this->settings_sections[] = $section;
        return $this;
    }
    /**
     * Set settings fields
     *
     * @param array   $fields settings fields array
     */
    function set_fields( $fields ) {
        $this->settings_fields = $fields;
        return $this;
    }
    function add_field( $section, $field ) {
        $defaults = array(
            'name'  => '',
            'label' => '',
            'desc'  => '',
            'type'  => 'text'
        );
        $arg = wp_parse_args( $field, $defaults );
        $this->settings_fields[$section][] = $arg;
        return $this;
    }
    /**
     * Initialize and registers the settings sections and fileds to WordPress
     *
     * Usually this should be called at `admin_init` hook.
     *
     * This function gets the initiated settings sections and fields. Then
     * registers them to WordPress and ready for use.
     */
    function admin_init() {
        //register settings sections
        foreach ( $this->settings_sections as $section ) {
            if ( isset($section['desc']) && !empty($section['desc']) ) {
                $section['desc'] = '
' . $section['desc'] . '
';
                $callback = create_function('', 'echo "' . str_replace( '"', '\"', $section['desc'] ) . '";');
            } else if ( isset( $section['callback'] ) ) {
                $callback = $section['callback'];
            } else {
                $callback = null;
            }
            add_settings_section( $section['id'], $section['title'], $callback, $section['id'] );
        }
        //register settings fields
        foreach ( $this->settings_fields as $section => $field ) {
            foreach ( $field as $option ) {
                $name = $option['name'];
                $type = isset( $option['type'] ) ? $option['type'] : 'text';
                $label = isset( $option['label'] ) ? $option['label'] : '';
                $callback = isset( $option['callback'] ) ? $option['callback'] : array( $this, 'callback_' . $type );
                $args = array(
                    'id'                => $name,
                    'class'             => isset( $option['class'] ) ? $option['class'] : $name,
                    'label_for'         => "{$section}[{$name}]",
                    'desc'              => isset( $option['desc'] ) ? $option['desc'] : '',
                    'desc_btn'          => isset( $option['desc_btn'] ) ? $option['desc_btn'] : '',
                    'desc_link'         => isset( $option['desc_link'] ) ? $option['desc_link'] : '',
					'desc_class'        => isset( $option['desc_class'] ) ? $option['desc_class'] : '',
					'desc_extra_btn'    => isset( $option['desc_extra_btn'] ) ? $option['desc_extra_btn'] : '',
                    'desc_extra_link'   => isset( $option['desc_extra_link'] ) ? $option['desc_extra_link'] : '',
					'desc_extra_class'  => isset( $option['desc_extra_class'] ) ? $option['desc_extra_class'] : '',
                    'name'              => $label,
                    'section'           => $section,
                    'size'              => isset( $option['size'] ) ? $option['size'] : null,
                    'options'           => isset( $option['options'] ) ? $option['options'] : '',
                    'std'               => isset( $option['default'] ) ? $option['default'] : '',
                    'sanitize_callback' => isset( $option['sanitize_callback'] ) ? $option['sanitize_callback'] : '',
                    'type'              => $type,
                    'placeholder'       => isset( $option['placeholder'] ) ? $option['placeholder'] : '',
                    'min'               => isset( $option['min'] ) ? $option['min'] : '',
                    'max'               => isset( $option['max'] ) ? $option['max'] : '',
                    'step'              => isset( $option['step'] ) ? $option['step'] : '',
                    'icon'              => isset( $option['icon'] ) ? $option['icon'] : '',
                );
                add_settings_field( "{$section}[{$name}]", $label, $callback, $section, $section, $args );
            }
        }
        // creates our settings in the options table
        foreach ( $this->settings_sections as $section ) {
            register_setting( $section['id'], $section['id'], array( $this, 'sanitize_options' ) );
        }
    }
    /**
     * Get field description for display
     *
     * @param array   $args settings field args
     */
    public function get_field_description( $args ) {
        $desc = '';
        if ( ! empty( $args['desc'] ) ) {
            $desc = sprintf( '%s
', $args['desc'] );
        }
        if ( ! empty( $args['desc_btn'] ) ) {
            $desc .= sprintf( '%s 
', (!empty($args['desc_link']) ? $args['desc_link'] : '#'), $args['desc_class'], $args['desc_btn'] );
		}
		if ( ! empty( $args['desc_extra_btn'] ) ) {
            $desc .= sprintf( '%s 
', (!empty($args['desc_extra_link']) ? $args['desc_extra_link'] : '#'), $args['desc_extra_class'], $args['desc_extra_btn'] );
		}
        return $desc;
    }
    /**
     * Displays a text field for a settings field
     *
     * @param array   $args settings field args
     */
    function callback_text( $args ) {
        $value       = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
        $size        = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
        $type        = isset( $args['type'] ) ? $args['type'] : 'text';
        $placeholder = empty( $args['placeholder'] ) ? '' : ' placeholder="' . $args['placeholder'] . '"';
        $html        = sprintf( '';
        $html  .= sprintf( '', $args['section'], $args['id'] );
        $html  .= sprintf( ' ', $args['desc'] );
        $html  .= ' ';
        echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }
    /**
     * Displays a toggle for a settings field
     *
     * @param array   $args settings field args
     */
    function callback_toggle( $args ) {
        $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
        $html  = '';
        $html  .= sprintf( '', $args['section'], $args['id'] );
        $html  .= sprintf( ' ';
        $html  .= ' ';
        echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }
    /**
     * Displays a toggle for a settings field
     *
     * @param array   $args settings field args
     */
    function callback_section_title( $args ) {
        $html  = '';
        $html  .= '';
        $html  .= esc_html( $args['name'] );
        $html  .= ' ';
        if( array_key_exists('desc', $args) ){
            if( $args['desc'] ){
                $html  .= sprintf( '%1$s
', $args['desc'] );
            }
        }
        $html  .= ' ';
        echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }
    /**
     * Displays a multicheckbox for a settings field
     *
     * @param array   $args settings field args
     */
    function callback_multicheck( $args ) {
        $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
        $html  = '';
        $html .= sprintf( '', $args['section'], $args['id'], $key );
            $html    .= sprintf( '  ';
        echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }
    /**
     * Displays a radio button for a settings field
     *
     * @param array   $args settings field args
     */
    function callback_radio( $args ) {
        $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
        $html  = '';
        foreach ( $args['options'] as $key => $label ) {
            $html .= sprintf( '',  $args['section'], $args['id'], $key );
            $html .= sprintf( '  ';
        echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }
    /**
     * Displays a selectbox for a settings field
     *
     * @param array   $args settings field args
     */
    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';
        $html  = sprintf( '', $size, $args['section'], $args['id'] );
        foreach ( $args['options'] as $key => $label ) {
            $html .= sprintf( '%s ', $key, selected( $value, $key, false ), $label );
        }
        $html .= sprintf( ' ' );
        $html .= $this->get_field_description( $args );
        echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }
    /**
     * Displays a textarea for a settings field
     *
     * @param array   $args settings field args
     */
    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';
        $placeholder = empty( $args['placeholder'] ) ? '' : ' placeholder="'.$args['placeholder'].'"';
        $html        = sprintf( '', $size, $args['section'], $args['id'], $placeholder, $value );
        $html        .= $this->get_field_description( $args );
        echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }
    /**
     * Displays the html for a settings field
     *
     * @param array   $args settings field args
     * @return string
     */
    function callback_html( $args ) {
        echo $this->get_field_description( $args ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }
    /**
     * Displays a rich text textarea for a settings field
     *
     * @param array   $args settings field args
     */
    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 '';
        $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 '
';
        echo $this->get_field_description( $args ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }
    /**
     * Displays a file upload field for a settings field
     *
     * @param array   $args settings field args
     */
    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 = isset( $args['options']['button_label'] ) ? $args['options']['button_label'] : esc_html__( 'Choose File' );
        $html  = sprintf( '';
        $count = count( $this->settings_sections );
        // don't show the navigation if only one section exists
        if ( $count === 1 ) {
            return;
        }
        foreach ( $this->settings_sections as $tab ) {
            if( array_key_exists('icon', $tab) ){
                $html .= sprintf( '
', $tab['id'], $tab['title'], $tab['icon'] );
            }else{
                $html .= sprintf( '
%2$s ', $tab['id'], $tab['title'] );
            }
        }
        $html .= '
' . esc_html( $section['title'] ) . ' ';
            }
            if ( $section['callback'] ) {
                call_user_func( $section['callback'], $section );
            }
            if ( ! isset( $wp_settings_fields ) || ! isset( $wp_settings_fields[ $page ] ) || ! isset( $wp_settings_fields[ $page ][ $section['id'] ] ) ) {
                continue;
            }
            echo '';
            $this->do_settings_fields( $page, $section['id'] );
            echo '
';
        }
    }
    /**
     * Print out the settings fields for a particular settings section.
     *
     * Part of the Settings API. Use this in a settings page to output
     * a specific section. Should normally be called by do_settings_sections()
     * rather than directly.
     *
     * @global $wp_settings_fields Storage array of settings fields and their pages/sections.
     *
     * @since 2.7.0
     *
     * @param string $page Slug title of the admin page whose settings fields you want to show.
     * @param string $section Slug title of the settings section whose fields you want to show.
     */
    function do_settings_fields( $page, $section ) {
        global $wp_settings_fields;
        if ( ! isset( $wp_settings_fields[ $page ][ $section ] ) ) {
            return;
        }
        foreach ( (array) $wp_settings_fields[ $page ][ $section ] as $field ) {
            $class = '';
            if ( $field['args']['type'] == 'section_title' ) {
                $class = 'form-addons-section-title';
            }else{
                if ( ! empty( $field['args']['class'] ) ) {
                    $class = $field['args']['class'];
                }
            }
            echo '';
        }
    }
    /**
     * Show the section settings forms
     *
     * This function displays every sections in a different form
     */
    function show_forms() {
        ?>
        
        script();
    }
    /**
     * Tabbable JavaScript codes & Initiate Color Picker
     *
     * This code uses localstorage for displaying active tabs
     */
    function script() {
        ?>
        
        add_style();
    }
    function add_style() {
        global $wp_version;
        if (version_compare($wp_version, '3.8', '<=')):
            ?>