<?php

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

if ( ! class_exists( 'WPCleverWoosg_Helper' ) ) {
    return;
}

if ( ! class_exists( 'PWBE_WPC_Grouped_Product' ) ) :

defined( 'PWBE_WPC_GROUPED_PRODUCT_QUANTITY' ) or define( 'PWBE_WPC_GROUPED_PRODUCT_QUANTITY', '0' );

final class PWBE_WPC_Grouped_Product {
    private $meta_key = 'woosg_ids';
    private $all_products = null;
    private $results = array();

    function __construct() {
        add_filter( 'pwbe_product_columns', array( $this, 'pwbe_product_columns' ) );
        add_filter( 'pwbe_results_decode_array', array( $this, 'pwbe_results_decode_array' ), 10, 4 );
        add_filter( 'pwbe_select_options', array( $this, 'pwbe_select_options' ), 11 ); // Priority 11 to run after /plugins/woocommerce-linked-products.php
        add_filter( 'pwbe_before_save_array_value', array( $this, 'pwbe_before_save_array_value' ), 10, 3 );
        add_filter( 'pwbe_save_array_value', array( $this, 'pwbe_save_array_value' ), 10, 3 );
    }

    function pwbe_product_columns( $columns ) {
        $new_columns = array();

        $new_columns[] = array(
            'name' => 'WPC Smart Group Products',
            'type' => 'multiselect',
            'table' => 'meta',
            'field' => "{$this->meta_key}___",
            'readonly' => 'false',
            'visibility' => 'parent',
            'sortable' => 'true',
            'views' => array( 'all' ),
        );

        // Insert after the "Sale End Date" column.
        $start_index = 1;
        foreach ( $columns as $index => $column ) {
            if ( $column['field'] === '_sale_price_dates_to' ) {
                $start_index = $index + 1;
                break;
            }
        }

        array_splice( $columns, $start_index, 0, $new_columns );

        return $columns;
    }

    function pwbe_results_decode_array( $array_value, $field, $pwbe_product, $array_name ) {
        // translate items into product id array
        if ( $field === "{$this->meta_key}___" ) {
            $array_value = array_column( $array_value, 'id' );
        }

        return $array_value;
    }

    function pwbe_select_options( $select_options ) {
        $this->load_all_products();

        $select_options[ "{$this->meta_key}___" ] = array();
        foreach ( $this->all_products as $id => $product ) {
            $select_options[ "{$this->meta_key}___" ][ $id ][ 'name' ] = $product[ 'name' ];
            $select_options[ "{$this->meta_key}___" ][ $id ][ 'visibility' ] = 'parent';
        }

        return $select_options;
    }

    function pwbe_before_save_array_value( $stored_data, $meta_key, $field ) {
        if ( $meta_key === $this->meta_key ) {
            unset( $this->results[ $field[ 'post_id' ] ] );
            $product_ids = explode( ',', $field['value'] );

            // re-use data from existing product if available
            foreach ( $stored_data as $key => $data ) {
                if ( ( $index = array_search( $data['id'], $product_ids ) ) !== false) {
                    unset( $product_ids[ $index ] );
                    $this->results[ $field[ 'post_id' ] ][ $key ] = array_merge( [], $data );
                }
            }

            // add new products with defaults
            foreach ( $product_ids as $new_product_id ) {
                $generated_key = WPCleverWoosg_Helper::generate_key();
                $product = wc_get_product( $new_product_id );
                $quantity = apply_filters( 'pwbe_wpc_grouped_product_quantity', PWBE_WPC_GROUPED_PRODUCT_QUANTITY, $field[ 'post_id' ], $new_product_id );

                $this->results[ $field[ 'post_id' ] ][ $generated_key ][ 'id' ] = $new_product_id;
                $this->results[ $field[ 'post_id' ] ][ $generated_key ][ 'sku' ] = $product->get_sku();
                $this->results[ $field[ 'post_id' ] ][ $generated_key ][ 'qty' ] = $quantity;
            }
        }

        return $stored_data;
    }

    function pwbe_save_array_value( $array_value, $meta_key, $field ) {
        if ( $meta_key === $this->meta_key ) {
            $array_value = $this->results[ $field[ 'post_id' ] ];
        }

        return $array_value;
    }

    function load_all_products() {
        global $wpdb;

        if ( ! $this->all_products ) {
            $this->all_products = array();

            $product_types = array_merge( array_keys( wc_get_product_types() ), [ 'variation' ] );
            $all_products = wc_get_products( array(
                'type' => $product_types,
                'limit' => -1,
            ) );

            foreach( $all_products as $product ) {
                $id = $product->get_id();

                $this->all_products[ $id ][ 'name' ] = $product->get_formatted_name();
                $this->all_products[ $id ][ 'sku' ] = $product->get_sku();
            }
        }
    }
}

new PWBE_WPC_Grouped_Product();

endif;