<?php

/**
 * @package     ApproveOrders
 * @since       1.0.4
 */

namespace ApproveOrders;

use ApproveOrders\Settings as AOFWC_Settings;
use ApproveOrders\Traits\Get_Instance;
use ApproveOrders\Rest_API as AOFWC_Rest_API;

class Helper {

	use Get_Instance;

	/**
	 * Get roles
	 *
	 * @since 1.0.4
	 * @return array
	 */
	public function get_roles() {
		global $wp_roles;
		$roles = array();

		foreach ( $wp_roles->roles as $key => $value ) {
			$roles[ $key ] = $value['name'];
		}
		return $roles;
	}

	/**
	 * Get roles
	 *
	 * @since 1.0.4
	 * @return array
	 */
	public function get_roles_list() {
		$roles         = array();
		$wp_user_roles = $this->get_roles();

		if ( ! empty( $wp_user_roles ) ) {
			foreach ( $wp_user_roles as $key => $value ) {
				$roles[] = array(
					'id'   => $key,
					'text' => $value,
				);
			}
		}
		return $roles;
	}

	/**
	 * Get Pages
	 *
	 * @since 1.0.4
	 * @return array
	 */
	public function get_pages() {
		// Get all pages
		$pages = get_pages();

		// Initialize an array to hold page information
		$page_info = array();

		// Loop through each page and extract the required information
		foreach ( $pages as $page ) {
			$page_info[] = array(
				'id'   => $page->ID,
				'text' => get_the_title( $page->ID ), // Page Title
				'url'  => get_permalink( $page->ID ), // Page URL
			);
		}

		return $page_info;
	}

	/**
	 * Get Payment Gateways
	 *
	 * @since 1.0.4
	 * @return array
	 */
	public function get_payment_gateways() {
		// Get available payment gateways
		$available_gateways = WC()->payment_gateways()->get_available_payment_gateways();

		// Initialize an array to hold gateway information
		$gateway_info = array();

		// Loop through each available gateway and extract the required information
		foreach ( $available_gateways as $gateway ) {

			$gateway_info[] = array(
				'id'   => $gateway->id,
				'text' => $gateway->get_method_title(),
			);

		}

		return $gateway_info;
	}

	/**
	 * Search Product
	 *
	 * @since 1.0.4
	 * @return array
	 */
	public static function search_product( $keyword = '', $variations_only = false ) {
		global $wpdb;
		$products = array();

		if ( ! empty( $keyword ) ) {
			// Check if the keyword is an integer (for product ID)
			if ( is_int( $keyword ) || ctype_digit( $keyword ) ) {
				// If it's an ID, filter by ID
				$product_id = intval( $keyword );
				$product    = wc_get_product( $product_id );

				if ( $product ) {
					// If variations_only is true and the product is variable, get variations
					if ( $variations_only && $product->is_type( 'variable' ) ) {
						$variation_ids = $product->get_children(); // Get variation IDs
						foreach ( $variation_ids as $variation_id ) {
							$variation  = wc_get_product( $variation_id );
							$products[] = array(
								'id'        => $variation->get_id(),
								'text'      => $product->get_name() . ' - ' . $variation->get_name(), // Concatenate product name with variation name
								'permalink' => $variation->get_permalink(),
								'price'     => get_post_meta( $variation->get_id(), '_price', true ),
							);
						}
					} else {
						// Add the main product if variations_only is false or product is not variable
						$products[] = array(
							'id'        => $product->get_id(),
							'text'      => $product->get_name(),
							'permalink' => $product->get_permalink(),
							'price'     => get_post_meta( $product->get_id(), '_price', true ),
						);
					}
				}
			} else {
				// If it's a keyword, search by product title
				$keyword = sanitize_text_field( $keyword ) . '%';

				// Custom SQL query to get product IDs based on title
				$product_ids = $wpdb->get_col( // phpcs:ignore
					$wpdb->prepare(
						"
						SELECT ID FROM {$wpdb->prefix}posts 
						WHERE post_type = 'product' 
						AND post_status = 'publish' 
						AND post_title LIKE %s
					",
						$keyword
					)
				);

				// Retrieve product details for each found ID
				foreach ( $product_ids as $id ) {
					$product = wc_get_product( $id );

					// If variations_only is true and the product is variable, get variations
					if ( $variations_only && $product->is_type( 'variable' ) ) {
						$variation_ids = $product->get_children(); // Get variation IDs
						foreach ( $variation_ids as $variation_id ) {
							$variation  = wc_get_product( $variation_id );
							$products[] = array(
								'id'        => $variation->get_id(),
								'text'      => $variation->get_name(),
								'permalink' => $variation->get_permalink(),
								'price'     => get_post_meta( $variation->get_id(), '_price', true ),
							);
						}
					} else {
						// Add the main product if variations_only is false or product is not variable
						$products[] = array(
							'id'        => $product->get_id(),
							'text'      => $product->get_name(),
							'permalink' => $product->get_permalink(),
							'price'     => get_post_meta( $product->get_id(), '_price', true ),
						);
					}
				}
			}
		}

		return $products;
	}

	/**
	 * Search categories
	 *
	 * @since 1.0.4
	 *
	 * @param string $search_term
	 * @param string $post_type
	 * @return array
	 */
	public static function search_categories( $search_term, $post_type = 'post' ) {

		// Get categories that match the search term
		$args = array(
			'taxonomy'   => ( 'product' === $post_type ) ? 'product_cat' : 'category',
			'name__like' => $search_term,
			'hide_empty' => true,
		);

		$categories = get_categories( $args );
		$results    = array();

		// Loop through categories and get posts for the specified post type
		foreach ( $categories as $category ) {
			$results[] = array(
				'id'   => $category->name,
				'text' => $category->name,
			);
		}

		return $results;
	}

	/**
	 * Search tags
	 *
	 * @since 1.0.4
	 *
	 * @param string $search_term
	 * @param string $post_type
	 * @return array
	 */
	public static function search_tags( $search_term, $post_type = 'product' ) {

		// Sanitize the search term
		$search_term = sanitize_text_field( $search_term );

		// Determine the taxonomy based on the post type
		$taxonomy = ( 'product' === $post_type ) ? 'product_tag' : 'post_tag';

		// Get tags that match the search term
		$tags = get_terms(
			array(
				'taxonomy'   => $taxonomy,
				'name__like' => $search_term,
				'hide_empty' => false,
			)
		);

		$results = array();

		if ( ! empty( $tags ) ) {
			foreach ( $tags as $tag ) {
				$results[] = array(
					'id'   => $tag->name,
					'text' => $tag->name,
				);
			}
		}

		return $results;
	}

	/**
	 * Product details
	 *
	 * @since 1.0.4
	 *
	 * @param array $ids
	 * @return array
	 */
	public static function product_details( $ids ) {
		$products = array();
		// Get the product IDs from the request
		$product_ids = $ids;

		// Check if product_ids is provided and is an array
		if ( ! empty( $product_ids ) && is_array( $product_ids ) ) {

			// Loop through each product ID and fetch details
			foreach ( $product_ids as $product_id ) {
				// Get the WooCommerce product object by ID
				$product = wc_get_product( $product_id );

				// Check if product exists
				if ( $product ) {
					// Add product details to the response
					$products[] = array(
						'id'   => $product->get_id(),
						'text' => $product->get_name(),
					);
				}
			}

			return $products;

		}
	}

	/**
	 * Term details
	 *
	 * @since 1.0.4
	 *
	 * @param array  $ids
	 * @param string $taxonomy
	 * @return array
	 */
	public static function term_details( $ids, $taxonomy = 'product_cat' ) {
		$results = array();

		foreach ( $ids as $id ) {
			// Attempt to get term by ID, first as an integer
			$term = '';

			if ( ! $term && is_numeric( $id ) ) {
				$term = get_term( (int) $id, $taxonomy );
			}

			// If not found, try getting by slug (text ID)
			if ( ! $term && is_string( $id ) ) {
				$term = get_term_by( 'name', $id, $taxonomy );
			}

			if ( $term ) {
				$results[] = array(
					'id'   => $term->term_id,
					'text' => $term->name,
				);
			}
		}

		return $results;
	}

	/**
	 * Shorten array
	 *
	 * @since 1.0.4
	 *
	 * @param array  $input_array
	 * @param string $key_field
	 * @param string $value_field
	 * @return array
	 */
	public function shorten( $input_array, $key_field, $value_field ) {
		$shortened_array = array();

		foreach ( $input_array as $item ) {
			if ( isset( $item[ $key_field ] ) && isset( $item[ $value_field ] ) ) {
				$shortened_array[ $item[ $key_field ] ] = $item[ $value_field ];
			}
		}

		return $shortened_array;
	}

	/**
	 * Update order status
	 *
	 * @since 1.0.4
	 *
	 * @param integer $order_id
	 * @param string  $action
	 * @return array
	 */
	public static function update_order_status( $order_id = '', $action = '' ) {

		$statuses = array(
			'approved'          => __( 'Approved', 'approve-orders' ),
			'awaiting-approval' => __( 'Awaiting Approval', 'approve-orders' ),
			'pending'           => __( 'Pending Payment', 'approve-orders' ),
			'rejected'          => __( 'Rejected', 'approve-orders' ),
		);

		if ( ! empty( $order_id ) && ! empty( $action ) && isset( $statuses[ $action ] ) ) {
			$order = wc_get_order( $order_id );

			if ( $order ) {
				$order->update_status( $action, $statuses[ $action ] );
			}
		}

		return;
	}

	/**
	 * Search users
	 *
	 * @since 1.0.4
	 *
	 * @param string $term
	 * @return array
	 */
	public static function search_users( $term, $user_lookup = 0 ) {

		if ( empty( $term ) ) {
			return array();
		}

		$args = array(
			'fields' => array( 'ID', 'display_name', 'user_email' ),
		);

		if ( $user_lookup ) {
			// If user_lookup is true, treat $term as an array of user IDs
			$user_ids        = $term;
			$args['include'] = $user_ids;
		} else {
			// Otherwise, perform a search by term
			$args['search']         = '*' . $term . '*';
			$args['search_columns'] = array( 'user_login', 'user_nicename', 'user_email', 'display_name' );
		}

		// Execute query
		$query = new \WP_User_Query( $args );

		// Fetch users
		$users   = $query->get_results();
		$results = array();

		if ( ! empty( $users ) ) {
			foreach ( $users as $user ) {
				$results[] = array(
					'id'    => $user->ID,
					'text'  => $user->display_name,
					'email' => $user->user_email,
				);
			}
		}

		return $results;
	}

	/**
	 * Get approval rejection URLs
	 *
	 * @since 1.0.4
	 *
	 * @param integer $order_id
	 * @return array
	 */
	public static function get_approval_rejection_urls( $order_id, $is_front = 0 ) {

		$results = array(
			'approve_url' => '#',
			'reject_url'  => '#',
		);

		if ( ! empty( $order_id ) ) {

			$options  = self::get_approval_rejection_statuses();
			$base_url = ( ! $is_front ) ? admin_url( 'admin-ajax.php?delegate=aofwc&action=woocommerce_mark_order_status' ) : wc_get_page_permalink( 'myaccount' ) . 'aofwc-mark/?';

			$approved_status = str_replace( 'wc-', '', isset( $options['approved_status'] ) ? $options['approved_status'] : '' );
			$rejected_status = str_replace( 'wc-', '', isset( $options['rejected_status'] ) ? $options['rejected_status'] : '' );

			$admin_url = $base_url . '&order_id=' . $order_id;

			$approve_url = ( ! $is_front ) ? wp_nonce_url( $admin_url . '&status=' . esc_attr( $approved_status ), 'woocommerce-mark-order-status' ) : esc_url( $admin_url . '&status=' . esc_attr( $approved_status ) );
			$reject_url  = ( ! $is_front ) ? wp_nonce_url( $admin_url . '&status=' . esc_attr( $rejected_status ), 'woocommerce-mark-order-status' ) : esc_url( $admin_url . '&status=' . esc_attr( $rejected_status ) );

			$results = array(
				'approve_url' => $approve_url,
				'reject_url'  => $reject_url,
			);

		}

		return $results;
	}

	/**
	 * Get approval rejection statuses
	 *
	 * @since 1.0.4
	 *
	 * @param string $status
	 * @return array
	 */
	public static function get_approval_rejection_statuses( $status = '' ) {
		// Get saved options
		$settings = AOFWC_Settings::get_instance();
		$options  = $settings->get();

		$approved_status = str_replace( 'wc-', '', isset( $options['approved_status'] ) ? $options['approved_status'] : '' );
		$rejected_status = str_replace( 'wc-', '', isset( $options['rejected_status'] ) ? $options['rejected_status'] : '' );

		if ( empty( $status ) ) {
			return array(
				'approved_status' => $approved_status,
				'rejected_status' => $rejected_status,
			);
		}

		if ( ! empty( $status ) ) {
			if ( isset( $options[ $status ] ) ) {
				return esc_html( $$status );
			}
		}

		return array();
	}
}
