<?php

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

/**
 * A wrapper for all metaboxes.
 */
class GiveASAP_Metaboxes {

	/**
	 * Array of all metaboxes to render.
	 *
	 * @var array
	 */
	private $metaboxes = array();

	/**
	 * Get all metaboxes through hook if any and then register our metabox method.
	 */
	public function register() {
		do_action( 'sg_metaboxes_before_register', $this );
		add_action( 'add_meta_boxes', array( $this, 'register_metabox' ) );
        add_action( 'giveasap_visual_builder_sidebar', [ $this, 'render_visual_sidebar' ] );
        add_action( 'giveasap_visual_builder_sidebar_options', [ $this, 'render_visual_sidebar_options' ] );
	}

	/**
	 * Register our main metabox.
	 */
	public function register_metabox() {
		add_meta_box(
			'sg-metaboxes',
			__( 'Giveaway', 'giveasap' ),
			array(
				$this,
				'render',
			),
			'giveasap',
			'advanced',
			'high'
		);
	}

	/**
	 * @param GiveASAP_Metabox $metabox
	 */
	public function add( GiveASAP_Metabox $metabox ) {
		$metabox->register                        = false;
		$this->metaboxes[ $metabox->settings_id ] = $metabox;
	}

	/**
	 * Prepare the metaboxes by filtering them.
	 */
	private function prepare() {
		$this->metaboxes = apply_filters( 'sg_metaboxes', $this->metaboxes, $this );
	}

    public function render_visual_sidebar() {
        $this->prepare();
        if ( $this->metaboxes ) {
        ?>
             <ul class="sidebar-sections">
					<?php
					$active = true;
					foreach ( $this->metaboxes as $slug => $metabox ) {
					    $metabox_classes = array();
					    $metabox_classes[] = 'sg-' . $slug;
					    $metabox_classes[] = $active ? 'active' : '';

						$icon = '';
						if ( $metabox->icon ) {
							$icon = '<span class="sg-metabox-icon">' . $metabox->icon . '</span>';
						}
						?>
						<li class="sg-metabox <?php echo esc_attr( implode( ' ', $metabox_classes ) ); ?>"><a href="#sg-metabox-visual-fields-<?php echo esc_attr( $slug ); ?>"><?php echo wp_kses_post( $icon . $metabox->get_title() ); ?></a></li>
						<?php
						$active = false;
					}
					?>
				</ul>
            <?php
        }
    }

    public function render_visual_sidebar_options( $post ) {
        if (! $this->metaboxes ) {
            return;
        }
        ?>
        <div class="sg-metaboxes-fields">
            <?php
            $hidden = false;
            foreach ( $this->metaboxes as $slug => $metabox ) {
                $metabox_classes   = array();
                $metabox_classes[] = 'sg-' . $slug;
                $metabox_classes[] = $hidden ? 'hidden' : '';
                ?>
                <div id="sg-metabox-visual-fields-<?php echo esc_attr( $slug ); ?>" class="sg-metabox-fields <?php echo esc_attr( implode( ' ', $metabox_classes ) ); ?>">
                    <?php
                    $metabox->set_render_context( 'visual' );
                    $metabox->render( $post );
                    $metabox->set_render_context( 'table' );
                    ?>
                </div>
                <?php
                $hidden = true;
            }
            ?>
        </div>
        <?php
    }

	/**
	 * Render our metabox.
	 *
	 * @param $post
	 */
	public function render( $post ) {
		$this->prepare();
		if ( $this->metaboxes ) {
			?>
			<div class="sg-metaboxes">
				<ul>
					<?php
					$active = true;
					foreach ( $this->metaboxes as $slug => $metabox ) {
					    $metabox_classes = array();
					    $metabox_classes[] = 'sg-' . $slug;
					    $metabox_classes[] = $active ? 'active' : '';

						$icon = '';
						if ( $metabox->icon ) {
							$icon = '<span class="sg-metabox-icon">' . $metabox->icon . '</span>';
						}
						?>
						<li class="sg-metabox <?php echo esc_attr( implode( ' ', $metabox_classes ) ); ?>"><a href="#sg-metabox-fields-<?php echo esc_attr( $slug ); ?>"><?php echo wp_kses_post( $icon . $metabox->get_title() ); ?></a></li>
						<?php
						$active = false;
					}
					?>
				</ul>
				<div class="sg-metaboxes-fields">
					<?php
					$hidden = false;
					foreach ( $this->metaboxes as $slug => $metabox ) {
						$metabox_classes   = array();
						$metabox_classes[] = 'sg-' . $slug;
						$metabox_classes[] = $hidden ? 'hidden' : '';
						?>
						<div id="sg-metabox-fields-<?php echo esc_attr( $slug ); ?>" class="sg-metabox-fields <?php echo esc_attr( implode( ' ', $metabox_classes ) ); ?>"><?php $metabox->render( $post ); ?></div>
						<?php
						$hidden = true;
					}
					?>
				</div>
			</div>
			<?php
		}
	}
}

/**
 * Class for making Metaboxes
 */
class GiveASAP_Metabox extends GiveASAP_WordPressSettings {

	/**
	 * Icon
	 *
	 * @var string
	 */
	public $icon = '';

	/**
	 * Metabox Title
	 */
	protected $title = '';

	/**
	 * Metabox ID
	 */
	protected $slug = '';

	/**
	 * Array of post types for which we allow the metabox
	 */
	protected $post_types = array();

	/**
	 * Post ID used to save or retrieve the settings
	 */
	protected $post_id = 0;

	/**
	 * Metabox context
	 */
	protected $context = '';

	/**
	 * Should Register?
	 *
	 * @var bool
	 */
	public $register = true;

	/**
	 * Metabox priority
	 */
	protected $priority = '';

	/**
	 * Collecting errors and displaying them.
	 *
	 * @var array
	 */
	protected $errors = array();

	public function __construct( $title, $slug, $post_types = array( 'post' ), $context = 'advanced', $priority = 'default', $icon = '<i class="fal fa-cog"></i>' ) {

		if ( $slug == '' || $context == '' || $priority == '' ) {
			return;
		}

		if ( $title == '' ) {
			$this->title = ucfirst( $slug );
		}

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

		$this->title       = $title;
		$this->slug        = $slug;
		$this->post_types  = $post_types;
		$this->settings_id = $this->slug;
		$this->context     = $context;
		$this->priority    = $priority;
		$this->icon        = $icon;

		do_action( 'giveasap_metabox_object_' . $this->settings_id, $this );

		add_action( 'add_meta_boxes', array( $this, 'register' ) );
		add_action( 'save_post', array( $this, 'save_meta_settings' ) );
	}

	/**
	 * Get post ID.
	 *
	 * @return int
	 */
	public function get_post_id() {
		return $this->post_id;
	}

	/**
	 * Set the Post ID.
	 *
	 * @param $id
	 */
	public function set_post_id( $id ) {
		$this->post_id = $id;
	}

	public function register( $post_type ) {
		if ( $this->register && in_array( $post_type, $this->post_types ) ) {
			add_meta_box(
				$this->slug,
				$this->title,
				array(
					$this,
					'render',
				),
				$post_type,
				$this->context,
				$this->priority
			);
		}
	}

	public function get_title() {
		return $this->title;
	}

	public function render( $post ) {
		$this->post_id = $post->ID;

		wp_nonce_field( 'metabox_' . $this->slug, 'metabox_' . $this->slug . '_nonce' );

		$this->get_all_fields();

		$this->init_settings();

		if ( $this->errors ) {
			for ( $i = 0; $i < count( $this->errors ); $i++ ) {
				$error = $this->errors[ $i ];
				echo '<div class="error"><p>' . $error . '</p></div>';
			}
		}
		do_action( 'gasap_metabox_' . $this->slug . '_before_fields' );
		$this->render_fields( 'general' );
		?>
        <style>
            .form-table .wide-td td { width: 80%; }
        </style>
        <?php

	}

	/**
	 * Get the settings from the database
	 *
	 * @return void
	 */
	public function init_settings() {

		$post_id        = $this->post_id;
		$this->settings = get_post_meta( $post_id, $this->settings_id, true );

		if ( ! $this->settings ) {
			$this->settings = array();
		}

		if ( ! is_array( $this->settings ) ) {
			$this->settings = maybe_unserialize( $this->settings );
		}

		foreach ( $this->fields as $tab_key => $tab ) {

			foreach ( $tab as $name => $field ) {
				if ( isset( $field['single'] ) && true === $field['single'] ) {
					$this->fields[ $tab_key ][ $name ]['default'] = get_post_meta( $post_id, $name, true );
				} elseif ( isset( $this->settings[ $name ] ) ) {
					$this->fields[ $tab_key ][ $name ]['default'] = $this->settings[ $name ];
				}
			}
		}
	}

	public function save_meta_settings( $post_id ) {
		if ( ! in_array( get_post_type( $post_id ), $this->post_types ) ) {
			return $post_id;
		}
		// Check if our nonce is set.
		if ( ! isset( $_POST[ 'metabox_' . $this->slug . '_nonce' ] ) ) {
			return $post_id;
		}

		$nonce = \Simple_Giveaways\Helpers::unslash_and_clean( $_POST[ 'metabox_' . $this->slug . '_nonce' ] );

		// Verify that the nonce is valid.
		if ( ! wp_verify_nonce( $nonce, 'metabox_' . $this->slug ) ) {
			return $post_id;
		}

		/*
		* If this is an autosave, our form has not been submitted,
		* so we don't want to do anything.
		*/
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
			return $post_id;
		}

		// Check the user's permissions.
		if ( 'page' == $_POST['post_type'] ) {
			if ( ! current_user_can( 'edit_page', $post_id ) ) {
				return $post_id;
			}
		} else {
			if ( ! current_user_can( 'edit_post', $post_id ) ) {
				return $post_id;
			}
		}

		$this->post_id = $post_id;

		$this->get_all_fields();
		$this->save_settings();

		do_action( 'giveasap_metabox_' . $this->settings_id . '_saved' );
	}

	/**
	 * Save settings from POST
	 *
	 * @return void
	 */
	public function save_settings() {
		$this->posted_data = wp_unslash( $_POST );

		if ( empty( $this->settings ) ) {
			$this->init_settings();
		}

		if ( ! is_array( $this->settings ) ) {
			$this->settings = array();
		}

		$no_single = false;

		foreach ( $this->fields as $tab => $tab_data ) {
			foreach ( $tab_data as $name => $field ) {

				if ( empty( $this->posted_data[ $name ] ) ) {
					// Remove it if it's not posted on metabox.
					if ( isset( $this->settings[ $name ] ) ) {
						unset( $this->settings[ $name ] );
					}

					if ( isset( $field['single'] ) && true === $field['single'] ) {
                        delete_post_meta( $this->post_id, $name );
                    }
					continue;
				}

				if ( 'custom' === $field['type'] ) {
					if ( isset( $field['validate'] ) && '' !== $field['validate'] ) {
						$func = $field['validate'];
						if ( is_callable( $func ) ) {
							// Passes the value to the function
							$this->settings[ $name ] = call_user_func_array( $func, array( $this->posted_data[ $name ], $this ) );
						} else {
							$this->settings[ $name ] = $this->posted_data[ $name ];
						}
					} else {
						$this->settings[ $name ] = $this->posted_data[ $name ];
					}
				} else {
					$this->settings[ $name ] = $this->{'validate_' . $field['type']}( $name );
				}

				if ( isset( $field['single'] ) && true === $field['single'] ) {
					update_post_meta( $this->post_id, $name, $this->settings[ $name ] );
					unset( $this->settings[ $name ] );
				} else {
					$no_single = true;
				}
			}
		}

		// If we have no single fields, let's save them. Otherwise, don't.
		if ( $no_single ) {
			update_post_meta( $this->post_id, $this->settings_id, $this->settings );
		}
	}

	/**
	 * Adding the error message;
	 *
	 * @param string $error Error message.
	 */
	public function add_error( $error ) {
		$this->errors[] = $error;
	}

}
