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

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

if ( ! class_exists( 'OrokuBlocks_Woocommerce' ) ) {
  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;
    }
  }
}