<?php
/**
 * OrokuBlocks - WooCommerce Integration
 * 
 * @package OrokuBlocks
 * @author OrokuBlocks (https://orokublocks.com/)
 * 
 * @since 1.0.0
 * 
 */

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

final class OrokuBlocks_Woocommerce {
  /**
   * Prevent more than one instance from being created
   * 
   * @since 1.0.0
   * 
   * @access private
   */
  private function __construct() {}

  /**
   * Prevent cloning
   * 
   * @since 1.0.0
   * 
   * @access private
   */
  private function __clone() {}

  /**
   * Return product data by id or false if not found.
   * 
   * @since 1.0.0
   * 
   * @param string      $product_id         Product id.
   * @return array|bool $player_data        Product data or false if not found.
   */
  public static function productGet( $product_id ) {
    $product_data = false;

    $wc_product = wc_get_product( $product_id );

    // only get product information if indeed a product type post
    if ( $wc_product ) {
      $product_data = [
        'id'                  => $product_id,
        'name'                => $wc_product->get_name(),
        'type'                => $wc_product->get_type(),
        'description'         => $wc_product->get_description(),
        'short_description'   => $wc_product->get_short_description(),
        'permalink'           => $wc_product->get_permalink(),
        'image_url'           => '',
        'price'               => wc_price( $wc_product->get_price(), [ 'in_span' => false ] ),
        'regular_price'       => wc_price( $wc_product->get_regular_price(), [ 'in_span' => false ] ),
        'sale_price'          => wc_price( $wc_product->get_sale_price(), [ 'in_span' => false ] ),
        'on_sale'             => $wc_product->is_on_sale(),
        'rating_counts'       => $wc_product->get_rating_counts(),
        'average_rating'      => $wc_product->get_average_rating(),
        'review_count'        => $wc_product->get_review_count(),
        'gallery_image_urls'  => [],
        'categories'          => [],
        'attributes'          => []
      ];

      // get product variation price if a variable product
      if ( $product_data['type'] === Automattic\WooCommerce\Enums\ProductType::VARIABLE ) {
        $variation_price_html = $wc_product->get_price_html();

        $product_data['variation_price'] = wp_strip_all_tags( preg_replace( '/<span class="screen-reader-text">.*<\/span>/i', '', $variation_price_html ) );
      }

      // get product main image
      $product_image_id = $wc_product->get_image_id();

      if ( $product_image_id ) {
        $product_data['image_url'] = OrokuBlocks_Blog::thumbnailUrlGet( $product_image_id );
      }

      // get product gallery images
      $product_gallery_image_ids = $wc_product->get_gallery_image_ids();

      foreach ( $product_gallery_image_ids as $gallery_image_id ) {
        $product_data['gallery_image_urls'][$gallery_image_id] = OrokuBlocks_Blog::thumbnailUrlGet( $gallery_image_id );
      }

      // get product categories
      $product_category_ids = $wc_product->get_category_ids();

      foreach ( $product_category_ids as $category_id ) {
        $wp_term = get_term( $category_id );

        if ( $wp_term instanceof WP_Term ) {
          $product_data['categories'][$category_id] = [
            'id'    => $category_id,
            'name'  => $wp_term->name
          ];
        }
      }

      // get product attributes
      $product_attributes = $wc_product->get_attributes();

      foreach ( $product_attributes as $product_attribute_id => $product_attribute ) {
        $product_data['attributes'][$product_attribute_id] = [
          'id'      => $product_attribute_id,
          'name'    => $product_attribute['name'],
          'type'    => 'manual',
          'options' => $product_attribute['options']
        ];

        // if using a taxonomy, have to get its name and each option name (ids are provided as options)
        if ( $product_attribute->is_taxonomy() ) {
          // get real attribute name
          $taxonomy = $product_attribute->get_taxonomy_object();
          $product_data['attributes'][$product_attribute_id]['name'] = $taxonomy->attribute_label;
          $product_data['attributes'][$product_attribute_id]['type'] = $taxonomy->attribute_type;
          $product_data['attributes'][$product_attribute_id]['order'] = [];

          if ( $taxonomy->attribute_type === 'color' ) {
            $product_data['attributes'][$product_attribute_id]['values'] = [];
          }
          
          // get real attribute option names
          $terms = $product_attribute->get_terms();

          foreach ( $product_data['attributes'][$product_attribute_id]['options'] as $option_index => $option_id ) {
            foreach ( $terms as $term ) {
              if ( $term->term_id === $option_id ) {
                $product_data['attributes'][$product_attribute_id]['options'][$option_index] = $term->name;

                $order = get_term_meta( $term->term_id, 'order', true );
                $product_data['attributes'][$product_attribute_id]['order'][$option_index] = $order;
                
                if ( $taxonomy->attribute_type === 'color' ) {
                  $color = get_term_meta( $term->term_id, 'product_attribute_color', true );
                  $product_data['attributes'][$product_attribute_id]['values'][$option_index] = $color;
                }
                break;
              }
            }
          }

          // sort options and values by user selected order
          $sorted_options = [];
          $sorted_values = [];

          $has_values = array_key_exists( 'values', $product_data['attributes'][$product_attribute_id] );
          
          foreach ( $product_data['attributes'][$product_attribute_id]['order'] as $option_id => $order ) {
            $sorted_options[$order - 1] = $product_data['attributes'][$product_attribute_id]['options'][$option_id];

            if ( $has_values ) {
              $sorted_values[$order - 1] = $product_data['attributes'][$product_attribute_id]['values'][$option_id];
            }
          }

          ksort( $sorted_options );

          $product_data['attributes'][$product_attribute_id]['options'] = $sorted_options;

          if ( $has_values ) {
            ksort( $sorted_values );
            $product_data['attributes'][$product_attribute_id]['values'] = $sorted_values;
          }
        }
      }
    }

    return $product_data;
  }
}