<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase, WordPress.Files.FileName.InvalidClassFileName
/**
 * Commissions Table class
 *
 * @author  YITH
 * @package YITH\COG\Classes
 * @version 1.0.0
 */

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

if ( ! class_exists( 'YITH_COG_Stock_Report_Admin_Table' ) ) {
	/**
	 * WooCommerce Commissions Table
	 *
	 * @since 1.0.0
	 */
	class YITH_COG_Stock_Report_Admin_Table extends YITH_COG_Abstract_Admin_Table {

		/**
		 * Class constructor method
		 *
		 * @param array $args Arguments for the parent constructor.
		 * @since 1.0.0
		 */
		public function __construct( $args = array() ) {

			parent::__construct(
				array_merge(
					$args,
					array(
						'singular' => 'stock',
						'plural'   => 'stock',
						'ajax'     => false,
					)
				)
			);
		}

		/**
		 * Prints Export CSV button
		 *
		 * @return void
		 */
		protected function print_export_csv_button() {
			printf(
				'<a href="%s" class="button action primary stock-report-export-csv">%s</a>',
				esc_url(
					add_query_arg(
						array(
							'action' => 'export_stock_report',
							'nonce'  => wp_create_nonce( 'export-stock-report' ),
							'args'   => isset( $_POST ) ? $_POST : array(), // phpcs:ignore WordPress.Security.NonceVerification.Missing
						),
						admin_url( 'edit.php' )
					)
				),
				esc_html_x( 'Export CSV', '[ADMIN] Export CSV button on admin screens', 'yith-cost-of-goods-for-woocommerce' )
			);
		}

		/* === COLUMNS METHODS === */
		/**
		 * Returns columns available in table
		 *
		 * @return array Array of columns of the table
		 * @since 2.0.0
		 */
		public function get_columns() {
			$columns = array(
				'product'          => _x( 'Product', 'yith-cost-of-goods-for-woocommerce' ),
				'quantity'         => _x( 'Qty in stock', '[ADMIN] Sales report heading', 'yith-cost-of-goods-for-woocommerce' ),
				'product_price'    => _x( 'Price', '[ADMIN] Sales report heading', 'yith-cost-of-goods-for-woocommerce' ),
				'total_price'      => _x( 'Total Price', '[ADMIN] Sales report heading', 'yith-cost-of-goods-for-woocommerce' ),
				'product_cost'     => _x( 'Cost', '[ADMIN] Sales report heading', 'yith-cost-of-goods-for-woocommerce' ),
				'cost'             => _x( 'Total Cost', '[ADMIN] Sales report heading', 'yith-cost-of-goods-for-woocommerce' ),
				'potential_profit' => _x( 'Potential Profit', '[ADMIN] Sales report heading', 'yith-cost-of-goods-for-woocommerce' ),
			);

			$custom_columns_options = get_option( 'yith_cog_columns_custom_fields_toggle', array() );

			if ( ! empty( $custom_columns_options ) ) {
				foreach ( $custom_columns_options as $column ) {
					$columns[ $column['cog_custom_column_meta'] ] = $column['cog_custom_column_name'];
				}
			}

			return $columns;
		}

		/**
		 * Column Default
		 *
		 * @param object $item        Product.
		 * @param string $column_name Column name.
		 */
		public function column_default( $item, $column_name ) {
			switch ( $column_name ) {
				case $column_name:
					$meta = get_post_meta( $item->id, $column_name, true );

					if ( ! ! $meta ) {
						echo wp_kses_post( $meta );
					} else {
						echo wp_kses_post( get_post_meta( $item->id, '_' . $column_name, true ) );
					}

					break;
			}
		}

		/**
		 * Print column with product details
		 *
		 * @param object $item Current item row.
		 *
		 * @return string Column content
		 * @since 2.0.0
		 */
		public function column_product( $item ) {

			$product = wc_get_product( $item->id );

			if ( ! $product ) {
				return;
			}

			$column = sprintf( '%s<a href="' . get_edit_post_link( $product->get_id() ) . '">%s</a>', $product->get_image( array( 50, 50 ) ), $product->get_name() );

			return $column;
		}

		/**
		 * Print column with the data of how many this item has being sold
		 *
		 * @param object $item Current item row.
		 *
		 * @return string Column content
		 * @since 2.0.0
		 */
		public function column_quantity( $item ) {

			return $item->stock;
		}

		/**
		 * Print column with the avergare product price
		 *
		 * @param object $item Current item row.
		 *
		 * @return string Column content
		 * @since 2.0.0
		 */
		public function column_product_price( $item ) {

			return yith_cog_price( $item->price );
		}

		/**
		 * Print column with the net sales of each item
		 *
		 * @param object $item Current item row.
		 *
		 * @return string Column content
		 * @since 2.0.0
		 */
		public function column_total_price( $item ) {

			return yith_cog_price( floatval( $item->price ) * $item->stock );
		}

		/**
		 * Print column with the average item cost
		 *
		 * @param object $item Current item row.
		 *
		 * @return string Column content
		 * @since 2.0.0
		 */
		public function column_product_cost( $item ) {

			return yith_cog_price( $item->cost );
		}

		/**
		 * Print column with the cost of each product
		 *
		 * @param object $item Current item row.
		 *
		 * @return string Column content
		 * @since 2.0.0
		 */
		public function column_cost( $item ) {

			return yith_cog_price( floatval( $item->cost ) * $item->stock );
		}

		/**
		 * Print column with margin of each item
		 *
		 * @param object $item Current item row.
		 *
		 * @return string Column content
		 * @since 2.0.0
		 */
		public function column_potential_profit( $item ) {

			return yith_cog_price( $item->product_profit * $item->stock );
		}

		/**
		 * Print filters for current table
		 *
		 * @param string $which Top / Bottom.
		 *
		 * @return void
		 * @since 1.0.0
		 */
		protected function extra_tablenav( $which ) {
			if ( 'top' !== $which ) {
				return;
			}

			$stock       = 0;
			$total_price = 0;
			$total_cost  = 0;
			$profit      = 0;

			$items = $this->total_items;

			foreach ( $items as $item ) {
				$product = wc_get_product( $item->id );

				$product_price      = $product->get_price();
				$product_quantity   = $product->get_stock_quantity();
				$product_cost       = get_cost( $product ) ?? 0;
				$profit_per_product = floatval( $product_price ) - floatval( $product_cost );

				$stock       += $product_quantity;
				$total_price += floatval( $product_price ) * $product_quantity;
				$total_cost  += floatval( $product_cost ) * $product_quantity;
				$profit      += $profit_per_product * $product_quantity;
			}

			$args = array(
				'stock'            => array(
					'label' => _x( 'Stock', '[ADMIN] Header total labels stock report table', 'yith-cost-of-goods-for-woocommerce' ),
					'value' => $stock,
				),
				'total_price'      => array(
					'label' => _x( 'Potential Revenue', '[ADMIN] Header total labels stock report table', 'yith-cost-of-goods-for-woocommerce' ),
					'value' => yith_cog_price( $total_price ),
				),
				'total_cost'       => array(
					'label' => _x( 'Total Cost', '[ADMIN] Header total labels stock report table', 'yith-cost-of-goods-for-woocommerce' ),
					'value' => yith_cog_price( $total_cost ),
				),
				'potential-profit' => array(
					'label' => _x( 'Potential Profit', '[ADMIN] Header total labels stock report table', 'yith-cost-of-goods-for-woocommerce' ),
					'value' => yith_cog_price( $profit ),
				),
			);

			$this->print_totals_section( $args );

			// Options for the select in the report table to sort by them.
			$options = array(
				'product' => _x( 'Name', '[ADMIN] Label of the order by select input', 'yith-cost-of-goods-for-woocommerce' ),
				'stock'   => _x( 'Stock', '[ADMIN] Label of the order by select input', 'yith-cost-of-goods-for-woocommerce' ),
				'price'   => _x( 'Price', '[ADMIN] Label of the order by select input', 'yith-cost-of-goods-for-woocommerce' ),
				'cost'    => _x( 'Cost', '[ADMIN] Label of the order by select input', 'yith-cost-of-goods-for-woocommerce' ),
				'profit'  => _x( 'Potential Profit', '[ADMIN] Label of the order by select input', 'yith-cost-of-goods-for-woocommerce' ),
			);

			?>
				<div class="yith-cog-reports-tablenav">
					<?php
						$this->print_product_filter();
						$this->print_category_filter();
						$this->print_select_orderby( $options );
						$this->print_filter_button();
						$this->print_reset_button();
						$this->print_export_csv_button();
					?>
				</div>
			<?php
		}

		/**
		 * Get items from Query.
		 *
		 * @param int $current_page Current page.
		 * @param int $per_page Items per page.
		 */
		public function get_items( $current_page, $per_page ) {

			global $wpdb;
			$this->items = array();

			$query_from = "FROM {$wpdb->posts} as posts
			INNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id
			INNER JOIN {$wpdb->postmeta} AS postmeta2 ON posts.ID = postmeta2.post_id
			INNER JOIN {$wpdb->postmeta} AS postmeta3 ON posts.ID = postmeta3.post_id
			LEFT JOIN {$wpdb->term_relationships} as tr ON posts.ID = tr.object_id 


			WHERE 1=1
			AND posts.post_type IN ( 'product' , 'product_variation' )
			AND posts.post_status = 'publish'
			AND postmeta.meta_key = '_manage_stock'
			AND postmeta.meta_value = 'yes'
			AND postmeta2.meta_key = '_stock'
			AND postmeta2.meta_value > '0'
			AND postmeta3.meta_key = 'yith_cog_cost'
			AND postmeta3.meta_value > '0'
			";

			if ( isset( $_POST['_product_id'] ) && '' !== $_POST['_product_id'] && isset( $_POST['filter_action'] ) && ! empty( $_POST['filter_action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing

				$product_id  = sanitize_text_field( wp_unslash( $_POST['_product_id'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
				$query_from .= "AND postmeta.post_id = {$product_id} ";
			}

			if ( isset( $_POST['_category_id'] ) && isset( $_POST['filter_action'] ) && ! empty( $_POST['filter_action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
				$categories  = implode( ',', array_map( 'intval', wp_unslash( $_POST['_category_id'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
				$query_from .= "AND tr.term_taxonomy_id IN ( {$categories} ) ";
			}

			$this->total_items = $wpdb->get_results( "SELECT posts.ID as id, posts.post_parent as parent {$query_from} GROUP BY posts.ID ORDER BY postmeta2.meta_value ASC;" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared

			$raw_items = $wpdb->get_results( $wpdb->prepare( "SELECT posts.ID as id, posts.post_parent as parent {$query_from} GROUP BY posts.ID ORDER BY postmeta2.meta_value ASC LIMIT %d, %d;", ( $current_page - 1 ) * $per_page, $per_page ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
			$aux_items = array();

			foreach ( $raw_items as $item ) {
				$product = wc_get_product( $item->id );

				// Saving data within the array.
				$item->product_name   = $product->get_name();
				$item->stock          = $product->get_stock_quantity();
				$item->price          = $product->get_price();
				$item->cost           = get_cost( $product );
				$item->product_profit = floatval( $item->price ) - floatval( $item->cost );

				if ( $product->is_type( 'gift-card' ) ) {
					continue;
				}

//				if ( defined( 'ICL_LANGUAGE_CODE' ) ) {
//
//					$language = apply_filters( 'wpml_post_language_details', '', $product->get_id() );
//
//					if ( ICL_LANGUAGE_CODE !== $language['language_code'] ) {
//						continue;
//					}
//				}

				$aux_items[] = $item;
			}

			$this->items = $aux_items;

			$this->max_items = $wpdb->get_var( "SELECT COUNT( DISTINCT posts.ID ) {$query_from};" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared

			// phpcs:disable WordPress.Security.NonceVerification.Recommended
			// Order by.
			if ( isset( $_REQUEST['cog_orderby'] ) && 'product' === $_REQUEST['cog_orderby'] ) {
				usort(
					$this->items,
					function ( $a, $b ) {
						return strnatcasecmp( $a->product_name, $b->product_name );
					}
				);
			}

			if ( isset( $_REQUEST['cog_orderby'] ) && 'stock' === $_REQUEST['cog_orderby'] ) {
				usort( $this->items, fn( $a, $b ) => $b->stock <=> $a->stock );
			}

			if ( isset( $_REQUEST['cog_orderby'] ) && 'price' === $_REQUEST['cog_orderby'] ) {
				usort( $this->items, fn( $a, $b ) => $b->price <=> $a->price );
			}

			if ( isset( $_REQUEST['cog_orderby'] ) && 'cost' === $_REQUEST['cog_orderby'] ) {
				usort( $this->items, fn( $a, $b ) => $b->cost <=> $a->cost );
			}

			if ( isset( $_REQUEST['cog_orderby'] ) && 'profit' === $_REQUEST['cog_orderby'] ) {
				usort( $this->items, fn( $a, $b ) => $b->product_profit <=> $a->product_profit );
			}
			// phpcs:enable WordPress.Security.NonceVerification.Recommended

			// Add the filters and the blank state when filtering a no search result are retrieved.
			if ( empty( $this->items ) && isset( $_REQUEST['filter_action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended

				$args = array(
					'stock'            => array(
						'label' => _x( 'Stock', '[ADMIN] Header total labels stock report table', 'yith-cost-of-goods-for-woocommerce' ),
						'value' => '-',
					),
					'total_price'      => array(
						'label' => _x( 'Total Price', '[ADMIN] Header total labels stock report table', 'yith-cost-of-goods-for-woocommerce' ),
						'value' => '-',
					),
					'total_cost'       => array(
						'label' => _x( 'Total Cost', '[ADMIN] Header total labels stock report table', 'yith-cost-of-goods-for-woocommerce' ),
						'value' => '-',
					),
					'potential-profit' => array(
						'label' => _x( 'Potential Profit', '[ADMIN] Header total labels stock report table', 'yith-cost-of-goods-for-woocommerce' ),
						'value' => '-',
					),
				);

				$this->print_totals_section( $args );
				// Print filters again to allow to continue filtering when no items were found.
				?>
				<div class="yith-cog-reports-tablenav">
					<?php
					$this->print_product_filter();
					$this->print_category_filter();
					$this->print_filter_button();
					$this->print_reset_button();
					?>
				</div>
				<?php

			}
		}

		/**
		 * Prepare items for table
		 *
		 * @return void
		 * @since 1.0.0
		 */
		public function prepare_items() {
			// sets pagination arguments.
			$per_page     = $this->get_items_per_page( 'yith_cog_products_per_page' );
			$current_page = $this->get_pagenum();

			$this->get_items( $current_page, $per_page );

			// sets columns headers.
			$columns  = $this->get_columns();
			$hidden   = $this->get_hidden_columns();
			$sortable = $this->get_sortable_columns();

			$this->_column_headers = array( $columns, $hidden, $sortable );

			$total_pages = ceil( $this->max_items / $per_page );

			$this->set_pagination_args(
				array(
					'total_items' => $this->max_items,
					'per_page'    => $per_page,
					'total_pages' => $total_pages,
				)
			);
		}
	}
}
