<?php
 
 /**
 * =============================================================================
 * @package         Blue Raven (Free Version)
 * @Plugin URI      https://enterrahost.com/plugins/blue-raven
 * 
 * @Author          EnterraHost
 * @Author URI      https://enterrahost.com
 * @License         GPL-2.0-or-later
 *  
 * @Copyright       (c) 2025 EnterraHost
 * @Contents        Export Woo Commenrse Products to Blue Raven
 *
 * =============================================================================
 * 
 * || INDEX:
 * ||   - EXPORT WOO PRODUCT
 * ||   - HEADERS
 * ||   - ATTRIBUTES
 * ||   - CREATE
 * ||   - VARIATIONS
 * ||   - UPLOAD AND UPDATES
 * ||   - PRODUCT DATA
 * || 
 * =============================================================================
 */

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

/*
============================================================
    EXPORT WOO PRODUCT
============================================================
*/

function exportWooProduct($product_id){
    
    ## =========== GET WOO PRODUCT =========== ##
        
    $product = wc_get_product($product_id);
    if (!$product) { die(esc_html("Product with ID {$product_id} not found.")); }

/*
============================================================
    HEADERS
============================================================
*/

    ## =========== Prepare CSV headers =========== ##

    $headers = array(
        'ID', 'Type', 'SKU', 'GTIN, UPC, EAN, or ISBN', 'Name', 'Published', 'Is featured?',
        'Visibility in catalog', 'Short description', 'Description', 'Date sale price starts',
        'Date sale price ends', 'Tax status', 'Tax class', 'In stock?', 'Stock', 'Low stock amount',
        'Backorders allowed?', 'Sold individually?', 'Weight (kg)', 'Length (cm)', 'Width (cm)',
        'Height (cm)', 'Allow customer reviews?', 'Purchase note', 'Sale price', 'Regular price',
        'Categories', 'Tags', 'Shipping class', 'Images', 'Virtual', 'Download limit', 'Download expiry days',
        'Parent', 'Grouped products', 'Upsells', 'Cross-sells', 'External URL', 'Button text',
        'Position', 'Brands'
    );

    ## =========== Add dynamic attribute headers (count all attributes first) =========== ##

    $attributes = $product->get_attributes();
    $attribute_headers = array();
    $attribute_count = !empty($attributes) ? count($attributes) : 0;
    
    for ($i = 1; $i <= $attribute_count; $i++) {
        $attribute_headers[] = "Attribute {$i} name";
        $attribute_headers[] = "Attribute {$i} value(s)";
        $attribute_headers[] = "Attribute {$i} visible";
        $attribute_headers[] = "Attribute {$i} used_for_variations";
    }
    
    ## =========== Merge all headers =========== ##
    
    $downloads_headers = array(); 

    if ($product->get_downloadable()) {
        $downloads = $product->get_downloads();

        if (!empty($downloads)) {
            $i = 1;
            foreach ($downloads as $download) {
                $downloads_headers[] = "Download {$i} ID";
                $downloads_headers[] = "Download {$i} name";
                $downloads_headers[] = "Download {$i} URL";
                $i++;
            }
        }
    }

    $csv_headers = array_merge($headers, $attribute_headers, $downloads_headers);
    
/*
============================================================
    ATTRIBUTES
============================================================
*/    

    $attribute_index = 1;
    foreach ($attributes as $attribute_name => $attribute) {
        $product_data["Attribute {$attribute_index} name"] = wc_attribute_label($attribute_name);
        $product_data["Attribute {$attribute_index} value(s)"] = str_replace('|', ',', $product->get_attribute($attribute_name));
        $product_data["Attribute {$attribute_index} visible"] = $attribute->get_visible() ? 1 : 0;
        $product_data["Attribute {$attribute_index} used_for_variations"] = ($attribute->is_taxonomy() && $attribute->get_variation()) ? 1 : 0;
        $attribute_index++;
    }
    
    $product = wc_get_product($product_id); 
    $attributes = $product->get_attributes();
    $attribute_data = [];
    
    foreach ($attributes as $attribute_name => $attribute) {
        $name = wc_attribute_label($attribute_name);
        $raw_value = $product->get_attribute($attribute_name);
        $values = array_map('trim', explode('|', $raw_value));
    
        $attribute_data[] = [
            'name'       => $name,
            'values'     => $values,
            'visible'    => (bool) $attribute->get_visible(),
            'variations' => (bool) $attribute->get_variation(),
        ];
    }

    
/*
============================================================
    CREATE
============================================================
*/ 

    ob_start();
	// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen -- Safe fopen on php://output stream
    $csv_stream = fopen('php://output', 'w');
    fputcsv($csv_stream, $csv_headers);
    fputcsv($csv_stream, generate_product_row($product, $product_id, $attributes));
	// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- Safe fclose of php://output stream
    fclose($csv_stream);
    $parent_csv = ob_get_clean();
    
/*
============================================================
    VARIATIONS
============================================================
*/ 

    $variations_csv = '';
    
    if ($product->is_type('variable')) {
        
        $max_downloads = 0;
        $max_att = count( $product->get_attributes() );

        foreach ($product->get_children() as $variation_id) {
            $variation = wc_get_product($variation_id);
            if ($variation && $variation->is_downloadable()) {
                $downloads = $variation->get_downloads(); 
                $download_count = count($downloads);
                if ($download_count > $max_downloads) {
                    $max_downloads = $download_count;
                }
            }
        }
    
        $variations = $product->get_children();
        if (!empty($variations)) {
            ob_start();
            $csv_stream = fopen('php://output', 'w');
            
            $downloads_headers_v = array();
            
            for ($i = 1; $i <= $max_downloads; $i++) {
                $downloads_headers_v[] = "Download {$i} ID";
                $downloads_headers_v[] = "Download {$i} name";
                $downloads_headers_v[] = "Download {$i} URL";
            }
            
            $csv_Varaition_headers = array_merge($headers, $attribute_headers, $downloads_headers_v);
            fputcsv($csv_stream, $csv_Varaition_headers);
            
            foreach ($variations as $variation_id) {
                $variation = wc_get_product($variation_id);
                if ($variation) fputcsv($csv_stream, generate_product_variate_row($variation, $variation_id, $attributes, $max_downloads, $max_att));
            }
    		
			// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- Safe fclose of php://output stream
            fclose($csv_stream);
            $variations_csv = ob_get_clean();
        }
    }

/*
============================================================
    UPLOAD AND UPDATES
============================================================
*/ 
    
    try{
    
        global $wpdb;
        $table_name = $wpdb->prefix . 'BlueRavenProducts';
        $row = $wpdb->get_row($wpdb->prepare("SELECT id, status, create_json FROM $table_name WHERE woo_product_id = %d",$product_id));
        $status = $row->status ?? 'woo';
        $create_json = $row->create_json ?? 'WOO-PRODUCT';
        
    ## =========== Extract data from parent product =========== ##
    
        $longDescription = $wpdb->get_var($wpdb->prepare("SELECT post_content FROM {$wpdb->prefix}posts WHERE ID = %d",$product_id));
        $longDescription = apply_filters('the_content', $longDescription);
        $shortDescription = $wpdb->get_var($wpdb->prepare("SELECT post_excerpt FROM {$wpdb->prefix}posts WHERE ID = %d",$product_id));
        $shortDescription = apply_filters('the_excerpt', $shortDescription);
        
    ## =========== Make sure it renders exactly as WooCommerce would =========== ##
        
        $product_cats = wp_get_post_terms($product_id, 'product_cat', ['fields' => 'names']);
        $category = implode(', ', wp_get_post_terms($product->get_id(), 'product_cat', ['fields' => 'names'])) ?? 'Uncategorized';
        $price = $product->get_regular_price();
        
        $data = array(
            'woo_product_id'        => $product_id, 
            'title'                 => $product->get_name(), 
            'slug'                  => $product->get_slug(),
            'sku'                   => $product->get_sku(), 
            'thumbnail'             => get_the_post_thumbnail_url( $product->get_id(), 'full' ), 
            'status'                => $status, 
            'description'           => $longDescription, 
            'short_description'     => $shortDescription, 
            'category'              => $category, 
            'price'                 => $price,
            'product_CSV'           => $parent_csv,
            'variations_CSV'        => $variations_csv, 
            'create_json'           => $create_json, 
            'attributes_json'       => json_encode($attribute_data),
            'updated_at'            => current_time('mysql'), 
        );
        
        $format = array(
            '%d',                                                               // woo_product_id
            '%s',                                                               // title
            '%s',                                                               // slug
            '%s',                                                               // sku
            '%s',                                                               // thumbnail
            '%s',                                                               // status
            '%s',                                                               // description
            '%s',                                                               // short_description
            '%s',                                                               // category
            '%s',                                                               // price
            '%s',                                                               // product_CSV
            '%s',                                                               // variations_CSV
            '%s',                                                               // create_json
            '%s',                                                               // attributes_json
            '%s',                                                               // updated_at
        );
        
        if (isset($row)) {
            $where = array('id' => $row->id);
            $where_format = array('%d');
            $success = $wpdb->update($table_name, $data, $where, $format, $where_format);
        } else {
            $success = $wpdb->insert($table_name, $data, $format);
        }
    } catch (Exception $e) {
        sendError("Error", "blue-raven/includes/third-party/class-blue-raven-woo-exporter.php", "Cant Upload WOO product to table :: ", "Error : " . $e->getMessage());
    }
}

/*
============================================================
    PRODUCT DATA
============================================================
*/

function generate_product_row($product, $product_id, $attributes) {

    $data = array(
        'ID' => $product->get_id(),
        'Type' => $product->get_type(),
        'SKU' => $product->get_sku(),
        'GTIN, UPC, EAN, or ISBN' => '',
        'Name' => $product->get_name(),
        'Published' => $product->get_status() === 'publish' ? 1 : 0,
        'Is featured?' => $product->get_featured() ? 1 : 0,
        'Visibility in catalog' => $product->get_catalog_visibility(),
        'Short description' => $product->get_short_description(),
        'Description' => $product->get_description(),
        'Date sale price starts' => $product->get_date_on_sale_from() ? $product->get_date_on_sale_from()->date('Y-m-d') : '',
        'Date sale price ends' => $product->get_date_on_sale_to() ? $product->get_date_on_sale_to()->date('Y-m-d') : '',
        'Tax status' => $product->get_tax_status(),
        'Tax class' => $product->get_tax_class(),
        'In stock?' => $product->get_stock_status(),
        'Stock' => $product->get_stock_quantity(),
        'Low stock amount' => get_post_meta($product->get_id(), '_low_stock_amount', true),
        'Backorders allowed?' => $product->get_backorders() ?? 'no',
        'Sold individually?' => $product->get_sold_individually() ? 1 : 0,
        'Weight (kg)' => $product->get_weight(),
        'Length (cm)' => $product->get_length(),
        'Width (cm)' => $product->get_width(),
        'Height (cm)' => $product->get_height(),
        'Allow customer reviews?' => $product->get_reviews_allowed() ? 1 : 0,
        'Purchase note' => $product->get_purchase_note(),
        'Sale price' => $product->get_sale_price(),
        'Regular price' => $product->get_regular_price(),
        'Categories' => implode(', ', wp_get_post_terms($product->get_id(), 'product_cat', ['fields' => 'names'])),
        'Tags' => implode(', ', wp_get_post_terms($product->get_id(), 'product_tag', ['fields' => 'names'])),
        'Shipping class' => $product->get_shipping_class(),
        'Images' => implode(',', array_filter(array_merge([wp_get_attachment_url($product->get_image_id())],array_map('wp_get_attachment_url', $product->get_gallery_image_ids())))),
        'Virtual' => $product->get_virtual(),
        'Download limit' => $product->get_download_limit(),
        'Download expiry days' => $product->get_download_expiry(),
        'Parent' => $product->get_parent_id(),
        'Grouped products' => ($product->get_type() === 'grouped') ? implode(',', $product->get_children()) : '',
        'Upsells' => implode(',', $product->get_upsell_ids()),
        'Cross-sells' => implode(',', $product->get_cross_sell_ids()),
        'External URL' => ($product->get_type() === 'external') ? $product->get_product_url() : '',
        'Button text' => ($product->get_type() === 'external') ? $product->get_button_text() : '',
        'Position' => $product->get_menu_order(),
        'Brands' => implode(', ', wp_get_post_terms($product->get_id(), 'product_brand', ['fields' => 'names'])) ?? "",
    );

    ## =========== Add attribute data =========== ##
    
    foreach ($attributes as $attr) {
        if (!$attr instanceof WC_Product_Attribute) continue;
        $data[] = $attr->get_name();
        $data[] = implode(', ', $attr->get_options());
        $data[] = $attr->get_visible() ? 1 : 0;
        $data[] = $attr->get_variation() ? 1 : 0;
    }
    
    ## =========== Add downloads data =========== ##
       
    if ($product->get_downloadable()) {
        $downloads = $product->get_downloads();
        
        if (!empty($downloads)) {
            foreach ($downloads as $download) {
                $data[] = $download->get_id();
                $data[] = $download->get_name();
                $data[] = $download->get_file();
            }
        }
    }

    return $data;
}

function generate_product_variate_row($product, $product_id, $attributes, $max_downloads, $max_att) {
    
    $data = array(
        'ID' => $product->get_id(),
        'Type' => $product->get_type(),
        'SKU' => $product->get_sku(),
        'GTIN, UPC, EAN, or ISBN' => '',
        'Name' => $product->get_name(),
        'Published' => $product->get_status() === 'publish' ? 1 : 0,
        'Is featured?' => $product->get_featured() ? 1 : 0,
        'Visibility in catalog' => $product->get_catalog_visibility(),
        'Short description' => $product->get_short_description(),
        'Description' => $product->get_description(),
        'Date sale price starts' => $product->get_date_on_sale_from() ? $product->get_date_on_sale_from()->date('Y-m-d') : '',
        'Date sale price ends' => $product->get_date_on_sale_to() ? $product->get_date_on_sale_to()->date('Y-m-d') : '',
        'Tax status' => $product->get_tax_status(),
        'Tax class' => 'parent',
        'In stock?' => $product->get_stock_status(),
        'Stock' => $product->get_stock_quantity(),
        'Low stock amount' => get_post_meta($product->get_id(), '_low_stock_amount', true),
        'Backorders allowed?' => $product->get_backorders() ?? 'no',
        'Sold individually?' => $product->get_sold_individually() ? 1 : 0,
        'Weight (kg)' => $product->get_weight(),
        'Length (cm)' => $product->get_length(),
        'Width (cm)' => $product->get_width(),
        'Height (cm)' => $product->get_height(),
        'Allow customer reviews?' => $product->get_reviews_allowed() ? 1 : 0,
        'Purchase note' => $product->get_purchase_note(),
        'Sale price' => $product->get_sale_price(),
        'Regular price' => $product->get_regular_price(),
        'Categories' => implode(', ', wp_get_post_terms($product->get_id(), 'product_cat', ['fields' => 'names'])),
        'Tags' => implode(', ', wp_get_post_terms($product->get_id(), 'product_tag', ['fields' => 'names'])),
        'Shipping class' => $product->get_shipping_class(),
        'Images' => implode(',', array_filter(array_merge([wp_get_attachment_url($product->get_image_id())],array_map('wp_get_attachment_url', $product->get_gallery_image_ids())))),
        'Virtual' => $product->get_virtual(),
        'Download limit' => $product->get_download_limit(),
        'Download expiry days' => $product->get_download_expiry(),
        'Parent' => $product->get_parent_id(),
        'Grouped products' => ($product->get_type() === 'grouped') ? implode(',', $product->get_children()) : '',
        'Upsells' => implode(',', $product->get_upsell_ids()),
        'Cross-sells' => implode(',', $product->get_cross_sell_ids()),
        'External URL' => ($product->get_type() === 'external') ? $product->get_product_url() : '',
        'Button text' => ($product->get_type() === 'external') ? $product->get_button_text() : '',
        'Position' => $product->get_menu_order(),
        'Brands' => implode(', ', wp_get_post_terms($product->get_id(), 'product_brand', ['fields' => 'names'])) ?? "",
    );

    ## =========== Add attribute data =========== ##
    
    $attributes = $product->get_attributes();
    $attributes_values = array_values($attributes);
    $attributes_keys = array_keys($attributes);
    
    for ($i = 0; $i < $max_att; $i++) {
        if (!isset($attributes_values[$i])) {
            $data[] = '';
            $data[] = '';
            $data[] = '';
            $data[] = '';
            continue;
        }
    
        $attr_name = $attributes_keys[$i];    
        $selected_value = $attributes_values[$i]; 
        
        $visible = 1;  
        $variation = 1;
        
        $data[] = $attr_name;
        $data[] = $selected_value;
        $data[] = $visible;
        $data[] = $variation;
    }
    
    ## =========== Add downloads data =========== ##
        
    $downloads = $product->get_downloads();
    
    $downloads_array = array_values($downloads);
    for ($i = 0; $i < $max_downloads; $i++) {
        $download = $downloads_array[$i] ?? null;
        $data[] = $download ? $download->get_id() : '';
        $data[] = $download ? $download->get_name() : '';
        $data[] = $download ? $download->get_file() : '';
    }
    
    return $data;
}

?>