<?php
/**
 * The core metabox framework class.
 *
 * @package Sifency
 */

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

class Sifency_Metabox {

	private $metaboxes;

	public function __construct( array $metabox_definitions ) {
		$this->metaboxes = $metabox_definitions;
		add_action( 'add_meta_boxes', [ $this, 'register_meta_boxes' ] );
		add_action( 'save_post', [ $this, 'save_meta_data' ] );
		add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_scripts' ] );
	}

	public function enqueue_admin_scripts( $hook ) {
		if ( 'post.php' !== $hook && 'post-new.php' !== $hook ) {
			return;
		}

		// Enqueue all necessary scripts and styles.
		wp_enqueue_style( 'wp-color-picker' );
		wp_enqueue_media();
		wp_enqueue_script( 'jquery-ui-sortable' );
		
		// Note: wp-color-picker is a dependency for our main script now.
		$script_dependencies = [ 'jquery', 'jquery-ui-sortable', 'wp-color-picker' ];

		wp_enqueue_style(
			'sifency-admin-metabox',
			SIFENCY_TB_URL . 'assets/css/admin-metabox.css',
			[],
			SIFENCY_TB_VERSION
		);

		wp_enqueue_script(
			'sifency-admin-metabox',
			SIFENCY_TB_URL . 'assets/js/admin-metabox.js',
			$script_dependencies,
			SIFENCY_TB_VERSION,
			true
		);
	}
	public function register_meta_boxes() {
		foreach ( $this->metaboxes as $id => $metabox ) {
			add_meta_box(
				$id,
				$metabox['title'],
				[ $this, 'render_metabox_content' ],
				$metabox['post_type'],
				$metabox['context'] ?? 'normal',
				$metabox['priority'] ?? 'high',
				[ 'fields' => $metabox['fields'], 'id' => $id ]
			);
		}
	}

	public function render_metabox_content( $post, $args ) {
		$fields       = $args['args']['fields'];
		$metabox_id   = $args['args']['id'];
		$nonce_action = $metabox_id . '_nonce_action';
		$nonce_name   = $metabox_id . '_nonce';

		wp_nonce_field( $nonce_action, $nonce_name );
		echo '<div class="sifency-metabox-wrapper">';

		foreach ( $fields as $field ) {
			$value = get_post_meta( $post->ID, $field['id'], true );
			if ( '' === $value && isset( $field['default'] ) ) {
				$value = $field['default'];
			}

			$field_classes = [
				'sifency-addons-field-row',
				'sifency-addons-field-type-' . esc_attr( $field['type'] ),
				'sifency-addons-field-id-' . esc_attr( $field['id'] ),
			];

			if ( ! empty( $field['class'] ) ) {
				$field_classes[] = esc_attr( $field['class'] );
			}


			$dependency_attrs = '';
			if ( ! empty( $field['dependency'] ) ) {
				list( $controller, $operator, $dep_value ) = $field['dependency'];
				$dependency_attrs = sprintf(
					' data-dependency-controller="%s" data-dependency-operator="%s" data-dependency-value="%s"',
					esc_attr( $controller ),
					esc_attr( $operator ),
					esc_attr( $dep_value )
				);
			}

			echo '<div class="' . esc_attr( implode( ' ', $field_classes ) ) . '"' . wp_kses_post ( $dependency_attrs ) . '>';
			echo '<div class="sifency-addons-label-col"><label for="' . esc_attr( $field['id'] ) . '">' . esc_html( $field['title'] ) . '</label></div>';
			echo '<div class="sifency-addons-field-col">';
			$this->render_field( $field, $value );
			if ( ! empty( $field['desc'] ) ) {
				echo '<p class="description">' . wp_kses_post( $field['desc'] ) . '</p>';
			}
			echo '</div></div>';
		}
		echo '</div>';
	}

	private function render_field( $field, $value, $name_prefix = '' ) {
		$field_id       = $field['id'];
		$field_name     = $name_prefix ? $name_prefix . '[' . $field_id . ']' : $field_id;
		$attributes_str = '';
		if ( ! empty( $field['attributes'] ) && is_array( $field['attributes'] ) ) {
			foreach ( $field['attributes'] as $attr => $attr_val ) {
				$attributes_str .= ' ' . esc_attr( $attr ) . '="' . esc_attr( $attr_val ) . '"';
			}
		}

		switch ( $field['type'] ) {
			case 'repeater':
				$template_id = 'sifency-repeater-template-' . esc_attr( $field_id );
				echo '<div class="sifency-repeater-items" id="' . esc_attr( $field_id ) . '-items" data-template-id="' . esc_attr( $template_id ) . '">';
				$items = ! empty( $value ) && is_array( $value ) ? $value : ( $field['default'] ?? [] );
				foreach ( $items as $index => $item_data ) {
					echo '<div class="sifency-repeater-row">';
					echo '<span class="sifency-repeater-handle" title="' . esc_attr__( 'Drag to reorder', 'sifency-addons' ) . '"></span>';
					echo '<a href="#" class="sifency-repeater-remove" title="' . esc_attr__( 'Remove item', 'sifency-addons' ) . '"></a>';
					$repeater_name_prefix = $field_id . '[' . $index . ']';
					foreach ( $field['fields'] as $sub_field ) {
						echo '<div class="sifency-repeater-sub-field">';
						echo '<label>' . esc_html( $sub_field['title'] ) . '</label>';
						$sub_value = $item_data[ $sub_field['id'] ] ?? '';
						$this->render_field( $sub_field, $sub_value, $repeater_name_prefix );
						echo '</div>';
					}
					echo '</div>';
				}
				echo '</div>';
				echo '<button type="button" class="button sifency-repeater-add">' . esc_html__( 'Add New', 'sifency-addons' ) . '</button>';
				echo '<script type="text/html" id="' .  esc_attr ( $template_id ) . '">';
				echo '<div class="sifency-repeater-row">';
				echo '<span class="sifency-repeater-handle" title="' . esc_attr__( 'Drag to reorder', 'sifency-addons' ) . '"></span>';
				echo '<a href="#" class="sifency-repeater-remove" title="' . esc_attr__( 'Remove item', 'sifency-addons' ) . '"></a>';
				$repeater_name_prefix = $field_id . '[__i__]';
				foreach ( $field['fields'] as $sub_field ) {
					echo '<div class="sifency-repeater-sub-field">';
					echo '<label>' . esc_html( $sub_field['title'] ) . '</label>';
					$this->render_field( $sub_field, $sub_field['default'] ?? '', $repeater_name_prefix );
					echo '</div>';
				}
				echo '</div></script>';
				break;
			case 'button_set':
				echo '<div class="sifency-button-set">';
				foreach ( $field['options'] as $key => $label ) {
					$radio_id = esc_attr( $field_id ) . '_' . esc_attr( $key );
					echo '<input type="radio" id="' . esc_attr ( $radio_id ) . '" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $key ) . '" ' . checked( $value, $key, false ) . '/>';
					echo '<label for="' . esc_attr ( $radio_id ) . '">' . esc_html( $label ) . '</label>';
				}
				echo '</div>';
				break;
			case 'select':
				echo '<select id="' . esc_attr( $field_id ) . '" name="' . esc_attr( $field_name ) . '">';
				$options = is_callable( $field['options'] ) || function_exists( $field['options'] ) ? call_user_func( $field['options'] ) : $field['options'];
				foreach ( (array) $options as $key => $label ) {
					echo '<option value="' . esc_attr( $key ) . '" ' . selected( $value, $key, false ) . '>' . esc_html( $label ) . '</option>';
				}
				echo '</select>';
				break;
			case 'upload':
				$file_id     = $value;
				$filename    = $file_id ? basename( get_attached_file( $file_id ) ) : '';
				$hide_remove = empty( $file_id ) ? 'style="display:none;"' : '';
				$hide_name   = empty( $filename ) ? 'style="display:none;"' : '';
				echo '<div class="sifency-upload-field">';
				echo '<input type="hidden" class="sifency-upload-input" id="' . esc_attr( $field_id ) . '" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $file_id ) . '" />';
				echo '<span class="sifency-upload-filename" ' . esc_attr ( $hide_name ) . '>' . esc_html( $filename ) . '</span>';
				echo '<button type="button" class="button sifency-upload-add">' . esc_html__( 'Upload File', 'sifency-addons' ) . '</button> ';
				echo '<button type="button" class="button button-link-delete sifency-upload-remove" ' . esc_attr (  $hide_remove ) . '>' . esc_html__( 'Remove', 'sifency-addons' ) . '</button>';
				echo '</div>';
				break;
			case 'media':
				$image_src = $value ? wp_get_attachment_image_url( $value, 'thumbnail' ) : '';
				echo '<div class="sifency-media-field">';
				echo '<input type="hidden" class="sifency-media-input" id="' . esc_attr( $field_id ) . '" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $value ) . '" />';
				echo '<button type="button" class="button sifency-media-upload">' . esc_html__( 'Upload/Select Image', 'sifency-addons' ) . '</button> ';
				echo '<button type="button" class="button button-link-delete sifency-media-remove">' . esc_html__( 'Remove Image', 'sifency-addons' ) . '</button>';
				echo '<div class="sifency-media-preview">' . ( $image_src ? '<img src="' . esc_url( $image_src ) . '" style="max-width:150px; height:auto;" />' : '' ) . '</div>';
				echo '</div>';
				break;
			case 'textarea':
				echo '<textarea id="' . esc_attr( $field_id ) . '" name="' . esc_attr( $field_name ) . '">' . esc_textarea( $value ) . '</textarea>';
				break;
			case 'slider':
				$min  = $field['min'] ?? 0;
				$max  = $field['max'] ?? 100;
				$step = $field['step'] ?? 1;
				$val  = ! empty( $value ) ? $value : ( $field['default'] ?? $min );
				echo '<div class="sifency-slider-wrapper">';
				echo '<input type="range" class="sifency-slider-input" id="' . esc_attr( $field_id ) . '" name="' . esc_attr( $field_name ) . '" min="' . esc_attr( $min ) . '" max="' . esc_attr( $max ) . '" step="' . esc_attr( $step ) . '" value="' . esc_attr( $val ) . '" />';
				echo '<span class="sifency-slider-value">' . esc_html( $val ) . '</span>';
				echo '</div>';
				break;
			case 'checkbox':
				echo '<div class="sifency-checkbox-group">';
				$value = is_array( $value ) ? $value : [];
				foreach ( $field['options'] as $key => $label ) {
					$checkbox_id = esc_attr( $field_id ) . '_' . esc_attr( $key );
					echo '<label for="' . esc_attr ( $checkbox_id ) . '"><input type="checkbox" id="' . esc_attr ( $checkbox_id ) . '" name="' . esc_attr( $field_name ) . '[]" value="' . esc_attr( $key ) . '" ' . checked( in_array( $key, $value ), true, false ) . '/> ' . esc_html( $label ) . '</label><br>';
				}
				echo '</div>';
				break;

				case 'wp_editor':
				$editor_id = str_replace( [ '[', ']' ], [ '_', '' ], $field_name );
				$settings = $field['settings'] ?? [];
				$settings['textarea_name'] = $field_name;
				wp_editor( $value, $editor_id, $settings );
				break;
			case 'color':
				echo '<input type="text" class="sifency-color-picker" id="' . esc_attr( $field_id ) . '" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $value ) . '" data-default-color="' . esc_attr( $field['default'] ?? '' ) . '"' . esc_attr ( $attributes_str ) . ' />';
				break;

			case 'datetime':
				echo '<input type="datetime-local" class="sifency-field-date" id="' . esc_attr( $field_id ) . '" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $value ) . '"' . esc_attr ( $attributes_str ) . ' />';
				break;
			case 'text':
			case 'email':
			case 'url':
			case 'number':
			case 'time':
			case 'date':
			default:
				echo '<input type="' . esc_attr( $field['type'] ) . '" id="' . esc_attr( $field_id ) . '" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $value ) . '"' . esc_attr ( $attributes_str ) . ' />';
				break;
		}
	}
	
	public function save_meta_data( $post_id ) {
		$current_post_type = get_post_type( $post_id );
		$active_metabox = null;
		foreach ( $this->metaboxes as $id => $metabox ) {
			if ( $metabox['post_type'] === $current_post_type ) {
				$active_metabox = $metabox;
				$metabox_id     = $id;
				break;
			}
		}
		if ( ! $active_metabox ) {
			return;
		}
		$nonce_action = $metabox_id . '_nonce_action';
		$nonce_name   = $metabox_id . '_nonce';
		if ( ! isset( $_POST[ $nonce_name ] ) || ! wp_verify_nonce( sanitize_key( $_POST[ $nonce_name ] ), $nonce_action ) ) {
			return;
		}
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
			return;
		}
		if ( ! current_user_can( 'edit_post', $post_id ) ) {
			return;
		}
		foreach ( $active_metabox['fields'] as $field ) {
			if ( isset( $_POST[ $field['id'] ] ) ) {
				$value = $this->sanitize_field( $_POST[ $field['id'] ], $field ); // phpcs:ignore
				update_post_meta( $post_id, $field['id'], $value );
			} else {
				if ( 'checkbox' === $field['type'] ) {
					update_post_meta( $post_id, $field['id'], [] );
				} else {
					delete_post_meta( $post_id, $field['id'] );
				}
			}
		}
	}

	private function sanitize_field( $data, $field_config ) {
		if ( 'repeater' === $field_config['type'] ) {
			$sanitized_data = [];
			if ( is_array( $data ) ) {
				foreach ( $data as $index => $row_data ) {
					$sanitized_row = [];
					foreach ( $field_config['fields'] as $sub_field ) {
						if ( isset( $row_data[ $sub_field['id'] ] ) ) {
							$sanitized_row[ $sub_field['id'] ] = $this->sanitize_field( $row_data[ $sub_field['id'] ], $sub_field );
						}
					}
					$sanitized_data[] = $sanitized_row;
				}
			}
			return $sanitized_data;
		}
		if ( isset( $field_config['sanitize'] ) ) {
			switch ( $field_config['sanitize'] ) {
				case 'wp_kses_post':
					return wp_kses_post( $data );
				case 'allow_iframe':
					$allowed_html = [ 'iframe' => [ 'src' => true, 'width' => true, 'height' => true, 'style' => true, 'frameborder' => true, 'allowfullscreen' => true, 'loading' => true, 'referrerpolicy' => true ] ];
					return wp_kses( $data, $allowed_html );
				case false:
				case 'none':
					return $data;
			}
		}

		$type = $field_config['type'];
		switch ( $type ) {
			case 'textarea':   return sanitize_textarea_field( $data );
			case 'checkbox':   return is_array( $data ) ? array_map( 'sanitize_text_field', $data ) : [];
			case 'slider':     return floatval( $data );
			case 'upload':
			case 'media':      return absint( $data );
			case 'email':      return sanitize_email( $data );
			case 'url':        return esc_url_raw( $data );
			case 'number':     return intval( $data );
			case 'wp_editor':  return wp_kses_post( $data );
			case 'color':      return sanitize_hex_color( $data );

			// Default for all other text-based fields
			case 'select':
			case 'button_set':
			case 'text':
			case 'date':
			case 'time':
			case 'datetime':
			default:
				return sanitize_text_field( $data );
		}
	}
}