<?php

namespace CustomerJourneyForWooCommerce;

/**
 * Customer Journey backend related functionality.
 *
 * @since 1.0.0
 */
class Backend {

	/**
	 * Primary key.
	 *
	 * @var string
	 */
	public $primary_key = 'order_id';

	/**
	 * Table Name.
	 *
	 * @var string
	 */
	public $table_name;

	/**
	 * Initialize.
	 */
	public function init() {

		// Bail if it's not an admin page.
		if ( ! is_admin() ) {
			return;
		}

		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
		add_action( 'admin_init', array( $this, 'init_metabox' ) );
	}

	/**
	 * Enqueue required CSS for customer journey.
	 *
	 * @return
	 */
	public function enqueue_assets() {

		global $current_screen;

		if ( empty( $current_screen->id ) ) {
			return;
		}

		if ( 'shop_order' === $current_screen->id || 'woocommerce_page_wc-orders' === $current_screen->id ) {
			wp_enqueue_style( 'customer-journey', plugins_url( 'assets/customer-journey.css', CUSTOMER_JOURNEY_FOR_WOOCOMMERCE_PLUGIN_FILE ), false, CUSTOMER_JOURNEY_FOR_WOOCOMMERCE_VERSION );
			wp_enqueue_style( 'font-awesome', plugins_url( 'assets/font-awesome-4.7.0/css/font-awesome.min.css', CUSTOMER_JOURNEY_FOR_WOOCOMMERCE_PLUGIN_FILE ), false, '4.7.0' );
		}
	}

	/**
	 * Initialize metabox.
	 */
	public function init_metabox() {
		add_action( 'add_meta_boxes', array( $this, 'add_metabox' ) );
	}

	/**
	 * Add metabox.
	 */
	public function add_metabox() {
		add_meta_box(
			'customer-journey',
			esc_html__( 'Customer Journey', 'customer-journey' ),
			array( $this, 'render_metabox' ),
			[ 'shop_order', 'woocommerce_page_wc-orders' ]
		);
	}

	/**
	 * Displays the customer journey in this metabox.
	 *
	 * @param  WP_Post $post Post.
	 * @return void.
	 */
	public function render_metabox( $post ) {

		$args     = array( 'order_id' => $post->ID );

		$get_rows = $this->get_rows( $args );

		if ( empty( $get_rows ) ) {
			?><p style="padding:0 10px 10px;"><?php esc_html_e( 'There\'s no customer journey for this order.', 'customer-journey' ); ?></p>
			<?php

			return;
		}

		?>
		<table width="100%" cellspacing="0" cellpadding="0"> 
		
			<?php

			foreach ( $get_rows as $record ) {
				$timestamp = strtotime( $record->date );

				if ( empty( $timestamp_prev ) || ( gmdate( 'd', $timestamp ) !== gmdate( 'd', $timestamp_prev ) ) ) {
					?>
						<tr>
							<td colspan="3" class="date">
								<?php echo esc_html( date_i18n( get_option( 'date_format' ), $timestamp + ( get_option( 'gmt_offset' ) * 3600 ) ) ); ?>
							</td>
						</tr>
					<?php
				}

				$time     = date_i18n( get_option( 'time_format' ), $timestamp + ( get_option( 'gmt_offset' ) * 3600 ) );
				$title    = $record->title;
				$url      = $record->url;
				$path     = str_replace( home_url(), '', $record->url );
				$params   = json_decode( $record->parameters, true );
				$duration = ! empty( $record->duration ) ? human_time_diff( $timestamp - $record->duration, $timestamp ) : 0;
				$status   = 'visit';

				include CUSTOMER_JOURNEY_FOR_WOOCOMMERCE_PLUGIN_PATH . '/templates/metabox.php';

				$timestamp_prev = $timestamp;
			}

				$summary = sprintf(
					/* translators: %1$s - number of steps; %2$s - total time spent. */
					esc_html__( 'Customer took %1$s over %2$s', 'customer-journey' ),
					sprintf(
					/* translators: Total number of steps taken. */
						_n( '%s step', '%s steps', count( $get_rows ), 'customer-journey' ),
						count( $get_rows )
					),
					human_time_diff( strtotime( $get_rows[0]->date ), strtotime( $post->post_date ) )
				);

				$time     = date_i18n( get_option( 'time_format' ), strtotime( $post->post_date ) + ( get_option( 'gmt_offset' ) * 3600 ) );
				$title    = esc_html__( 'Order Completed', 'customer-journey' );
				$path     = $summary;
				$duration = human_time_diff( $timestamp_prev, strtotime( $post->post_date ) );
				$status   = 'ordered';

				include CUSTOMER_JOURNEY_FOR_WOOCOMMERCE_PLUGIN_PATH . '/templates/metabox.php';

		?>
		</table> <!-- End of table >
		<?php
	}

	/**
	 * Get rows from the database.
	 *
	 * @since 1.0.0
	 *
	 * @param array $args  Optional args.
	 * @param bool  $count Flag to return count instead of results.
	 *
	 * @return array|int
	 */
	public function get_rows( $args = array(), $count = false ) {

		global $wpdb;

		$table_name = $wpdb->prefix . 'cjforwoo';


		$this->table_name = $table_name;

		$defaults = array(
			'number'   => 999,
			'offset'   => 0,
			'id'       => 0,
			'order_id' => 0,
			'post_id'  => 0,
			'orderby'  => 'id',
			'order'    => 'ASC',
		);

		$args = wp_parse_args( $args, $defaults );

		if ( $args['number'] < 1 ) {
			$args['number'] = PHP_INT_MAX;
		}

		$where = "WHERE `order_id` IN( {$args['order_id']} )";

		// Orderby.
		$args['orderby'] = ! array_key_exists( $args['orderby'], $this->get_columns() ) ? $this->primary_key : $args['orderby'];

		// Offset.
		$args['offset'] = absint( $args['offset'] );

		// Number.
		$args['number'] = absint( $args['number'] );

		// Order.
		if ( 'ASC' === strtoupper( $args['order'] ) ) {
			$args['order'] = 'ASC';
		} else {
			$args['order'] = 'DESC';
		}

		if ( true === $count ) {

			$results = absint( $wpdb->get_var( "SELECT COUNT({$this->primary_key}) FROM {$this->table_name} {$where};" ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared

		} else {

			$results = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
				"SELECT * FROM {$this->table_name} {$where} ORDER BY {$args['orderby']} {$args['order']} LIMIT {$args['offset']}, {$args['number']};" // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
			);
		}

		return $results;
	}

	/**
	 * Get table columns.
	 *
	 * @since 1.0.0
	 */
	public function get_columns() {

		return array(
			'id'         => '%d',
			'order_id'   => '%d',
			'post_id'    => '%d',
			'url'        => '%s',
			'parameters' => '%s',
			'external'   => '%d',
			'title'      => '%s',
			'duration'   => '%d',
			'step'       => '%d',
			'date'       => '%s',
		);
	}
}