<?php
/**
 * The class manage the post table for our prices rule
 *
 * @package YITH\DynamicPricingAndDiscounts\Classes
 */

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

/**
 * The class that manage the list table
 */
class YWDPD_Rules_Table extends YITH_Post_Type_Admin {
	/**
	 * The post type.
	 *
	 * @var string
	 */
	protected $post_type = 'ywdpd_discount';
	/**
	 * The rule type
	 *
	 * @var array
	 */
	protected $dynamic_rule_type = array();


	public function __construct() {
		parent::__construct();

		add_filter( 'views_edit-ywdpd_discount', array( $this, 'hide_views' ) );
	}

	/**
	 * Add the right column for this post type
	 *
	 * @param array $columns The default columns.
	 *
	 * @return array
	 * @author YITH <plugins@yithemes.com>
	 * @since  1.3.0
	 */
	public function define_columns( $columns ) {
		if ( isset( $columns['title'] ) ) {
			unset( $columns['title'] );
		}
		if ( isset( $columns['date'] ) ) {
			unset( $columns['date'] );
		}

		$custom_columns = array(
			'custom_title'  => __( 'Rule name', 'ywdpd' ),
			'discount_mode' => __( 'Type', 'ywdpd' ),
			'priority'      => __( 'Priority', 'ywdpd' ),
			'status'        => __( 'Status', 'ywdpd' ),
			'enable'        => __( 'Enable', 'ywdpd' ),
			'actions'       => __( 'Actions', 'ywdpd' ),
		);

		return array_merge( $columns, $custom_columns );
	}

	/**
	 * Define bulk actions.
	 *
	 * @param array $actions Existing actions.
	 *
	 * @return array
	 */
	public function define_bulk_actions( $actions ) {
		unset( $actions['trash'] );
		unset( $actions['edit'] );
		$actions['activate']   = __( 'Enable', 'ywdpd' );
		$actions['deactivate'] = __( 'Disable', 'ywdpd' );
		$actions['delete']     = __( 'Delete', 'ywdpd' );

		return $actions;
	}

	/**
	 * Return the sortable column
	 *
	 * @param array $columns The sortable columns.
	 *
	 * @return array
	 * @since  1.3.0
	 */
	public function define_sortable_columns( $columns ) {
		$columns = array(
			'priority' => array( 'priority', true ),
		);

		return $columns;
	}

	/**
	 * Use the post id
	 *
	 * @return bool
	 * @since  1.3.0
	 */
	public function use_object() {
		return false;
	}

	/**
	 * Show the column
	 *
	 * @since  3.0.0
	 */
	public function render_custom_title_column() {
		$post          = get_post( $this->post_id );
		$edit_link     = get_edit_post_link( $this->post_id );
		$can_edit_post = current_user_can( 'edit_post', $post->ID );

		if ( $can_edit_post && 'trash' !== $post->post_status ) {
			$lock_holder = wp_check_post_lock( $post->ID );

			if ( $lock_holder ) {
				$lock_holder   = get_userdata( $lock_holder );
				$locked_avatar = get_avatar( $lock_holder->ID, 18 );
				/* translators: %s: User's display name. */
				$locked_text = esc_html( sprintf( __( '%s is currently editing' ), $lock_holder->display_name ) );
			} else {
				$locked_avatar = '';
				$locked_text   = '';
			}

			echo '<div class="locked-info"><span class="locked-avatar">' . $locked_avatar . '</span> <span class="locked-text">' . $locked_text . "</span></div>\n";  //phpcs:ignore WordPress.Security.EscapeOutput
		}

		echo '<strong>';

		$title = _draft_or_post_title();

		if ( $can_edit_post && 'trash' !== $post->post_status ) {
			printf(
				'<a class="row-title" href="%s" aria-label="%s">%s</a>',
				$edit_link,  //phpcs:ignore WordPress.Security.EscapeOutput
				/* translators: %s: Post title. */
				esc_attr( sprintf( __( '&#8220;%s&#8221; (Edit)' ), $title ) ),
				$title  //phpcs:ignore WordPress.Security.EscapeOutput
			);
		} else {
			printf(
				'<span>%s</span>',
				$title  //phpcs:ignore WordPress.Security.EscapeOutput
			);
		}
		_post_states( $post );

		if ( isset( $parent_name ) ) {
			$post_type_object = get_post_type_object( $post->post_type );
			echo ' | ' . $post_type_object->labels->parent_item_colon . ' ' . esc_html( $parent_name );  //phpcs:ignore WordPress.Security.EscapeOutput
		}

		echo "</strong>\n";

		get_inline_data( $post );
	}

	/**
	 * Show the discount mode
	 *
	 * @since  3.0.0
	 */
	public function render_discount_mode_column() {

		$discount_mode = get_post_meta( $this->post_id, '_discount_mode', true );
		$price_rules   = $this->get_dynamic_rule_types();

		$discount_mode = isset( $price_rules[ $discount_mode ] ) ? $price_rules[ $discount_mode ] : '-';

		echo wp_kses_post( $discount_mode );
	}

	/**
	 * Render the field to toggle status
	 *
	 * @since  3.0.0
	 */
	public function render_enable_column() {

		$status = get_post_meta( $this->post_id, '_active', true );

		$args = array(
			'type'  => 'onoff',
			'class' => 'ywdpd-toggle-enabled',
			'value' => yith_plugin_fw_is_true( $status ) ? 'yes' : 'no',
			'data'  => array(
				'discount-id' => $this->post_id,
				'security'    => wp_create_nonce( 'discount-status-toggle-enabled' ),
			),
		);

		yith_plugin_fw_get_field( $args, true );
	}

	/**
	 * Render priority button
	 *
	 * @since  3.0.0
	 */
	public function render_priority_column() {
		$priority = get_post_meta( $this->post_id, '_priority', true );
		echo wp_kses_post( $priority );

	}


	/**
	 * Render Actions column
	 *
	 * @since  1.3.0
	 */
	protected function render_actions_column() {
		$show_duplicate_link = add_query_arg(
			array(
				'post_type' => $this->post_type,
				'action'    => 'duplicate_discount',
				'post'      => $this->post_id,
			),
			admin_url( 'post.php' )
		);

		$show_duplicate_link = wp_nonce_url( $show_duplicate_link, 'ywdpd-duplicate-rule_' . $this->post_id );
		$extra_action        = array(
			'duplicate-url' => $show_duplicate_link,
		);
		$actions             = yith_plugin_fw_get_default_post_actions( $this->post_id, $extra_action );

		if ( isset( $actions['trash'] ) ) {
			unset( $actions['trash'] );
		}
		$actions['delete']                 = array(
			'type'   => 'action-button',
			'title'  => _x( 'Delete Permanently', 'Post action', 'yith-plugin-fw' ),
			'action' => 'delete',
			'icon'   => 'trash',
			'url'    => get_delete_post_link( $this->post_id, '', true ),
		);
		$actions['delete']['confirm_data'] = array(
			'title'               => __( 'Confirm delete', 'yith-plugin-fw' ),
			// phpcs:ignore  WordPress.WP.I18n.MissingTranslatorsComment
			'message'             => sprintf( __( 'Are you sure you want to delete "%s"?', 'yith-plugin-fw' ), '<strong>' . _draft_or_post_title( $this->post_id ) . '</strong>' ) . '<br /><br />' . __( 'This action cannot be undone and you will not be able to recover this data.', 'yith-plugin-fw' ),
			'cancel-button'       => __( 'No', 'yith-plugin-fw' ),
			'confirm-button'      => _x( 'Yes, delete', 'Delete confirmation action', 'yith-plugin-fw' ),
			'confirm-button-type' => 'delete',
		);

		yith_plugin_fw_get_action_buttons( $actions, true );
	}

	/**
	 * Show the rule status
	 *
	 * @throws Exception The error.
	 */
	protected function render_status_column() {
		$rule = ywdpd_get_rule( $this->post_id );
		echo wp_kses_post( $rule->get_formatted_status() );
	}

	/**
	 * Show the back to wp text
	 *
	 * @return string
	 * @since  1.3-0
	 */
	public function get_back_to_wp_list_text() {
		return __( 'Back to rules', 'ywdpd' );
	}

	/**
	 * Show the filter by discount mode
	 *
	 * @since  3.0.0
	 */
	protected function render_filters() {
		$discount_mode = ! empty( $_REQUEST['discount_mode'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['discount_mode'] ) ) : false; //phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$rule_status   = ! empty( $_REQUEST['rule_status'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['rule_status'] ) ) : false; //phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$price_rules   = $this->get_dynamic_rule_types();
		$rule_type     = array_merge(
			array(
				'' => __( 'Filter by type...', 'ywdpd' ),
			),
			$price_rules,
		);

		yith_plugin_fw_get_field(
			array(
				'type'    => 'select',
				'options' => $rule_type,
				'name'    => 'discount_mode',
				'value'   => $discount_mode,
			),
			true,
			false
		);

		yith_plugin_fw_get_field(
			array(
				'type'    => 'select',
				'options' => array(
					''          => __( 'Filter by status...', 'ywdpd' ),
					'active'    => __( 'Active', 'ywdpd' ),
					'inactive'  => __( 'Inactive', 'ywdpd' ),
					'scheduled' => __( 'Scheduled', 'ywdpd' ),
					'ended'     => __( 'Ended', 'ywdpd' ),
				),
				'name'    => 'rule_status',
				'value'   => $rule_status,
			),
			true,
			false
		);
	}

	/**
	 * Handle any custom filters.
	 *
	 * @param array $query_vars Query vars.
	 *
	 * @return array
	 * @throws Exception The error.
	 */
	protected function query_filters( $query_vars ) {

		$query_vars['post_status'] = 'publish';
		$query_vars                = $this->get_order_query_args( $query_vars );

		$discount_mode_tax_query = $this->get_discount_mode_meta_args();
		$rule_status_tax_query   = $this->get_status_meta_args();

		if ( $discount_mode_tax_query || $rule_status_tax_query ) {
			if ( ! isset( $query_vars['meta_query'] ) ) {
				$query_vars['meta_query'] = array(); // phpcs:ignore WordPress.DB.SlowDBQuery
			}

			if ( $discount_mode_tax_query ) {
				$query_vars['meta_query'] = $discount_mode_tax_query; // phpcs:ignore WordPress.DB.SlowDBQuery
			}

			if ( $rule_status_tax_query ) {
				$query_vars['meta_query'] = array_merge( // phpcs:ignore WordPress.DB.SlowDBQuery
					array(
						'relation' => 'and',
					),
					$query_vars['meta_query'],
					$rule_status_tax_query
				);
			}
		}

		return $query_vars;
	}

	/**
	 * Set in query vars the order query args
	 *
	 * @param array $query_vars The query vars.
	 *
	 * @return array
	 */
	protected function get_order_query_args( $query_vars ) {
		$orderby = isset( $_GET['orderby'] ) ? sanitize_text_field( wp_unslash( $_GET['orderby'] ) ) : 'priority'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$order   = isset( $_GET['order'] ) ? sanitize_text_field( wp_unslash( $_GET['order'] ) ) : 'ASC'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ( 'date_modified' === $orderby ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended

			$query_vars['orderby'] = 'modified';
			$query_vars['order']   = $order;

		} elseif ( 'priority' === $orderby ) {
			$query_vars['orderby']  = 'meta_value_num';
			$query_vars['meta_key'] = '_priority'; // phpcs:ignore WordPress.DB.SlowDBQuery
			$query_vars['order']    = $order;
		}

		return $query_vars;
	}

	/**
	 * Return the meta query for the discount mode
	 *
	 * @return array|array[]
	 * @since 4.0.0
	 */
	protected function get_discount_mode_meta_args() {
		$discount_mode = ! empty( $_REQUEST['discount_mode'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['discount_mode'] ) ) : false; //phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$meta_query    = false;
		if ( $discount_mode ) {
			$meta_query = array( // phpcs:ignore WordPress.DB.SlowDBQuery
				array(
					'key'     => '_discount_mode',
					'value'   => $discount_mode,
					'compare' => '=',
				),
			);
		}

		return $meta_query;
	}

	/**
	 * Return the meta query for the rule status
	 *
	 * @return array|array[]
	 * @throws Exception The error.
	 */
	protected function get_status_meta_args() {
		$rule_status = ! empty( $_REQUEST['rule_status'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['rule_status'] ) ) : false; //phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$tax_query   = false;

		if ( $rule_status ) {
			if ( 'inactive' === $rule_status ) {
				$tax_query = array(
					array(
						'key'   => '_active',
						'value' => 'no',
					),
				);
			} else {
				$active_query = array(
					array(
						'key'   => '_active',
						'value' => 'yes',
					),
				);
				$now          = new DateTime( 'now', new DateTimeZone( wc_timezone_string() ) );
				if ( 'active' === $rule_status ) {
					$tax_query = array(
						array(
							'relation' => 'or',
							array(
								'key'   => '_is_scheduled',
								'value' => 'no',
							),
							array(
								'relation' => 'and',
								array(
									array(
										'key'     => '_schedule_from',
										'compare' => '<=',
										'type'    => 'DATETIME',
										'value'   => $now->format( 'Y-m-d H:i' ),
									),
								),
								array(
									'key'     => '_schedule_to',
									'compare' => '>=',
									'type'    => 'DATETIME',
									'value'   => $now->format( 'Y-m-d H:i' ),
								),
							),
						),
					);
				} elseif ( 'scheduled' === $rule_status ) {
					$tax_query = array(
						array(
							'key'     => '_schedule_from',
							'compare' => '>',
							'type'    => 'DATETIME',
							'value'   => $now->format( 'Y-m-d H:i' ),
						),
					);
				} elseif ( 'ended' === $rule_status ) {
					$tax_query = array(
						array(
							'key'     => '_schedule_to',
							'compare' => '<',
							'type'    => 'DATETIME',
							'value'   => $now->format( 'Y-m-d H:i' ),
						),
					);
				}

				$tax_query             = array_merge(
					$active_query,
					$tax_query
				);
				$tax_query['relation'] = 'and';
			}
		}

		return $tax_query;
	}


	/**
	 * Handle the custom bulk action.
	 *
	 * @param string $redirect_to Redirect URL.
	 * @param string $do_action   Selected bulk action.
	 * @param array  $post_ids    Post ids.
	 *
	 * @return string
	 */
	public function handle_bulk_actions( $redirect_to, $do_action, $post_ids ) {

		if ( 'activate' !== $do_action && 'deactivate' !== $do_action ) {
			return parent::handle_bulk_actions( $redirect_to, $do_action, $post_ids );
		}

		foreach ( $post_ids as $discount_id ) {

			$post_type_object = get_post_type_object( $this->post_type );

			if ( current_user_can( $post_type_object->cap->delete_post, $discount_id ) ) {
				switch ( $do_action ) {
					case 'activate':
						update_post_meta( $discount_id, '_active', 'yes' );
						break;
					case 'deactivate':
						update_post_meta( $discount_id, '_active', 'no' );
						break;
					default:
				}
			}
		}

		return $redirect_to;
	}

	/**
	 * Render blank state. Extend to add content.
	 */
	protected function render_blank_state() {
		parent::render_blank_state();

		echo '<style>.page-title-action{display:none!important;}</style>';
	}

	/**
	 * Retrieve an array of parameters for blank state.
	 *
	 * @return array{
	 * @type string $icon         The YITH icon. You can use this one (to use an YITH icon) or icon_class or icon_url.
	 * @type string $icon_class   The icon class. You can use this one (to use a custom class for your icon) or icon or icon_url.
	 * @type string $icon_url     The icon URL. You can use this one (to specify an icon URL) or icon_icon or icon_class.
	 * @type string $message      The message to be shown.
	 * @type array  $cta          {
	 *                            The call-to-action button params.
	 * @type string $title        The call-to-action button title.
	 * @type string $icon         The call-to-action button icon.
	 * @type string $url          The call-to-action button URL.
	 * @type string $class        The call-to-action button class.
	 *                            }
	 *                            }
	 */
	protected function get_blank_state_params() {
		$submessage = '<p><small>' . esc_html__( 'Create now your first dynamic rule to make your customers happy!', 'ywdpd' ) . '</small></p>';

		return array(
			'icon_url' => YITH_YWDPD_URL . '/assets/icons/price-rule.svg',
			'message'  => __( 'You have no dynamic rule yet.', 'ywdpd' ) . $submessage,
			'cta'      => array(
				'title' => __( 'Create rule', 'ywdpd' ),
				'class' => 'ywdpd_add_new_dynamic_rule yith-plugin-fw__button--add',
			),
		);
	}

	/**
	 * Return all dynamic rules type
	 *
	 * @return array
	 * @since  3.0.0
	 *
	 */
	protected function get_dynamic_rule_types() {

		if ( 0 === count( $this->dynamic_rule_type ) ) {
			$dynamic_rule_types = ywdpd_get_price_rule_type();
			global $wpdb;

			$query = "SELECT COUNT( ID )  
				  FROM {$wpdb->posts} JOIN {$wpdb->postmeta} on {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id 
				  WHERE {$wpdb->postmeta}.meta_key = '%s' AND {$wpdb->postmeta}.meta_value='%s'; 
				";

			$query = $wpdb->prepare( $query, '_discount_mode', 'exclude_items' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared

			$result = $wpdb->get_var( $query ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.NotPrepared

			if ( $result > 0 ) {
				$dynamic_rule_types['exclude_items'] = __( 'Exclude items from rules', 'ywdpd' );
			}
			$this->dynamic_rule_type = $dynamic_rule_types;
		}

		return $this->dynamic_rule_type;
	}

	public function hide_views() {
		return array();
	}


}

return YWDPD_Rules_Table::instance();
