<?php
/**
 * Quick edit manager
 *
 * Fields supported at the moment:
 * - text
 * - number
 * - date
 * - time
 * - datetime-local
 * - textarea
 * - checkbox (only with Save as array enabled)
 * - radio
 * - select
 */

// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
	die;
}

if ( ! class_exists( 'Jet_Engine_CPT_Quick_Edit' ) ) {

	/**
	 * Define Jet_Engine_CPT_Quick_Edit class
	 */
	class Jet_Engine_CPT_Quick_Edit {

		public static $hook_after_save_all = array();

		public $post_type   = null;
		public $field       = null;
		public $trigger_col = 'jet_engine_quick_edit';

		public static $add_inline_css = false;
		public static $is_first = true;

		public function __construct( $post_type, $field ) {

			$this->post_type = $post_type;
			$this->field     = $field;

			add_filter( 'manage_' . $this->get_post_type() . '_posts_columns', array( $this, 'register_quick_edit_trigger' ), 10, 2 );
			add_action( 'manage_' . $this->get_post_type() . '_posts_custom_column', array( $this, 'set_column_value' ), 10, 2 );
			add_filter( 'hidden_columns', array( $this, 'hide_quick_edit_trigger' ), 10, 2 );

			add_action( 'quick_edit_custom_box', array( $this, 'render_control' ), 10, 2 );
			add_action( 'save_post_' . $this->post_type, array( $this, 'save_field' ), 5 );

			if ( ! in_array( $this->post_type, self::$hook_after_save_all ) ) {
				add_action( 'save_post_' . $this->post_type, array( $this, 'after_save_all' ), 6 );
				self::$hook_after_save_all[] = $this->post_type;
			}

		}

			/**
			 * Run cx_post_meta/after_save hook after save all quick edit boxes to better compatibility with Cherry_X_Post_Meta
			 *
			 * @return void
			 */
			public function after_save_all() {
				// phpcs:disable WordPress.Security.NonceVerification
				$post_id = isset( $_REQUEST['post_ID'] ) ? absint( wp_unslash( $_REQUEST['post_ID'] ) ) : false;
				do_action( 'cx_post_meta/after_save', $post_id, get_post( $post_id ) );
				// phpcs:enable WordPress.Security.NonceVerification
			}

		/**
		 * Post type slug current field is related to
		 *
		 * @return string
		 */
		public function get_post_type() {
			return $this->post_type;
		}

		/**
		 * Save field on quick edit update call
		 *
		 * @return null
		 */
		public function save_field() {
			// phpcs:disable WordPress.Security.NonceVerification
			if ( empty( $_REQUEST['post_type'] ) || $this->get_post_type() !== $_REQUEST['post_type'] ) {
				return;
			}

			$quick_edit_raw = isset( $_REQUEST['jet_engine_quick_edit'] ) ? wp_unslash( $_REQUEST['jet_engine_quick_edit'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- sanitized below
			$quick_edit     = is_array( $quick_edit_raw ) ? array_map( 'sanitize_text_field', $quick_edit_raw ) : array();

			if ( empty( $quick_edit ) || ! is_array( $quick_edit ) || ! in_array( $this->get_trigger_col(), $quick_edit ) ) {
				return;
			}

			$post_id = isset( $_REQUEST['post_ID'] ) ? absint( wp_unslash( $_REQUEST['post_ID'] ) ) : false;

			if ( ! $post_id || ! current_user_can( 'edit_post', $post_id ) ) {
				return;
			}

			$post_meta = new Cherry_X_Post_Meta();
			$post_meta->args = array(
				'fields' => array(
					$this->get_field( 'name' ) => $this->get_field(),
				)
			);

			if ( 'checkbox' === $this->get_field( 'type' ) ) {

				$field_name = $this->get_field( 'name' );

				$raw_value = isset( $_POST[ $field_name ] ) ? wp_unslash( $_POST[ $field_name ] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- sanitized below
				$value     = is_array( $raw_value )
					? array_map( 'sanitize_text_field', $raw_value )
					: sanitize_text_field( $raw_value );

				if ( ! is_array( $value ) ) {
					$value = array();
				}

				update_post_meta( $post_id, $field_name, $value );

				// save custom support
				if ( ! empty( $value ) ) {
					$_POST[ $field_name ] = array();
					foreach ( $value as $val ) {
						$_POST[ $field_name ][ $val ] = true;
					}
				}

			} else {
				$post_meta->save_meta_option( $post_id );
			}
			// phpcs:enable WordPress.Security.NonceVerification
		}

		/**
		 * Get current field data or spicified argument
		 *
		 * @param  [type] $key [description]
		 * @return [type]      [description]
		 */
		public function get_field( $key = null ) {

			$field = $this->field;

			if ( ! $key ) {
				return $field;
			} else {
				return isset( $field[ $key ] ) ? $field[ $key ] : null;
			}

		}

		/**
		 * Set field arg
		 *
		 * @param [type] $key   [description]
		 * @param [type] $value [description]
		 */
		public function set_field( $key, $value ) {
			$this->field[ $key ] = $value;
		}

		/**
		 * Get column name related to current field
		 *
		 * @return [type] [description]
		 */
		public function get_trigger_col() {
			return $this->trigger_col . '_' . $this->get_post_type() . '_' . $this->get_field( 'name' );
		}

		/**
		 * Hide column related to current field
		 *
		 * @param  [type] $hidden [description]
		 * @param  [type] $screen [description]
		 * @return [type]         [description]
		 */
		public function hide_quick_edit_trigger( $hidden, $screen ) {

			if ( 'edit' === $screen->base && $this->get_post_type() !== $screen->post_type ) {
				return $hidden;
			}

			if ( ! in_array( $this->get_trigger_col(), $hidden ) ) {
				$hidden[] = $this->get_trigger_col();
			}

			return $hidden;

		}

		/**
		 * Print current field value into prepared column
		 *
		 * @param [type] $column  [description]
		 * @param [type] $post_id [description]
		 */
		public function set_column_value( $column, $post_id ) {

			if ( $column !== $this->get_trigger_col() ) {
				return;
			}

			$post      = get_post( $post_id );
			$post_meta = new Cherry_X_Post_Meta();
			$default   = $this->get_field( 'value' );
			$value     = $post_meta->get_meta( $post, $this->get_field( 'name' ), $default, $this->get_field() );

			if ( 'select' === $this->get_field( 'type' ) && $this->get_field( 'multiple' ) && ! is_array( $value ) ) {
				$value = array( $value );
			} elseif ( 'select' === $this->get_field( 'type' ) && ! $this->get_field( 'multiple' ) && is_array( $value ) ) {
				$value = $value[0];
			}

			if ( 'radio' === $this->get_field( 'type' ) ) {
				$this->set_field( 'value', '' );
			}

			if ( 'checkbox' === $this->get_field( 'type' ) ) {
				$this->set_field( 'type', 'checkbox-raw' );
				$this->set_field( 'value', array() );
				$this->set_field( 'required', false );
			}

			if ( 'text' === $this->get_field( 'type' ) && ! empty( $value )
				 && $post_meta->to_timestamp( $this->get_field() ) && is_numeric( $value )
			) {

				switch ( $this->get_field( 'input_type' ) ) {
					case 'date':
						$value = jet_engine_date( 'Y-m-d', $value );
						break;

					case 'datetime-local':
						$value = jet_engine_date( 'Y-m-d\TH:i', $value );
						break;
				}
			}

			printf(
				'<div data-jet-engine-quick-edit-val="%1$s" data-jet-engine-quick-edit-type="%3$s">%2$s</div>',
				esc_attr( $this->get_field( 'name' ) ),
				esc_html( wp_json_encode( $value ) ),
				esc_attr( $this->get_field( 'type' ) )
			);
		}

		/**
		 * Register related columne for current field
		 *
		 * @param  [type] $columns [description]
		 * @return [type]          [description]
		 */
		public function register_quick_edit_trigger( $columns ) {

			$columns = array_merge(
				array( $this->get_trigger_col() => '' ),
				$columns
			);

			return $columns;

		}

		/**
		 * Render field related control into quick edit section
		 *
		 * @param  [type] $column    [description]
		 * @param  [type] $post_type [description]
		 * @return [type]            [description]
		 */
		public function render_control( $column, $post_type ) {

			if ( $post_type !== $this->get_post_type() || $column !== $this->get_trigger_col() ) {
				return;
			}

			$field = $this->get_field();

			$builder_data = jet_engine()->framework->get_included_module_data( 'cherry-x-interface-builder.php' );
			$builder      = new CX_Interface_Builder(
				array(
					'path' => $builder_data['path'],
					'url'  => $builder_data['url'],
				)
			);

			$field['id'] = $field['name'];

			if ( self::$is_first ) {
				self::$is_first = false;
				echo '<div class="cx-ui-clear"></div>';
			}
			
			//https://github.com/Crocoblock/issues-tracker/issues/10492
			//actual value is set in includes/components/meta-boxes/assets/js/inline-quick-edit.js inlineEditPost.edit
			unset( $field['value'] );
			
			$builder->register_control( $field );
			$control_html = $builder->render( false );

			$replace_map_attrs = array(
				'data-required=' => 'required=',
				'data-min='      => 'min=',
				'data-max='      => 'max=',
				'data-step='     => 'step=',
			);

			$control_html = str_replace( array_keys( $replace_map_attrs ), array_values( $replace_map_attrs ), $control_html );

			// Output is safe, generated by plugin logic, not user input.
			// Markup is required for rendering custom fields in Quick Edit.
			echo $control_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

			printf( '<input type="hidden" name="jet_engine_quick_edit[]" value="%s">', esc_attr( $this->get_trigger_col() ) );

			if ( false === self::$add_inline_css ) {

				self::$add_inline_css = true;
				echo '<style>
					.inline-edit-row .cx-ui-clear {
						clear: both;
						padding: 15px 0 0 0;
					}
					
					.inline-edit-row .cx-control {
						display: inline-block;
						vertical-align: top;
						padding: 12px 12px 12px 0;
						width: calc(25% - 4px);
						box-sizing: border-box;
					}
					
					.inline-edit-row .cx-ui-kit__name,
					.inline-edit-row .cx-ui-kit__description {
						font-size: 12px;
						font-style: italic;
						opacity: .7;
					}
					
					.inline-edit-row .cx-ui-container,
					.inline-edit-row .cx-ui-kit__name {
						margin-bottom: 4px;
					}
					
					.inline-edit-row .cx-ui-stepper-input {
						width: 100%;
					}
					
					.inline-edit-row .cx-control select[multiple] {
						height: 120px;
					}
					
					.inline-edit-row .cx-control__required {
						color: #e54343;
					}
				</style>';

				ob_start();
				include jet_engine()->meta_boxes->component_path( 'assets/js/inline-quick-edit.js' );
				wp_add_inline_script( 'inline-edit-post', ob_get_clean() );

			}

		}

	}

}
