<?php
/**
 * Custom MetaBox Options for Portfolios
 * 
 * @package Responsive Portfolio Image Gallery 1.3 - 10 July, 2025
 * @link https://www.realwebcare.com/
 */

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

if (!class_exists('RPGAL_Custom_Metabox')) {
	class RPGAL_Custom_Metabox
	{

		// Hold the single instance of the class.
		private static $instance;

		// Constructor is private to enforce the Singleton pattern.
		private function __construct()
		{
			add_action('add_meta_boxes', [$this, 'rpgal_add_meta_button']);
			add_action('save_post', [$this, 'rpgal_save_meta_boxes_button']);
			add_action('add_meta_boxes', [$this, 'rpgal_add_meta_box']);
			add_action('wp_insert_post', [$this, 'rpgal_insert_postdata']);
			add_action('save_post', [$this, 'rpgal_insert_postdata']);
		}

		// Public static method to retrieve the singleton instance.
		public static function get_instances()
		{
			if (self::$instance) {
				return self::$instance;
			}

			self::$instance = new self();

			return self::$instance;
		}

		/**
		 * Buttons For this Portfolio
		 * @return void
		 */
		public function rpgal_add_meta_button()
		{
			$rpgal_post_type = 'rpgal';
			add_meta_box(
				'rpgal_portfolio_button',
				esc_html__('Buttons For this Portfolio', 'responsive-portfolio-image-gallery'),
				[$this, 'rpgal_render_buttons_meta_box'],
				$rpgal_post_type,
				'normal',
				'default'
			);
		}

		/**
		 * Render the meta box for adding custom buttons in the portfolio item editor.
		 *
		 * This meta box includes options to:
		 * - Enable/disable "Read More" and "Show Button(s)" checkboxes.
		 * - Add one or more buttons with customizable:
		 *     - Text
		 *     - URL
		 *     - New tab toggle
		 *     - Button and font colors (normal and hover)
		 *
		 * The values are pre-filled from post meta, and each field is properly escaped for output.
		 * @return void
		 */
		public function rpgal_render_buttons_meta_box()
		{
			global $post;
			// $btn = 1;
			wp_nonce_field(plugin_basename(RPGAL_AUF), 'rpgal_meta_box_nonce');

			$button_text = get_post_meta($post->ID, '_button_text', true);
			$button_link = get_post_meta($post->ID, '_button_link', true);
			$button_ntab = get_post_meta($post->ID, '_button_ntab', true);
			?>

			<div class='inside advance-input'>
				<label class="input-title"><?php esc_html_e('Portfolio Button Text', 'responsive-portfolio-image-gallery'); ?></label>
				<input type="text" name="button_text" class="medium" id="button_text" value="<?php echo esc_html($button_text); ?>" placeholder="<?php esc_html_e('e.g. Demo', 'responsive-portfolio-image-gallery'); ?>">

				<label class="input-title"><?php esc_html_e('Portfolio Button Link', 'responsive-portfolio-image-gallery'); ?></label>
				<input type="text" name="button_link" class="medium" id="button_link" value="<?php echo esc_url_raw($button_link); ?>" placeholder="<?php esc_html_e('e.g. http://example.com', 'responsive-portfolio-image-gallery'); ?>">

				<label class="input-title"><?php esc_html_e('Open Link in New Tab', 'responsive-portfolio-image-gallery'); ?>:</label>
				<select name="button_ntab" id="button_ntab" class="port-dir">
					<?php foreach (['true' => __('Yes', 'responsive-portfolio-image-gallery'), 'false' => __('No', 'responsive-portfolio-image-gallery')] as $value => $label): ?>
						<option value="<?php echo esc_attr($value); ?>" <?php selected($button_ntab, $value); ?>>
							<?php echo esc_html($label); ?>
						</option>
					<?php endforeach; ?>
				</select>
			</div>
			<?php
		}

		/**
		 * Save the meta box data for gallery buttons
		 *
		 * This method handles saving all the button-related custom fields when the post is saved.
		 * It validates the nonce, ensures permissions, and sanitizes all submitted values.
		 * @param mixed $post_id
		 * @return void
		 */
		public function rpgal_save_meta_boxes_button($post_id)
		{
			// Skip autosaves
			if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
				return;
			}

			// Check user capabilities
			if (!current_user_can('edit_post', $post_id)) {
				return;
			}

			// Verify nonce
			if (!isset($_POST['rpgal_meta_box_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['rpgal_meta_box_nonce'])), plugin_basename(RPGAL_AUF))) {
				return;
			}

			// Helper function to sanitize and store array fields
			$save_array_meta = function ($field_name, $sanitizer = 'text') use ($post_id) {
				if (!isset($_POST['rpgal_meta_box_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['rpgal_meta_box_nonce'])), plugin_basename(RPGAL_AUF))) {
					return;
				}

				if (!isset($_POST[$field_name])) {
					delete_post_meta($post_id, '_' . $field_name);
					return;
				}

				$raw_value = wp_unslash($_POST[$field_name]);

				// Convert single values to array
				$values = is_array($raw_value) ? $raw_value : [$raw_value];

				$sanitized_array = array_map(function ($value) use ($sanitizer) {
					if ($sanitizer === 'url') {
						return esc_url_raw($value);
					}
					return sanitize_text_field($value);
				}, $values);

				// If all values are empty, delete meta
				if (empty(array_filter($sanitized_array))) {
					delete_post_meta($post_id, '_' . $field_name);
					return;
				}

				// Save as comma-separated string
				$combined = implode(',', $sanitized_array);
				update_post_meta($post_id, '_' . $field_name, $combined);
			};

			// Sanitize and update other fields
			$save_array_meta('button_text'); // text
			$save_array_meta('button_link', 'url'); // urls
			$save_array_meta('button_ntab'); // 'true' or 'false'
		}

		/**
		 * 'Images For this Portfolio
		 * @return void
		 */
		public function rpgal_add_meta_box()
		{
			$rpgal_post_type_select = 'rpgal';
			add_meta_box(
				'rpgal_portfolio_meta',
				esc_html__('Images For this Portfolio', 'responsive-portfolio-image-gallery'),
				[$this, 'rpgal_render_images_meta_box'],
				$rpgal_post_type_select,
				'side',
				'default'
			);
		}

		/**
		 * Render the image upload meta box in the post edit screen.
		 * Displays selected images and allows users to upload or remove images.
		 * @return void
		 */
		public function rpgal_render_images_meta_box()
		{
			global $post;

			// Output nonce for verification
			wp_nonce_field(plugin_basename(RPGAL_AUF), 'rpgal_noncename');

			// Retrieve stored image IDs
			$value = get_post_meta($post->ID, '_multi_img_array', true);
			$value = sanitize_text_field($value); // Ensure it's a clean comma-separated string
			$image_ids = array_filter(array_map('absint', explode(',', $value))); // Sanitize and remove empty

			$temp = '';

			if (!empty($image_ids)) {
				foreach ($image_ids as $img_id) {
					$image_attributes = wp_get_attachment_image_src($img_id, array(63, 63));

					if (!empty($image_attributes)) {
						$src = $image_attributes[0];
						$width = (int) $image_attributes[1];
						$height = (int) $image_attributes[2];

						printf(
							'<img src="%s" width="%d" height="%d" data-id="%d">',
							esc_url($src),
							intval($width),
							intval($height),
							intval($img_id)
						);

						$temp .= $img_id . ',';
					}
				}
				// Remove trailing comma
				$temp = rtrim($temp, ',');
			}

			// Hidden field with image IDs
			printf(
				"<input type='hidden' name='image_upload_val' id='image_upload_val' value='%s' />",
				esc_attr($temp)
			);

			// Upload and instruction buttons
			echo "<div class='rpgal_upload_media' id='rpgal_image_upload'>" . esc_html__('Upload Images', 'responsive-portfolio-image-gallery') . "</div>";
			echo "<span class='remove_image'>" . esc_html__('Click on image to remove it', 'responsive-portfolio-image-gallery') . "</span>";
		}

		/**
		 * Save the selected image IDs from the meta box when the post is saved.
		 * @param mixed $post_id
		 * @return void
		 */
		public function rpgal_insert_postdata($post_id)
		{
			// Check if this is an autosave or a revision
			if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
				return;
			}

			// Verify nonce
			if (!isset($_POST['rpgal_noncename']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['rpgal_noncename'])), plugin_basename(RPGAL_AUF))) {
				return;
			}

			// Check if the current user has permission to edit the post
			if (!current_user_can('edit_post', $post_id)) {
				return;
			}

			// Ensure the form field exists
			if (!isset($_POST['image_upload_val'])) {
				return;
			}

			// Sanitize and validate image IDs
			$raw_ids = sanitize_text_field(wp_unslash($_POST['image_upload_val']));
			$image_ids = array_filter(array_map('absint', explode(',', $raw_ids))); // Keep only integers

			if (!empty($image_ids)) {
				$clean_ids = implode(',', $image_ids); // Rebuild sanitized CSV
				update_post_meta($post_id, '_multi_img_array', $clean_ids);
			} else {
				// If empty, remove the meta to clear previous images
				delete_post_meta($post_id, '_multi_img_array');
			}
		}
	}
}

RPGAL_Custom_Metabox::get_instances();
