<?php
class Book_Author_Template_Meta_Box {
	private $config = '{
	    "title": "Book Author Template Settings",
	    "prefix": "book_author_template_",
	    "domain": "book-author-template",
	    "class_name": "Book_Author_Template_Meta_Box",
	    "post-type": ["post", "page"],
	    "context": "side",
	    "priority": "default",
	    "fields": [
	        {
	            "type": "select",
	            "label": "Show Page Banner",
	            "default": "customizer",
	            "options": "customizer : Customizer\r\nshow : Show\r\nhide : Hide",
	            "id": "book_author_template_show-page-banner"
	        },
	        {
	            "type": "select",
	            "label": "Content Layout",
	            "default": "default",
	            "options": "default : Default Layout\r\nstretched : Full Width Stretched",
	            "id": "book_author_template_content-layout"
	        },
	        {
	            "type": "select",
	            "label": "Sidebar Settings",
	            "default": "both",
	            "options": "customizer : Customizer\r\nright : Right Sidebar\r\nleft : Left Sidebar\r\nno : No Sidebar\r\nboth : Left & Right Sidebar",
	            "id": "book_author_template_sidebar-settings"
	        },
	        {
	            "type": "select",
	            "label": "Hide Featured Image",
	            "default": "customizer",
	            "options": "customizer : Customizer\r\nno : No\r\nyes : Yes",
	            "id": "book_author_template_hide-featured-image",
	            "description": "If you set it to \'Yes\', the featured image will be hidden from the single post/page view but will still be displayed in loops."
	        }
	    ]
	}';

	public function __construct() {
		$this->config = json_decode( $this->config, true );
		add_action( 'add_meta_boxes', [ $this, 'add_meta_boxes' ] );
		add_action( 'save_post', [ $this, 'save_post' ] );
	}

	public function add_meta_boxes() {
		foreach ( $this->config['post-type'] as $screen ) {
			add_meta_box(
				sanitize_title( $this->config['title'] ),
				$this->config['title'],
				[ $this, 'add_meta_box_callback' ],
				$screen,
				$this->config['context'],
				$this->config['priority']
			);
		}
	}

	public function save_post( $post_id ) {
		// Check if our nonce is set and verify it.
		if ( ! isset( $_POST['book_author_template_meta_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['book_author_template_meta_nonce'] ) ), 'book_author_template_meta_save' ) ) {
			return;
		}

		// 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;
		}

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

		// Process and save the fields.
		foreach ( $this->config['fields'] as $field ) {
			switch ( $field['type'] ) {
				default:
					if ( isset( $_POST[ $field['id'] ] ) ) {
						$sanitized = sanitize_text_field( wp_unslash( $_POST[ $field['id'] ] ) );
						update_post_meta( $post_id, $field['id'], $sanitized );
					}
			}
		}
	}

	public function add_meta_box_callback() {
		// Add a nonce field so we can check for it later.
		wp_nonce_field( 'book_author_template_meta_save', 'book_author_template_meta_nonce' );
		$this->fields_div();
	}

	public function fields_div() {
	    global $post;
	    $post_type = $post->post_type;

	    foreach ( $this->config['fields'] as $field ) {
	        // Skip the "Show Page Banner" field for the 'post' post type
	        if ( $post_type === 'post' && $field['id'] === 'book_author_template_show-page-banner' ) {
	            continue;
	        }

	        ?><div class="components-base-control">
	            <div class="components-base-control__field"><?php
	                $this->label( $field );
	                $this->field( $field );
	            ?></div>
	        </div><?php
	    }
	}

	private function label( $field ) {
		switch ( $field['type'] ) {
			default:
				printf(
					'<label class="components-base-control__label" for="%s">%s</label>',
					$field['id'], $field['label']
				);
			if ( isset( $field['description'] ) && ! empty( $field['description'] ) ) {
                printf(
                    '<p class="description">%s</p>',
                    esc_html( $field['description'] )
                );
            }
		}
	}

	private function field( $field ) {
		switch ( $field['type'] ) {
			case 'select':
				$this->select( $field );
				break;
			default:
				$this->input( $field );
		}
	}

	private function input( $field ) {
		printf(
			'<input class="components-text-control__input %s" id="%s" name="%s" %s type="%s" value="%s">',
			isset( $field['class'] ) ? $field['class'] : '',
			$field['id'], $field['id'],
			isset( $field['pattern'] ) ? "pattern='{$field['pattern']}'" : '',
			$field['type'],
			$this->value( $field )
		);
	}

	private function select( $field ) {
		printf(
			'<select id="%s" name="%s">%s</select>',
			$field['id'], $field['id'],
			$this->select_options( $field )
		);
	}

	private function select_selected( $field, $current ) {
		$value = $this->value( $field );
		if ( $value === $current ) {
			return 'selected';
		}
		return '';
	}

	private function select_options( $field ) {
		$output = [];
		$options = explode( "\r\n", $field['options'] );
		$i = 0;
		foreach ( $options as $option ) {
			$pair = explode( ':', $option );
			$pair = array_map( 'trim', $pair );
			$output[] = sprintf(
				'<option %s value="%s"> %s</option>',
				$this->select_selected( $field, $pair[0] ),
				$pair[0], $pair[1]
			);
			$i++;
		}
		return implode( '<br>', $output );
	}

	private function value( $field ) {
		global $post;
		if ( metadata_exists( 'post', $post->ID, $field['id'] ) ) {
			$value = get_post_meta( $post->ID, $field['id'], true );
		} else if ( isset( $field['default'] ) ) {
			$value = $field['default'];
		} else {
			return '';
		}
		return str_replace( '\u0027', "'", $value );
	}

}
new Book_Author_Template_Meta_Box;
