<?php

/**
 * The file that defines the plugin woocommerce order class
 *
 * @link       https://wpconfiguratorbuilder.com
 * @since      1.0.0
 *
 * @package    wcb-configurator-builder
 * @subpackage wcb-configurator-builder/includes/woocommerce
 */

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

/**
 * The plugin woocommerce order class.
 *
 * @since      1.0.0
 * @package    wcb-configurator-builder
 * @subpackage wcb-configurator-builder/includes/woocommerce
 * @author     WPCB <support@wpconfiguratorbuilder.com>
 */

class WPCB_Order {

	public function __construct() {
		add_action( 'woocommerce_checkout_create_order_line_item', array( $this, 'wpcb_save_order_meta' ), 20, 4 );
		add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'wpcb_update_order_meta' ), 20, 1 );

		add_filter( 'woocommerce_cart_item_name', array( $this, 'display_product_image_in_checkout' ), 20, 3 );
		add_filter( 'woocommerce_order_item_name', array( $this, 'display_product_image_in_order_details' ), 20, 3 );
		add_filter( 'woocommerce_email_order_items_args', array( $this, 'display_product_image_in_woocommerce_mails' ) );
		add_filter( 'woocommerce_order_item_thumbnail', array( $this, 'replace_product_image_in_order_emails' ), 20, 2 );

		add_filter( 'woocommerce_admin_order_item_thumbnail',array( $this, 'display_admin_order_item_thumbnail' ), 10, 3 );
		add_filter( 'woocommerce_hidden_order_itemmeta',array( $this, 'hide_private_order_itemmeta' ), 10, 1 );

		// add_filter( 'woocommerce_email_attachments', array( $this, 'add_order_item_attachments_to_email' ), 10, 3 );
	}

	/**
	 * Hide order item meta from admin view
	 * 
	 * @since    1.0.0
	 */
	public function hide_private_order_itemmeta( $keys ) {
		$keys[] = '_wpcb_option_ids';
		$keys[] = '_wpcb_option_skus';
		$keys[] = '_wpcb_filename';
		$keys[] = '_wpcb_product_image';
		$keys[] = '_wpcb_cart_meta';
		$keys[] = '_wpcb_id';

		$keys = apply_filters( 'wpcb_hide_order_item_meta', $keys );

		return $keys;
	}

	/**
	 * Add custom items to order item meta for permanent access.
	 *
	 * @since    1.0.0
	 */
	public function wpcb_save_order_meta( $order_item, $cart_item_key, $cart_item, $order ) {
		$save_option_sku = wpcb_get_option( 'wpcb_order_save_attribute_skus' );
		$save_option_pdf = wpcb_get_option( 'wpcb_order_save_pdf_attachment' );

		// Start collecting meta data
		$cart_meta = array(
			'cart_item_key' => $cart_item_key,
		);

		if ( $save_option_pdf && class_exists( 'WPCB_PDF' ) ) {
			/**
			 * Collect PDF data
			 */
			$pdf_data = array(
				'cart_item_key' => $cart_item_key,
				'configuration' => $cart_item['wpcb_product_selections'],
				'product_image' => $cart_item['wpcb_product_image'],
				'product_price' => $cart_item['wpcb_product_price'],
			);
			$order_item->update_meta_data( '_wpcb_pdf_data', $pdf_data );
		}

		if ( isset( $cart_item['wpcb_product_selections'] ) && is_array( $cart_item['wpcb_product_selections'] ) ) {
			$cart_meta['wpcb_product_selections'] = $cart_item['wpcb_product_selections']; // save for reorder

			$choice_item_ids  = array();
			$choice_item_skus = array();

			foreach ( $cart_item['wpcb_product_selections'] as $selection ) {
				if ( isset( $selection['values'] ) && is_array( $selection['values'] ) && count( $selection['values'] ) > 0 && array_key_exists( 'values', $selection['values'][0] ) ) {
					$sub_labels = [];

					foreach ( $selection['values'] as $sub_values ) {
						if ( isset( $sub_values['id'] ) ) {
							$sub_value_id = explode('-', $sub_values['id'])[0];
							$item_ids = array_map(function($sub_value) {
								if ( ! isset( $sub_value['id'] ) ) {
									return;
								}
								$parts = explode('-', $sub_value['id']);
								unset( $parts[ count( $parts ) - 1] ); // unset last item
								$sub_value_id = implode('-', $parts);
								if ( ! str_contains( $sub_value_id, '-' ) ) {
									$sub_value_id .= '-0';
								}
								return $sub_value_id;
							}, $sub_values['values'] );

							if ( ! isset( $choice_item_ids[ $sub_value_id ] ) ) {
								$choice_item_ids[ $sub_value_id ] = array();
							}
							$choice_item_ids[ $sub_value_id ] = array_merge( $choice_item_ids[ $sub_value_id ], $item_ids );
						}

						if ( isset( $sub_values['sku'] ) && $save_option_sku ) {
							$item_skus = array_map(function($sub_value) {
								return $sub_value['sku'];
							}, $sub_values['values'] );

							if ( ! isset( $choice_item_skus[ $sub_values['sku'] ] ) ) {
								$choice_item_skus[ $sub_values['sku'] ] = array();
							}
							$choice_item_skus[ $sub_values['sku'] ] = array_merge( $choice_item_skus[ $sub_values['sku'] ], $item_skus );
						}

						$sub_labels[] = $sub_values['value'];
					}

					$order_item->update_meta_data( $selection['label'], implode( ', ', $sub_labels ) );
				} else if ( isset( $selection['values'] ) && is_array( $selection['values'] ) ) {
					$order_item->update_meta_data( $selection['label'], $selection['value'] );

					if ( isset( $selection['id'] ) ) {
						$choice_item_ids[ $selection['id'] ] = array_map(function($selection_value) {
							if ( ! isset( $selection_value['id'] ) ) {
								return;
							}
							return $selection_value['id'];
						}, $selection['values'] );
					}

					if ( isset( $selection['sku'] ) && $save_option_sku ) {
						$choice_item_skus[ $selection['sku'] ] = array_map(function($selection_value) {
							return $selection_value['sku'];
						}, $selection['values'] );
					}
				}
			}

			if ( count( $choice_item_ids ) > 0 ) {
				$configurator_id = $cart_item['wpcb_configurator_id'];

				// Save configuration item ID's for stock updates.
				$order_item->update_meta_data( '_wpcb_id', $configurator_id );
				$order_item->update_meta_data( '_wpcb_option_ids', serialize( $choice_item_ids ) );
			}

			if ( function_exists( 'wpcb_collect_configuration_item_stats' ) ) {
				wpcb_collect_configuration_item_stats( $configurator_id, $cart_item['wpcb_product_selections'] );
			}

			if ( count( $choice_item_skus ) > 0 ) {
				$order_item->update_meta_data( '_wpcb_option_skus', serialize( $choice_item_skus ) );
			}
		}

		if ( isset( $cart_item['wpcb_filename'] ) ) {
			$cart_meta['wpcb_filename'] = $cart_item['wpcb_filename']; // save for reorder
			$order_item->update_meta_data( '_wpcb_filename', $cart_item['wpcb_filename'] );
		}

		if ( isset( $cart_item['wpcb_product_image'] ) ) {
			$cart_meta['wpcb_product_image'] = $cart_item['wpcb_product_image']; // save for reorder
			$order_item->update_meta_data( '_wpcb_product_image', $cart_item['wpcb_product_image'] );
		}

		if ( isset( $cart_item['wpcb_product_price'] ) ) {
			$cart_meta['wpcb_product_price'] = $cart_item['wpcb_product_price'];
		}

		if ( isset( $cart_item['wpcb_product_tax'] ) ) {
			$cart_meta['wpcb_product_tax'] = $cart_item['wpcb_product_tax'];
		}

		if ( isset( $cart_item['wpcb_product_sku'] ) ) {
			$order_item->update_meta_data( '_sku', $cart_item['wpcb_product_sku'] );
			$cart_meta['wpcb_product_sku'] = $cart_item['wpcb_product_sku'];
		}

		if ( isset( $cart_item['wpcb_product_weight'] ) ) {
			$cart_meta['wpcb_product_weight'] = $cart_item['wpcb_product_weight'];
			$order_item->update_meta_data( '_weight', $cart_item['wpcb_product_weight'] );
		}

		// save for reorder
		$order_item->update_meta_data( '_wpcb_cart_meta', $cart_meta );
	}

	/**
	 * Generate PDFs for order items
	 *
	 * @since    1.0.0
	 */
	public function wpcb_update_order_meta( $order_id ) {
		if ( ! class_exists( 'WPCB_PDF' ) ) {
			return;
		}

		$save_option_pdf = wpcb_get_option( 'wpcb_order_save_pdf_attachment' );
		$pdf_include_id  = wpcb_get_option( 'wpcb_order_pdf_include_order_id' );
		if ( ! $save_option_pdf ) {
			return;
		}

		// Generate PDFs
		$wpcb_pdf = new WPCB_PDF();
		$order    = wc_get_order( $order_id );
		foreach ( $order->get_items() as $order_item ) {
			if ( $order_item->get_meta('_wpcb_pdf_data') ) {
				// collect pdf data
				$pdf_data = $order_item->get_meta('_wpcb_pdf_data');
				if ( $pdf_include_id ) {
					$pdf_data['order_id'] = $order->get_id();
				}

				// Set pdf.
				$pdf_url = $wpcb_pdf->generate_pdf_file_url( $order_item->get_product_id(), $pdf_data, $pdf_data['cart_item_key'] );
				$order_item->update_meta_data( '_wpcb_pdf_url', $pdf_url );
			}
		}

		$order->save();
	}

	/**
	 * Show product image in checkout overview table.
	 *
	 * @since    1.0.0
	 */
	public function display_product_image_in_checkout( $product_name, $cart_item, $cart_item_key ){
		if ( ! is_checkout() ) {
			return $product_name;
		}

		// Check WCB image setting for checkout.
		$display_checkout_images = wpcb_get_option( 'wpcb_checkout_show_image' );
		if ( ! $display_checkout_images ) {
			return $product_name;
		}

		$image_size = $this->get_checkout_image_sizes();
		if ( isset( $cart_item['wpcb_product_image'] ) && '' !== $cart_item['wpcb_product_image'] ) {
			$image_html = '<div class="product-item-thumbnail"><img src="' . $cart_item['wpcb_product_image'] . '" width="' . $image_size[0] . '" height="' . $image_size[1] . '" /></div>';
		} else {
			$thumbnail  = $cart_item['data']->get_image( $image_size );
			$image_html = '<div class="product-item-thumbnail">' . $thumbnail . '</div> ';
		}

		$product_name = $image_html . $product_name;

		return $product_name;
	}

	/**
	 * Show image in order details table.
	 *
	 * @since    1.0.0
	 */
	public function display_product_image_in_order_details( $item_name, $item, $is_visible ) {
		// Targeting view order pages only
		if ( ! is_wc_endpoint_url( 'view-order' ) && ! is_wc_endpoint_url( 'order-received' ) ) {
			return $item_name;
		}

		// Check WCB image setting for order items.
		$display_order_images = wpcb_get_option( 'wpcb_checkout_order_show_image' );
		if ( ! $display_order_images ) {
			return $item_name;
		}

		$thumbnail = $this->get_order_item_product_thumbnail( $item );
		if ( '' == $thumbnail ) {
			$product = $item->get_product();
			$thumbnail = $product->get_image( $this->get_checkout_image_sizes() );
		}

		$item_name = '<div class="item-thumbnail">' . $thumbnail . '</div>' . $item_name;

		return $item_name;
	}

	/**
	 * Show images in woocommerce order email tables.
	 *
	 * @since    1.0.0
	 */
	public function display_product_image_in_woocommerce_mails( $args ) {
		if ( $args['show_image'] ) {
			// Show image already enabled.
			return $args;
		}

		// Check WCB image setting for order items.
		$display_email_images = wpcb_get_option( 'wpcb_checkout_email_show_image' );
		if ( ! $display_email_images ) {
			return $args;
		}

		$args['show_image'] = true;
		$args['image_size'] = $this->get_checkout_image_sizes();

		return $args;
	}

	/**
	 * Show image in customer account order view table.
	 *
	 * @since    1.0.0
	 */
	public function replace_product_image_in_order_emails( $image_html, $item ) {
		// Check WCB image setting for order items.
		$display_email_images = wpcb_get_option( 'wpcb_confirmation_email_display_image' );
		if ( ! $display_email_images ) {
			return $image_html;
		}

		$thumbnail = $this->get_order_item_product_thumbnail( $item );
		if ( '' == $thumbnail ) {
			return $image_html;
		}

		return $thumbnail;
	}

	/**
	 * Display custom thumbnail image in admin order items
	 *
	 * @since    1.0.0
	 */
	public function display_admin_order_item_thumbnail( $image, $item_id, $item ) {
		if ( ! is_object( $item ) ) {
			return $image;
		}

		$html = $this->get_order_item_product_thumbnail( $item );
		if ( ! $html ) {
			return $image;
		}

		return $html;
	}

	/**
	 * Attach order item uploaded images to email
	 *
	 * @since    1.0.0
	 */
	public function add_order_item_attachments_to_email( $attachments, $email_id, $order ) {
		if ( ! is_a( $order, 'WC_Order' ) ) {
			return $attachments;
		}

		$email_ids = array( 'new_order', 'customer_processing_order' );
		if ( ! in_array( $email_id, $email_ids ) ) {
			return $attachments;
		}

		foreach ( $order->get_items() as $item_id => $item ) {
			$urls = wpcb_get_order_item_file_urls( $item );

			if ( count( $urls ) > 0 ) {
				foreach ( $urls as $url ) {
					// Convert URL to absolute path (if needed)
					$url_path = str_replace( content_url(), WP_CONTENT_DIR, $url );

					if ( file_exists( $url_path ) ) {
						$attachments[] = $url_path;
					}
				}
			}
		}

		return $attachments;
	}

	/**
	 * Get custom product thumbnail stored in order item meta.
	 *
	 * @since    1.0.0
	 */
	private function get_order_item_product_thumbnail( $order_item ) {
		$thumbnail_html = '';

		$item_meta = $order_item->get_meta_data();
		if ( is_array( $item_meta ) && count( $item_meta ) > 0 ) {
			$thumbnail_url = '';
			foreach ( $item_meta as $meta_obj ) {
				if ( '_wpcb_product_image' === $meta_obj->key ) {
					$thumbnail_url = $meta_obj->value;
				}
			}

			$thumbnail_path = str_replace( trailingslashit( get_site_url() ), ABSPATH, $thumbnail_url );
			if ( $thumbnail_url && file_exists( $thumbnail_path ) ) {
				$image_size = $this->get_checkout_image_sizes();
				$thumbnail_html = '<img src="' . $thumbnail_url . '" width="' . $image_size[0] . '" height="' . $image_size[1] . '">';
			}
		}

		return $thumbnail_html;
	}

	/**
	 * Get image sizes for checkout tables.
	 *
	 * @since    1.0.0
	 */
	private function get_checkout_image_sizes() {
		$width = 100;
		$height = 100;

		if ( wpcb_get_option( 'wpcb_checkout_image_width' ) ) {
			$width = wpcb_get_option( 'wpcb_checkout_image_width' );
		}

		if ( wpcb_get_option( 'wpcb_checkout_image_height' ) ) {
			$height = wpcb_get_option( 'wpcb_checkout_image_height' );
		}

		return array( $width, $height );
	}
}
