<?php
/**
 * File responsible for defining helper methods for creating print templates.
 *
 * Author:          Uriahs Victor
 * Created on:      06/08/2023 (d/m/y)
 *
 * @link    https://uriahsvictor.com
 * @since   1.1.4
 * @package package
 */

namespace Printus\Helpers;

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

use Printus\Compatibility\ProductAddonPlugins as ProductAddonPluginsCompatibility;
use Printus\Models\PluginSettings\LocalizationSettingsModel;
use Printus\Models\PluginSettings\TemplateSettingsModel;
use Printus\Models\PluginSettings\ToolsSettingsModel;
use WC_Order;
use WC_Order_Item;

/**
 * Helper Template Class.
 *
 * Helper methods for template creation.
 *
 * @package Printus\Helpers
 * @since 1.1.4
 */
class Template {

	/**
	 * Create table headings.
	 *
	 * @param array $headings The table headings.
	 * @param array $colspans Colspans that should be applied on Headings if any.
	 * @return string
	 * @since 1.1.0
	 */
	public static function createHeadings( array $headings, array $colspans = array() ): string {
		$table_headings = array();

		foreach ( $headings as $heading ) {
			$localized_heading = LocalizationSettingsModel::getLocalizationStringSetting( $heading );
			/**
			 * If no localization translation if found for the heading column then leave heading as.
			 * This would most commonly happen in custom templates when creating custom columns.
			 */
			$table_headings[] = $localized_heading ?: $heading;
		}

		$heading_colspans = array();
		foreach ( $colspans as $column_name => $colspan_value ) {
			$localized_column_name                      = LocalizationSettingsModel::getLocalizationStringSetting( $column_name );
			$heading_colspans[ $localized_column_name ] = $colspan_value;
		}

		$table_headings_str = '';
		foreach ( $table_headings as $key => $heading ) {
			$colspan = $heading_colspans[ $heading ] ?? 1;
			if ( 0 === $key ) {
				$table_headings_str .= "<th class='text-left text-top heading' colspan='$colspan'>" . $heading . '</th>';
			} else {
				$table_headings_str .= "<th class='text-center text-top heading' colspan='$colspan'>" . $heading . '</th>';
			}
		}

		return $table_headings_str;
	}

	/**
	 * Generate the variations to add to the list item on the template.
	 *
	 * @param WC_Order_Item $item
	 *
	 * @return string
	 * @since 1.2.7
	 */
	public static function generateItemVariations( WC_Order_Item $item ): string {

		$wc_variations = '';

		if ( ToolsSettingsModel::applyAttributesFix() === false ) {

			if ( $item instanceof \WC_Order_Item_Product ) {
				$variation_id = $item->get_variation_id();
				if ( $variation_id ) {

					$variation = wc_get_product( $variation_id );

					if ( $variation && $variation->is_type( 'variation' ) ) {

						$variation_data = $variation->get_attributes();

						foreach ( $variation_data as $taxonomy_name => $taxonomy_slug ) {
							$taxonomy = get_term_by( 'slug', $taxonomy_slug, $taxonomy_name );
							// Fall back to the taxonomy slug because sometimes $taxonomy is empty.
							// Such as cases where the attribute is on the product edit screen but not in the WC attributes screen.
							$attribute_value = $taxonomy->name ?? $taxonomy_slug;
							$attribute_name  = ucfirst( wc_attribute_label( $taxonomy_name ) );
							$wc_variations  .= '<strong>' . $attribute_name . ':</strong> ' . $attribute_value . '<br/>';
						}
					}
				}
			} else {
				return '';
			}
		} else {

			// Get variation data from the order item.
			$variation_data = $item->get_all_formatted_meta_data();

			// Format variations properly.
			foreach ( $variation_data as $meta ) {
				$wc_variations .= '<strong>' . $meta->display_key . ':</strong> ' . strip_tags( $meta->display_value ) . '<br/>';
			}
		}

		if ( empty( $wc_variations ) ) {
			return '';
		}

		return '<div style="margin-left: 8px; margin-top: 10px">' . $wc_variations . '</div>';
	}

	/**
	 * Format the item addons to be appended onto the item name.
	 *
	 * @param WC_Order_Item $item
	 * @param WC_Order      $order
	 * @return string
	 * @since 1.1.10
	 */
	public static function generateItemAddons( WC_Order_Item $item, WC_Order $order ): string {

		$order_id            = $order->get_id();
		$product_addon_class = ( new ProductAddonPluginsCompatibility() )->getCustomProductAddonsHelperClass();

		$addon_variations = '';
		if ( ! is_null( $product_addon_class ) ) {
			// Product Addon variations.
			$addon_variations = $product_addon_class::addProductOptions( $order_id, $item ) ?: '';
		}

		if ( empty( $addon_variations ) ) {
			return '';
		}

		return '<div style="margin-left: 8px; margin-top: 10px">' . $addon_variations . '</div>';
	}

	/**
	 * Create rows given a list of columns.
	 *
	 * @param WC_Order $order The WooCommerce Order.
	 * @param array    $columns The array of columns to create rows for.
	 * @param array    $rows_colspans Colspan that should be applied to the row cell if any.
	 * @return string
	 * @since 1.1.0
	 */
	public static function createRows( WC_Order $order, array $columns, array $rows_colspans = array() ): string {

		$table_rows = array();

		$show_currency_symbol         = TemplateSettingsModel::getCurrencySymbolSetting();
		$include_tax_in_product_price = TemplateSettingsModel::getTaxInProductPriceSetting();

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

			$table_rows[] = '<tr>';

			if ( $item instanceof \WC_Order_Item_Product ) {

				$variation_id = $item->get_variation_id();
				$product      = $item->get_product();

				if ( $variation_id ) {
					$parent_id      = $product->get_parent_id();
					$parent_product = wc_get_product( $parent_id );
					$product_name   = $parent_product ? $parent_product->get_name() : $product->get_name();
				} else {
					$product_name = $product->get_name();
				}
			} else {
				$product_name = $item->get_name();
			}

			$filtered_ordered_item = apply_filters( 'printus_template__order_item', '', $item, $order );

			$ordered_item = $product_name . $filtered_ordered_item;

			$include_formatted_variation = apply_filters( 'printus_include_formatted_variation', true );
			if ( $include_formatted_variation === true ) {
				$ordered_item = $ordered_item . self::generateItemVariations( $item );
			}

			// Only add addons if attributes fix is not enabled. To prevent duplicate addons.
			if ( ToolsSettingsModel::applyAttributesFix() === false ) {
				$ordered_item = $ordered_item . self::generateItemAddons( $item, $order );
			}

			$ordered_item = apply_filters( 'printus_template__final_order_item', $ordered_item, $item, $order );

			$price    = apply_filters( 'printus_template__item_price', $order->get_item_subtotal( $item, $include_tax_in_product_price ), $item, $order );
			$item_qty = (int) apply_filters( 'printus_template__item_qty', $item->get_quantity(), $item, $order );
			$total    = apply_filters( 'printus_template__item_total', $price * $item_qty, $item, $order );

			foreach ( $columns as $row_item ) {

				$colspan = $rows_colspans[ $row_item ] ?? 1;

				if ( 'item-text' === $row_item ) {
					$table_rows[] = "<td class='text-left text-top item-name' style='word-wrap: break-word' colspan='$colspan'>" . $ordered_item . '</td>';
				}

				if ( 'price-text' === $row_item ) {
					$item_price   = wc_price( $price, array( 'currency' => $show_currency_symbol ) );
					$table_rows[] = "<td class='text-center text-top item-price' colspan='$colspan'>" . $item_price . '</td>';
				}

				if ( 'qty-text' === $row_item ) {
					$table_rows[] = "<td class='text-top item-quantity' colspan='$colspan'>" . $item_qty . '</td>';
				}

				if ( 'total-text' === $row_item ) {
					$item_total   = wc_price( $total, array( 'currency' => $show_currency_symbol ) );
					$table_rows[] = "<td class='text-center text-top item-total' colspan='$colspan'>" . $item_total . '</td>';
				}

				$table_rows = apply_filters( 'printus_template__rows', $table_rows, $row_item, $item, $order );
			}

			$table_rows[] = '</tr>';
		}

		return implode( '', $table_rows );
	}
}
