<?php
/**
 * Collection item class.
 *
 * @package SaveToWishlist\Classes\Factories
 * @since 1.0.0
 */
namespace SaveToWishlist\Classes\Factories;

use SaveToWishlist\Abstracts\Singleton;
use SaveToWishlist\Helpers\Helper_Functions;

/**
 * Class Collection_Item
 *
 * This class creates an instance of a collection item.
 *
 * @since 1.0.0
 */
class Collection_Item extends Singleton {

    /**
     * Item ID.
     *
     * @var int
     */
    public $id;

    /**
     * Item collection ID.
     *
     * @var int
     */
    public $collection_id;

    /**
     * Item product ID.
     *
     * @var string
     */
    public $product_id;

    /**
     * Item variant ID.
     *
     * @var string
     */
    public $variant_id;

    /**
     * Item quantity.
     *
     * @var string
     */
    public $quantity;

    /**
     * Item priority.
     *
     * @var string
     */
    public $priority;

    /**
     * Item notes.
     *
     * @var string
     */
    public $notes;

    /**
     * Item product object.
     *
     * @var WC_Product|null
     */
    public $product;

    /**
     * Item date added.
     *
     * @var string
     */
    public $date_added;

    /**
     * Item sort order.
     *
     * @var int
     */
    public $sort_order;

    /**
     * Helper functions.
     *
     * @var Helper_Functions
     */
    private $helper_functions;

    /**
     * Constructor.
     *
     * @param object $item Item.
     *
     * @since 1.0.0
     */
    public function __construct( $item ) {
        $this->helper_functions = Helper_Functions::instance();

        $this->id            = $item->id ?? 0;
        $this->collection_id = $item->collection_id ?? 0;
        $this->product_id    = $item->product_id ?? 0;
        $this->variant_id    = $item->variation_id ?? 0;
        $this->quantity      = $item->quantity ?? 0;
        $this->priority      = $item->priority ?? 0;
        $this->notes         = $item->notes ?? '';
        $this->product       = $this->_get_product_object( $this->product_id );
        $this->date_added    = $item->added_at ?? '';
        $this->sort_order    = $item->sort_order ?? 0;
    }

    /**
     * Get an instance of a collection item.
     *
     * @param object $item Item.
     *
     * @since 1.0.0
     * @access public
     *
     * @return Collection_Item
     */
    public static function get_instance( $item ) {
        return new self( $item );
    }

    /**
     * Get the item product object.
     *
     * @param int $item_product_id Item product ID.
     *
     * @since 1.0.0
     * @access private
     *
     * @return WC_Product|null
     */
    private function _get_product_object( $item_product_id ) {
        if ( ! $item_product_id ) {
            return null;
        }

        $item_product_id    = (int) $item_product_id;
        $product_object     = wc_get_product( $item_product_id );
        $product_variations = array();

        if ( ! $product_object || ! $product_object->exists() ) {
            return null;
        }

        // check if product is variable.
        if ( $product_object->is_type( 'variable' ) ) {
            $product_variations = $this->_get_variation_options( $product_object );
        }

        $image_id  = $product_object->get_image_id();
        $image_url = $image_id ? wp_get_attachment_image_url( $image_id, 'woocommerce_thumbnail' ) : wc_placeholder_img_src( 'woocommerce_thumbnail' );

        $product = array(
            'id'              => $product_object->get_id(),
            'name'            => $product_object->get_name(),
            'price'           => $product_object->get_price(),
            'price_formatted' => $product_object->get_price_html(),
            'image'           => $product_object->get_image(),
            'image_url'       => $image_url,
            'link'            => $product_object->get_permalink(),
            'stock'           => $product_object->get_stock_status(),
            'type'            => $product_object->get_type(),
            'sku'             => $product_object->get_sku(),
            'variations'      => $product_variations,
        );

        // Filter the product.
        $product = apply_filters( 'stwlite_collection_item_product_data', $product, $item_product_id );

        return $product;
    }

    /**
     * Get the variation options.
     *
     * @param WC_Product $product Product object.
     *
     * @since 1.0.0
     * @access private
     *
     * @return array
     */
    private function _get_variation_options( $product ) {
        if ( $product->is_type( 'variable' ) ) {

            // Get all available attribute options for the variable product.
            $available_attributes = array();
            $attribute_labels     = array();
            $attributes           = $product->get_variation_attributes();
            foreach ( $attributes as $attribute_name => $options ) {
                $attribute_key                          = strtolower( $attribute_name );
                $available_attributes[ $attribute_key ] = array();
                $attribute_labels[ $attribute_key ]     = wc_attribute_label( $attribute_name, $product );
                foreach ( $options as $option ) {
                    $name = $option;
                    $term = get_term_by( 'slug', $option, $attribute_name );
                    if ( $term ) {
                        $name = $term->name;
                    }

                    $available_attributes[ $attribute_key ][] = array(
                        'slug' => $option,
                        'name' => $name,
                    );
                }
            }

            // Filter the available attributes.
            $available_attributes = apply_filters( 'stwlite_collection_item_available_attributes', $available_attributes, $product );

            // Get the specific combinations for created variations.
            $variations_data = array();
            $variations      = array();
            $variation_ids   = $product->get_children();
            foreach ( $variation_ids as $variation_id ) {
                $variation_obj = wc_get_product( $variation_id );
                if ( $variation_obj && $variation_obj->exists() ) {
                    $variation_data = wc_get_product_variation_attributes( $variation_id );
                    $variations[]   = array_merge(
                        array(
                            'variation_id' => $variation_id,
                            'stock'        => $variation_obj->get_stock_status(),
                            'price'        => $variation_obj->get_price(),
                            'attributes'   => $variation_data,
                        ),
                        $variation_obj->get_data()
                    );
                }
            }

            // Filter the variations.
            $variations = apply_filters( 'stwlite_collection_item_variations', $variations, $product );

            foreach ( $variations as $variation ) {
                if ( isset( $variation['variation_id'] ) ) {
                    $variation_image_id  = isset( $variation['image_id'] ) ? (int) $variation['image_id'] : 0;
                    $variation_image_url = $variation_image_id ? wp_get_attachment_image_url( $variation_image_id, 'woocommerce_thumbnail' ) : '';

                    $variation_info = array(
                        'variation_id' => $variation['variation_id'],
                        'stock'        => $variation['stock'],
                        'price'        => $variation['price'],
                        'image_url'    => $variation_image_url,
                        'attributes'   => array(),
                    );

                    if ( isset( $variation['attributes'] ) && is_array( $variation['attributes'] ) ) {
                        foreach ( $variation['attributes'] as $key => $value ) {
                            $taxonomy                             = str_replace( 'attribute_', '', $key );
                            $term                                 = get_term_by( 'slug', $value, $taxonomy );
                            $variation_info['attributes'][ $key ] = $term ? $term->name : $value;
                        }
                    }
                    $variations_data[] = $variation_info;
                }
            }

            // Filter the variations data.
            $variations_data = apply_filters( 'stwlite_collection_item_variations_data', $variations_data, $product );

            return array(
                'attributes'       => $available_attributes,
                'attribute_labels' => $attribute_labels,
                'variations'       => $variations_data,
            );
        }

        return array();
    }
}
