<?php  defined('BASEPATH') OR exit('No direct script access allowed');



use GuzzleHttp\Client;



class Samaya_products_upload extends CI_Controller { 

public function __construct()
	{
		parent::__construct();
		header('X-Robots-Tag: noindex');

	}
	
	function run_job() {
		$this->processAddJewelry();

		$this->processUpdateJewelry();

		$this->addNewVariant();
		
		$this->updateQuantity();
		
		$this->processAddProductMetafield();
		
		$this->processUpdateProductMetafield();
		
		$this->processAddVariantMetafield();
		
		$this->processUpdateVariantMetafield();

 		$this->processUploadImage();

		/* Every process will execute only if the previous process has no records. */
	}

private function processAddJewelry() {
    $updateLocal = [];

    // Query to get records that are not uploaded yet
    $record = $this->db->query(
        "SELECT * FROM sh_product_raw WHERE is_upload = 0 LIMIT 50"
    )->result();

    foreach($record as $row) {
        // Check if the product SKU exists in the product_variant table
        $checkQuery = $this->db->query(
            "SELECT product_id FROM sh_product_variant WHERE sku = BINARY '$row->sku' "
        )->result();

        // Skip if the SKU already exists in the product_variant table
        if (!empty($checkQuery)) {
            $updateLocal[] = [
                'id' => $row->id,
                'is_upload' => 1,
            ];
            continue;
        }

        // Decode the JSON variant data
        $variants = json_decode($row->json_variant ?: '');

        // Ensure variants are not empty and have the expected format
        if (empty($variants)) {
            log_message('error', 'Empty or invalid variant data for product: ' . $row->sku);
            continue;
        }

        // Iterate through the variants and make sure the data is correct
        foreach($variants as $vRow) {
            if (!isset($vRow->sim_sku)) {
                log_message('error', 'Missing sim_sku in variant for product: ' . $row->sku);
                continue;
            }

            // Replace sku value with sim_sku and unset unnecessary fields
            $vRow->sku = $vRow->sim_sku;
            unset($vRow->sim_sku);
            unset($vRow->metal_v, $vRow->size); // Remove unnecessary fields
        }

        // Prepare the product data to send to Shopify
        $dataSend = [
            'product' => [
                'title' => $row->title,
                'body_html' => $row->body_html,
                'product_type' => $row->product_type,
                'status' => $row->status,
                'vendor' => $row->vendor,
                'tags' => $row->tags,
                'variants' => $variants,
                'options' => json_decode($row->json_option ?: '')
            ]
        ];

        // If handle exists, add it to the dataSend array
        if (!empty($row->handle)) {
            $dataSend['product']['handle'] = $row->handle;
        }

        // Insert the product into Shopify
        $newRecord = $this->addProduct(json_encode($dataSend));

        // Check if the product was successfully added
        if (empty($newRecord)) {
            log_message('error', 'Failed to insert product into Shopify for SKU: ' . $row->sku);
            continue;
        }

        // Save product details, quantity, SEO, images, and metafields
        $this->saveProduct($newRecord, 'insert', $row->sku);
        $this->saveHistory($dataSend, [
            'sku' => $row->sku,
            'product_status' => $row->status,
            'type' => 'insert'
        ]);

        $updateLocal[] = [
            'id' => $row->id,
            'is_upload' => 1,
        ];

        // Additional actions for quantity, SEO, and image
        $this->saveQuantityToUpload(
            $variants,
            $newRecord->product->variants
        );

        $this->updateSeo('title_tag', $row->seo_title, $newRecord->product->id);
        $this->updateSeo('description_tag', $row->seo_description, $newRecord->product->id);
        $this->saveImageToUpload($row->json_image, $newRecord->product->id);
        $this->saveProductMetafieldToUpload($row, $newRecord);

        // If video data exists, update it in the product record
        if (!empty($row->json_video)) {
            $this->db->update(
                'sh_product',
                ['json_video' => $row->json_video],
                ['product_id' => $newRecord->product->id]
            );
        }
    }

    // Update the database to mark products as uploaded
    if (!empty($updateLocal)) {
        $this->db->update_batch('sh_product_raw', $updateLocal, 'id');
    }

    // Exit if records were found to process
    if (!empty($record)) {
        exit;
    }
}

public function processUpdateJewelry() {
    $updateLocal = [];
    $sku = '';
    
    // Query to get products that need updating
    $product = $this->db->query(
        "SELECT * FROM sh_product WHERE is_update = 1 AND is_upload = 0 LIMIT 50"
    )->result();

    foreach ($product as $row) {
        
        $variants = [];

        // Get the product variants that are not marked as 'new'
        $productVariant = $this->db->query(
            "SELECT * FROM sh_product_variant WHERE is_new = 0 AND product_id = $row->product_id"
        )->result();
        // If there are no variants, skip this product
        if (empty($productVariant)) {
            log_message('error', 'No variants found for product: ' . $row->product_id);
            continue;
        }

        foreach ($productVariant as $rv) {
            $variants[] = [
                'id' => $rv->variant_id,
                'sku' => $rv->sim_sku,
                'barcode' => $rv->barcode,
                'price' => $rv->price,
                'compare_at_price' => $rv->compare_at_price,
                'cost' => $rv->cost,
                'option1' => $rv->option1,
                'option2' => $rv->option2,
                'option3' => $rv->option3
            ];

            $sku = $rv->sku;
        }

        // Prepare the product data for update
        $dataSend = [
            'product' => [
                'id' => $row->product_id,
                'title' => $row->title,
                'handle' => $row->handle,
                'body_html' => $row->body_html,
                'product_type' => $row->product_type,
                'vendor' => $row->vendor, 
                'status' => $row->status,
                'tags' => $row->tags,
                'variants' => $variants,
                'options' => json_decode($row->json_option ?: '')
            ]
        ];

        // Update the product in Shopify
        $newRecord = $this->updateProduct(json_encode($dataSend), $row->product_id);

        // If update fails, mark it as failed
        if (empty($newRecord)) {
            $updateLocal[] = [
                'id' => $row->id,
                'is_update' => 2,
                'is_upload' => 2,
            ];
            continue;
        }

        // Save product details, quantity, SEO, and images
        $this->saveProduct($newRecord, 'update', $sku);
        $this->saveHistory($dataSend, [
            'sku' => $sku,
            'product_status' => $row->status,
            'type' => 'update'
        ]);

        $this->saveQuantityToUpload($productVariant, $newRecord->product->variants);
        $this->updateSeo('title_tag', $row->seo_title, $row->product_id);
        $this->updateSeo('description_tag', $row->seo_description, $row->product_id);
    }

    // Update the local database to reflect the upload status
    if (!empty($updateLocal)) {
        $this->db->update_batch('sh_product', $updateLocal, 'id');
    }

    // Exit if there were any products processed
    if (!empty($product)) {
        exit;
    }
}


// 	public function addNewVariant() {
// 		$productVariant = $this->db->query(
// 			"SELECT * FROM sh_product_variant WHERE is_new = 1 LIMIT 50"
// 		)->result();
		
//     	foreach($productVariant as $rv) {
//             $product_id = $rv->product_id;

// 			$dataSend = [
// 			    'variant' => [
// 	                'sku' => $rv->sim_sku,
// 	                'barcode' => $rv->barcode,
// 	                'price' => $rv->price,
// 	                'compare_at_price' => $rv->compare_at_price,
// 	                'cost' => $rv->cost,
// 	                'option1' => $rv->option1,
// 	                'option2' => $rv->option2,
// 	                'option3' => $rv->option3
// 	            ]
// 			];
// 			$newRecord = $this->addVariant(
// 				json_encode($dataSend), 
// 				$product_id
// 			);		

// 			if(empty($newRecord)) {
// 				$this->db->update('sh_product_variant', ['is_new' => 2 ], ['id' => $rv->id]);		

// 				continue;
// 			}

// 			$variant_id = $newRecord->variant->id;
// 			$inventory_item_id = $newRecord->variant->inventory_item_id;
// 			$title = $newRecord->variant->title;
// 			$newMetalV = $rv->custom_metal_v;
// 			$newSize = $rv->custom_size;
// 			$newWebsite_stonetype = $rv->custom_website_stonetype;

// 			// -------------------------------------------------------------
// 			// custom metafield metal_v

// 			if(!empty($newMetalV)) {
// 				$metafieldInsertData = [
// 					'variant_id'=> $variant_id,
// 					'namespace'=> 'custom',
// 					'meta_key'=> 'metal_v',
// 					'value'=> $newMetalV,
// 					'type'=> 'single_line_text_field',					
// 					'to_create'=> 1,
// 				];
// 				$this->db->insert('sh_variant_metafield', $metafieldInsertData);
// 			}

// 			// -------------------------------------------------------------
// 			// custom metafield sizing 

// 			if(!empty($newSize)) {
// 				$metafieldInsertData = [
// 					'variant_id'=> $variant_id,
// 					'namespace'=> 'custom',
// 					'meta_key'=> 'sizing',
// 					'value'=> $newSize,
// 					'type'=> 'single_line_text_field',					
// 					'to_create'=> 1,
// 				];
// 				$this->db->insert('sh_variant_metafield', $metafieldInsertData);
// 			}

// 			// -------------------------------------------------------------
// 			// custom metafield newWebsite_stonetype 

// 			if(!empty($newWebsite_stonetype)) {
// 				$metafieldInsertData = [
// 					'variant_id'=> $variant_id,
// 					'namespace'=> 'custom',
// 					'meta_key'=> 'website_stonetype',
// 					'value'=> $newWebsite_stonetype,
// 					'type'=> 'single_line_text_field',					
// 					'to_create'=> 1,
// 				];
// 				$this->db->insert('sh_variant_metafield', $metafieldInsertData);
// 			}

// 			// -------------------------------------------------------------

// 			$this->saveHistory($dataSend, [
// 				'sku' => $rv->sku,
// 				'product_status' => '',
// 				'type' => 'add_variant'
// 			]);

// 			// -------------------------------------------------------------

// 			$variant_data = [
// 				'variant_id'=> $variant_id,
// 				'inventory_item_id'=> $inventory_item_id,
// 				'title'=> $title,
// 				'is_new' => 0		
// 			];

// 			$this->db->update('sh_product_variant', $variant_data, ['id' => $rv->id]);		
			
//     	}

//     	if(!empty($productVariant)) {
// 			exit;
// 		}
// 	}
public function addNewVariant() {
    $productVariant = $this->db->query(
        "SELECT * FROM sh_product_variant WHERE is_new = 1 LIMIT 50"
    )->result();

    foreach ($productVariant as $rv) {
        $product_id = $rv->product_id;

        // Get product options from Shopify
        $productOptions = $this->getProductOptions($product_id);

        // Prepare options data to send, only include existing options
        $optionsToSend = [];
        foreach ($productOptions as $index => $option) {
            $optionIndex = $index + 1;
            $optionValue = $rv->{"option" . $optionIndex};
            if (!empty($optionValue)) {
                $optionsToSend["option$optionIndex"] = $optionValue;
            }
        }

        $dataSend = [
            'variant' => array_merge([
                'sku' => $rv->sim_sku,
                'barcode' => $rv->barcode,
                'price' => $rv->price,
                'compare_at_price' => $rv->compare_at_price,
                'cost' => $rv->cost
            ], $optionsToSend)
        ];

        $newRecord = $this->addVariant(
            json_encode($dataSend),
            $product_id
        );

        if (empty($newRecord)) {
            $this->db->update('sh_product_variant', ['is_new' => 2], ['id' => $rv->id]);
            continue;
        }

        $variant_id = $newRecord->variant->id;
        $inventory_item_id = $newRecord->variant->inventory_item_id;
        $title = $newRecord->variant->title;
        $newMetalV = $rv->custom_metal_v;
        $newSize = $rv->custom_size;
        $newWebsite_stonetype = $rv->custom_website_stonetype;

        // Insert custom metafields if they exist
        if (!empty($newMetalV)) {
            $this->db->insert('sh_variant_metafield', [
                'variant_id' => $variant_id,
                'namespace' => 'custom',
                'meta_key' => 'metal_v',
                'value' => $newMetalV,
                'type' => 'single_line_text_field',
                'to_create' => 1,
            ]);
        }

        if (!empty($newSize)) {
            $this->db->insert('sh_variant_metafield', [
                'variant_id' => $variant_id,
                'namespace' => 'custom',
                'meta_key' => 'sizing',
                'value' => $newSize,
                'type' => 'single_line_text_field',
                'to_create' => 1,
            ]);
        }

        if (!empty($newWebsite_stonetype)) {
            $this->db->insert('sh_variant_metafield', [
                'variant_id' => $variant_id,
                'namespace' => 'custom',
                'meta_key' => 'website_stonetype',
                'value' => $newWebsite_stonetype,
                'type' => 'single_line_text_field',
                'to_create' => 1,
            ]);
        }

        $this->saveHistory($dataSend, [
            'sku' => $rv->sku,
            'product_status' => '',
            'type' => 'add_variant'
        ]);

        $variant_data = [
            'variant_id' => $variant_id,
            'inventory_item_id' => $inventory_item_id,
            'title' => $title,
            'is_new' => 0
        ];

        $this->db->update('sh_product_variant', $variant_data, ['id' => $rv->id]);
    }

    if (!empty($productVariant)) {
        exit;
    }
}
public function updateQuantity() {
		$updateLocal = [];

		$product = $this->db->query(
			"SELECT variant_id, inventory_item_id, inventory_quantity FROM sh_product_variant
			WHERE is_new = 0 AND is_quantity_update = 0 LIMIT 50"
		)->result();

    	foreach($product as $row) {
    		$variant_id = $row->variant_id;

			$dataInventory = [
			    "location_id"=> SHOP_LOCATION,
			    "inventory_item_id"=> $row->inventory_item_id,
			    "available"=> $row->inventory_quantity ?: 0
			];
			$updatedRecord = $this->updateInventory(json_encode($dataInventory));

			if(empty($updatedRecord)) {
				$updateLocal[] = [
					'variant_id'=> $variant_id,
					'is_quantity_update'=> 2,
				];

				continue;
			}

    		$updateLocal[] = [
				'variant_id'=> $variant_id,
				'is_quantity_update'=> 1,
			];
			
    	}

		if (!empty($updateLocal)) {
			$this->db->update_batch('sh_product_variant', $updateLocal, 'variant_id');
		}

		if(!empty($product)) {
			exit;
		}	
	}

private function getProductOptions($product_id) {
    $client = new Client([
        'base_uri' => SHOP_URL
    ]);

    $headers = [
        'Content-Type' => 'application/json',
        'X-Shopify-Access-Token' => SHOP_TOKEN
    ];

    $response = $client->request('GET', "products/$product_id.json", [
        'headers' => $headers
    ]);

    $body = $response->getBody();
    $parsedBody = json_decode($body);

    if ($response->getStatusCode() > 300) {
        return [];
    }

    return $parsedBody->product->options ?? [];
}

	public function processAddProductMetafield() {
		$updateLocal = [];

		$productMetafield = $this->db->query(
			"SELECT * FROM sh_product_metafield WHERE to_create = 1 LIMIT 50"
		)->result();

// $productMetafield = $this->db->query(
// 			"SELECT * FROM `sh_product_metafield` WHERE `meta_key` LIKE '%ring_category%' AND `value` LIKE '%Men\'s%' and to_create = 1 LIMIT 30"
// 		)->result();
		

		foreach($productMetafield as $row) {
			$product_id = $row->product_id;

			$dataInsert = [
			    "metafield" => [
			    	"namespace"=> $row->namespace,
				    "key"=> $row->meta_key,
				    "type"=> $row->type,
				    "value"=> $row->value
				]
			];

			$updatedRecord = $this->addMetafield(json_encode($dataInsert), 'products', $product_id);

			if(empty($updatedRecord)) {
				$updateLocal[] = [
					'id'=> $row->id,
					'to_create'=> 2,
				];

				continue;
			}

			$updateLocal[] = [
				'id'=> $row->id,
				'meta_id'=> $updatedRecord->metafield->id,
				'updated_at'=> date('Y-m-d H:i:s', strtotime($updatedRecord->metafield->updated_at)),
				'to_create'=> 0,
			];	

		}

		if (!empty($updateLocal)) {
			$this->db->update_batch('sh_product_metafield', $updateLocal, 'id');
		}

		if(!empty($productMetafield)) {
			exit;
		}
	}

	public function processUpdateProductMetafield() {
		$updateLocal = [];

		$productMetafield = $this->db->query(
			"SELECT * FROM sh_product_metafield WHERE to_update = 1 LIMIT 30"
		)->result();

		foreach($productMetafield as $row) {
			$product_id = $row->product_id;
			$meta_id = $row->meta_id;

			$dataInsert = [
			    "metafield" => [
				    "id"=> $meta_id,
				    "value"=> $row->value
				]
			];

			$updatedRecord = $this->updateMetafield(json_encode($dataInsert), 'products', $product_id, $meta_id);

			if(empty($updatedRecord)) {
				$updateLocal[] = [
					'id'=> $row->id,
					'to_update'=> 2,
				];

				continue;
			}
			if (isset($updatedRecord->metafield) && $updatedRecord->metafield !== null) {
                // If metafield is not null, update the record
                $updateLocal[] = [
                    'id' => $row->id,
                    'updated_at' => date('Y-m-d H:i:s', strtotime($updatedRecord->metafield->updated_at)),
                    'to_update' => 0,
                ];
            } else {
                // If metafield is null, delete the record
                $this->db->where('id', $row->id);
                $this->db->delete('sh_product_metafield');
            }

// 			$updateLocal[] = [
// 				'id'=> $row->id,
// 				'updated_at'=> date('Y-m-d H:i:s', strtotime($updatedRecord->metafield->updated_at)),
// 				'to_update'=> 0,
// 			];	

		}

		if (!empty($updateLocal)) {
			$this->db->update_batch('sh_product_metafield', $updateLocal, 'id');
		}

		if(!empty($productMetafield)) {
			exit;
		}
	}

	public function processAddVariantMetafield() {
		$updateLocal = [];

		$variantMetafield = $this->db->query(
			"SELECT * FROM sh_variant_metafield WHERE to_create = 1 LIMIT 50"
		)->result();

		foreach($variantMetafield as $row) {
			$variant_id = $row->variant_id;

			$dataInsert = [
			    "metafield" => [
			    	"namespace"=> $row->namespace,
				    "key"=> $row->meta_key,
				    "type"=> $row->type,
				    "value"=> $row->value
				]
			];

			$updatedRecord = $this->addMetafield(json_encode($dataInsert), 'variants', $variant_id);

			if(empty($updatedRecord)) {
				$updateLocal[] = [
					'id'=> $row->id,
					'to_create'=> 2,
				];

				continue;
			}
			if (!empty($updatedRecord->metafield)) {
                // If metafield is not null, update the record
                $updateLocal[] = [
                    'id' => $row->id,
                    'meta_id'=> $updatedRecord->metafield->id,
                    'updated_at' => date('Y-m-d H:i:s', strtotime($updatedRecord->metafield->updated_at)),
                    'to_update' => 0,
                ];
            } else {
                // If metafield is null, delete the record
                $this->db->where('id', $row->id);
                $this->db->delete('sh_product_metafield');
            }
            if(!empty($updatedRecord->metafield->updated_at)){

			$updateLocal[] = [
				'id'=> $row->id,
				'meta_id'=> $updatedRecord->metafield->id,
				'updated_at'=> date('Y-m-d H:i:s', strtotime($updatedRecord->metafield->updated_at)),
				'to_create'=> 0,
			];
            }

		}

		if (!empty($updateLocal)) {
			$this->db->update_batch('sh_variant_metafield', $updateLocal, 'id');
		}

		if(!empty($variantMetafield)) {
			exit;
		}
	}

	public function processUpdateVariantMetafield() {
		$updateLocal = [];

		$variantMetafield = $this->db->query(
			"SELECT * FROM sh_variant_metafield WHERE to_update = 1 LIMIT 50"
		)->result();

		foreach($variantMetafield as $row) {
			$variant_id = $row->variant_id;
			$meta_id = $row->meta_id;

			$dataInsert = [
			    "metafield" => [
				    "id"=> $meta_id,
				    "value"=> $row->value
				]
			];

			$updatedRecord = $this->updateMetafield(json_encode($dataInsert), 'variants', $variant_id, $meta_id);

			if(empty($updatedRecord)) {
				$updateLocal[] = [
					'id'=> $row->id,
					'to_update'=> 2,
				];
				
				continue;
			}
            if (!empty($updatedRecord->metafield)) {
                $updateLocal[] = [
                    'id' => $row->id,
                    'meta_id'=> $updatedRecord->metafield->id,
                    'updated_at' => date('Y-m-d H:i:s', strtotime($updatedRecord->metafield->updated_at)),
                    'to_update' => 0,
                ];
            } else {
                $updateLocal[] = [
                    'id' => $row->id,
                    "id"=> $meta_id,
                    'updated_at' => date('Y-m-d H:i:s'), 
                    'to_update' => 0,
                ];
            }
             if(!empty($updatedRecord->metafield->updated_at)){

			$updateLocal[] = [
				'id'=> $row->id,
				'meta_id'=> $updatedRecord->metafield->id,
				'updated_at'=> date('Y-m-d H:i:s', strtotime($updatedRecord->metafield->updated_at)),
				'to_create'=> 0,
			];
            }
// 			$updateLocal[] = [
// 				'id'=> $row->id,
// 				// 'meta_id'=> $updatedRecord->metafield->id,
// 				'updated_at'=> date('Y-m-d H:i:s', strtotime($updatedRecord->metafield->updated_at)),
// 				'to_update'=> 0,
// 			];	

		}

		if (!empty($updateLocal)) {
			$this->db->update_batch('sh_variant_metafield', $updateLocal, 'id');
		}

		if(!empty($variantMetafield)) {
			exit;
		}
	}

	// function processUploadImage() {
	// 	$updateLocal = [];

	// 	$product = $this->db->query(
	// 		"SELECT product_id, json_image FROM sh_product
	// 		WHERE is_image_upload = 0 LIMIT 10"
	// 	)->result();	

    // 	foreach($product as $row) {
    // 		$product_id = $row->product_id;

    // 		$updateLocal[] = [
	// 			'product_id'=> $product_id,
	// 			'is_image_upload'=> 1,
	// 		];

	// 		$imageList = json_decode($row->json_image ?? '');

	// 		if(empty($imageList)) {
	// 			continue;
	// 		}

    // 		$images = [];
    // 		$imgNameMergedArr = [];

    // 		foreach($imageList as $key => $imgRow) {
	// 			$imgName = $imgRow->name;    	

	// 			$imgArray = [
	// 				'src' => $imgRow->src,
	// 				'position' => ($imgRow->image_position ?? $key + 1),
	// 				'alt' => $imgName ?? ''
	// 		    ];

	// 		    //----------------------------------------------------------------- 
	// 		    if(!in_array($imgName, $imgNameMergedArr)) {
	// 				$variant_ids = $this->findImageVariant($imgName, $product_id);

	// 			    if(!empty($variant_ids)) {
	// 			        $imgArray['variant_ids'] = $variant_ids;
	// 			    }
	// 		    }
			    
	// 		    $imgNameMergedArr[] = $imgName; 
	// 		    //----------------------------------------------------------------- 

	// 			$images[] = $imgArray;
	// 		}

	// 		$dataSend = [
	// 		    'product' => [
	// 		    	'id' => $product_id,
	// 	            'images' => $images
	// 		    ]
	// 		];

	// 		$updatedRecord = $this->updateProductImage(
	// 			json_encode($dataSend), 
	// 			$product_id
	// 		);

	// 		if(empty($updatedRecord)) {
	// 			continue;
	// 		}

	// 		// -------------------------------------------------------------
	// 		$image_data = [];

	// 		foreach($updatedRecord->product->images as $iRow) {
	// 			$image_data[] = [
	// 				'image_id'=> $iRow->id,
	// 				'product_id'=> $product_id,
	// 				'src'=> $iRow->src,
	// 				'position'=> $iRow->position,
	// 				'updated_at'=> date('Y-m-d H:i:s', strtotime($iRow->updated_at)),						
	// 			];
	// 		}

	// 		if(!empty($image_data)) {
	// 			$this->db->delete('sh_product_image', ['product_id'=> $product_id]);	
	// 			$this->db->insert_batch('sh_product_image', $image_data);		
	// 		}
	// 		// -------------------------------------------------------------			

	// 		$this->saveHistory($dataSend, [
	// 			'sku' => $row->product_id,
	// 			'product_status' => '',
	// 			'type' => 'image'
	// 		]);
			
    // 	}

	// 	if (!empty($updateLocal)) {
	// 		$this->db->update_batch('sh_product', $updateLocal, 'product_id');
	// 	}	
	// }
		function processUploadImage() {
	$updateLocal = [];

	$product = $this->db->query(
		"SELECT product_id, json_image FROM sh_product
		WHERE is_image_upload = 0 LIMIT 30"
	)->result();

	foreach ($product as $row) {
		$product_id = $row->product_id;

		$updateLocal[] = [
			'product_id' => $product_id,
			'is_image_upload' => 1,
		];

		$imageList = json_decode($row->json_image ?? '');

		if (empty($imageList)) continue;

		$images = [];
		$imgNameMergedArr = [];

		foreach ($imageList as $key => $imgRow) {
			$imgName = $imgRow->name ?? '';
			$slugName = $this->slugify($imgName);
			$position = $imgRow->image_position ?? ($key + 1);
			$newFilename = "{$slugName}-{$product_id}-{$position}.jpg";

			// Download and encode image
			$base64Image = $this->downloadAndEncodeImage($imgRow->src);
			if (!$base64Image) continue;

			$imgArray = [
				'attachment' => $base64Image,
				'filename' => $newFilename,
				'position' => $position,
				'alt' => $imgName
			];

			if (!in_array($imgName, $imgNameMergedArr)) {
				$variant_ids = $this->findImageVariant($imgName, $product_id);
				if (!empty($variant_ids)) {
					$imgArray['variant_ids'] = $variant_ids;
				}
			}

			$imgNameMergedArr[] = $imgName;
			$images[] = $imgArray;
		}

		$dataSend = [
			'product' => [
				'id' => $product_id,
				'images' => $images
			]
		];

		$updatedRecord = $this->updateProductImage(json_encode($dataSend), $product_id);

		if (empty($updatedRecord)) continue;

		$image_data = [];
		foreach ($updatedRecord->product->images as $iRow) {
			$image_data[] = [
				'image_id' => $iRow->id,
				'product_id' => $product_id,
				'src' => $iRow->src,
				'position' => $iRow->position,
				'updated_at' => date('Y-m-d H:i:s', strtotime($iRow->updated_at))
			];
		}

		if (!empty($image_data)) {
			$this->db->delete('sh_product_image', ['product_id' => $product_id]);
			$this->db->insert_batch('sh_product_image', $image_data);
		}

		$this->saveHistory($dataSend, [
			'sku' => $product_id,
			'product_status' => '',
			'type' => 'image'
		]);
	}

	if (!empty($updateLocal)) {
		$this->db->update_batch('sh_product', $updateLocal, 'product_id');
	}
}

// Slugify helper
private function slugify($text) {
	$text = preg_replace('/[^A-Za-z0-9-]+/', '-', $text);
	return strtolower(trim($text, '-'));
}

// Download image & encode in base64
private function downloadAndEncodeImage($url) {
	$contents = @file_get_contents($url);
	if ($contents === false) return false;
	return base64_encode($contents);
}
private function findImageVariant($imgName, $product_id) {
	$imgName = strtolower($imgName);
	$color = '';

	if(str_starts_with($imgName, 'white')) {
		$color = 'w';
	} else if(str_starts_with($imgName, 'yellow')) {
		$color = 'y';
	} else if(str_starts_with($imgName, 'rose')) {
		$color = 'r';
	}else if (str_starts_with($imgName, 'two tone') || str_contains($imgName, 'two tone')) {
        $color = 'tt';
    }

	if(empty($color)) {
		return [];
	}

	$variantList = $this->db->query(
		"SELECT variant_id FROM sh_product_variant 
		WHERE product_id = $product_id AND option1 LIKE '%$color'"
	)->result();

	$variant_id = [];

	foreach($variantList as $vRow) {
		$variant_id[] = $vRow->variant_id;
	}

	return $variant_id;
}

	private function updateSeo($key, $value, $product_id) {
		if (empty($value)) {
			return;
		}

		$data = [
			'metafield' => [
				'namespace' => 'global',
		        'type' => 'string',
		        'key' => $key,
		        'value' => $value
			]
		];

		$this->addMetafield(json_encode($data), 'products', $product_id);
	}

	/*save product details to local DB*/
	private function saveProduct($newProduct, $type, $sku) {		
		if(empty($newProduct) || empty($newProduct->product)) {
			return '';
		}

		$product_data = [];
		$variant_data = [];
		$image_data = [];

		$product_data = [
			'product_id'=> $newProduct->product->id,
			'title'=> $newProduct->product->title,
			'handle'=> $newProduct->product->handle,
			'body_html'=> $newProduct->product->body_html,
			'product_type'=> $newProduct->product->product_type,
			'status'=> $newProduct->product->status,
			'vendor'=> $newProduct->product->vendor,
			'tags'=> $newProduct->product->tags,
			// 'published'=> '',
			// 'seo_description'=> '',
			// 'seo_title'=> '',
			// 'json_data'=> json_encode($newProduct->product),
			'edited_at'=> date('Y-m-d h:i'),
			'is_insert'=> 0,
			'is_update'=> 0,
			'is_upload'=> 1,
		];		
//test-1
		foreach($newProduct->product->variants as $vRow) {
			$variant_data[] = [
				'variant_id'=> $vRow->id,
				'product_id'=> $newProduct->product->id,
				'title'=> $vRow->title,
				'option1'=> $vRow->option1,
				'option2'=> $vRow->option2,
			    'option3'=> $vRow->option3,
				'sku'=> $sku,
				'sim_sku'=> $vRow->sku,
				'barcode'=> $vRow->barcode,
				'price'=> $vRow->price,
				'compare_at_price'=> $vRow->compare_at_price,
				'inventory_item_id'=> $vRow->inventory_item_id,
				'inventory_policy'=> $vRow->inventory_policy,
				'inventory_management'=> $vRow->inventory_management,
				'fulfillment_service'=> $vRow->fulfillment_service,
				'taxable'=> $vRow->taxable,
				'position'=> $vRow->position,					
			];
		}

		if($type == 'insert') {
			$product_data['added_at'] = date('Y-m-d h:i');
			
			if(!empty($product_data)) {
				$this->db->insert('sh_product', $product_data);			
			}
			if(!empty($variant_data)) {
				$this->db->insert_batch('sh_product_variant', $variant_data);			
			}

		} else if($type == 'update') {
			if(!empty($product_data)) {
				$this->db->update('sh_product', $product_data, ['product_id'=> $newProduct->product->id]);			
			}
			if(!empty($variant_data)) {
				$this->db->update_batch('sh_product_variant', $variant_data, 'variant_id');			
			}
		}
	}

	// save to quantity upload queue
	private function saveQuantityToUpload($variants, $newRecordVariants) {		
		if(empty($variants) || empty($newRecordVariants)) {
			return;
		}

		foreach($variants as $rv) {
			$variantQuantity[$rv->barcode] = ['inventory_quantity' => $rv->inventory_quantity];
		}

		foreach($newRecordVariants as $rv) {
			$this->db->update('sh_product_variant', 
				[
					'inventory_quantity'=> $variantQuantity[$rv->barcode]['inventory_quantity'] ?: 0,
					'is_quantity_update'=> 0
				], 
				['inventory_item_id'=> $rv->inventory_item_id]
			);
		}	
	}

	// save to product metafield upload queue
	private function saveProductMetafieldToUpload($record, $newProduct) {		
		if(empty($record) || empty($newProduct)) {
			return;
		}

		$product_id = $newProduct->product->id;
		$jewelryDetailsdArr = json_decode($record->json_jewelry_details, true);
		$gemstoneDetailsArr = json_decode($record->json_gemstone_details, true);
		$setcode = $record->setcode;
    	$jewelrybarcode = $record->jewelrybarcode;
		// -------------------------------------------------------------
		// custom metafield jewelry_details

		if(!empty($jewelryDetailsdArr)) {
			$metafieldInsertData = [
				'product_id'=> $product_id,
				'namespace'=> 'custom',
				'meta_key'=> 'jewelry_details',
				'value'=> json_encode($jewelryDetailsdArr),
				'type'=> 'list.single_line_text_field',					
				'to_create'=> 1,
			];

			$this->db->insert('sh_product_metafield', $metafieldInsertData);
		}

		// -------------------------------------------------------------
		// custom metafield gemstone_details

		if(!empty($gemstoneDetailsArr)) {
			$metafieldInsertData = [
				'product_id'=> $product_id,
				'namespace'=> 'custom',
				'meta_key'=> 'gemstone_details',
				'value'=> json_encode($gemstoneDetailsArr),
				'type'=> 'list.single_line_text_field',					
				'to_create'=> 1,
			];
			
			$this->db->insert('sh_product_metafield', $metafieldInsertData);
		}

		// -------------------------------------------------------------
		// custom metafield setcode

		if(!empty($setcode)) {
			$metafieldInsertData = [
				'product_id'=> $product_id,
				'namespace'=> 'custom',
				'meta_key'=> 'setcode',
				'value'=> $setcode,
				'type'=> 'single_line_text_field',					
				'to_create'=> 1,
			];

			$this->db->insert('sh_product_metafield', $metafieldInsertData);
		}
			// -------------------------------------------------------------
		// custom metafield jewelrybarcode

		if(!empty($jewelrybarcode)) {
			$metafieldInsertData = [
				'product_id'=> $product_id,
				'namespace'=> 'custom',
				'meta_key'=> 'jewelrybarcode',
				'value'=> $jewelrybarcode,
				'type'=> 'single_line_text_field',					
				'to_create'=> 1,
			];

			$this->db->insert('sh_product_metafield', $metafieldInsertData);
		}


		// -------------------------------------------------------------
		// variants metafields

		$variants = json_decode($record->json_variant ?: '');

		$this->saveVariantMetafieldToUpload(
			$variants, 
			$newProduct->product->variants
		);
	}

	// save to variants metafield upload queue
	private function saveVariantMetafieldToUpload($variants, $newRecordVariants) {		
		if(empty($variants) || empty($newRecordVariants)) {
			return;
		}

		foreach($variants as $rv) {
			$variantCustomArr[$rv->barcode] = [
				'metal_v' => $rv->metal_v,
				'size' => $rv->size,
				// 'quality' => $rv->quality,
			];
		}

		foreach($newRecordVariants as $rv) {
			$variant_id = $rv->id;
			$newMetalV = $variantCustomArr[$rv->barcode]['metal_v'] ?: 0;
			$newSize = $variantCustomArr[$rv->barcode]['size'] ?: 0;
// 			$newQuality = $variantCustomArr[$rv->barcode]['quality'] ?: 0;

			// -------------------------------------------------------------
			// custom metafield metal_v

			if(!empty($newMetalV)) {
				$metafieldInsertData = [
					'variant_id'=> $variant_id,
					'namespace'=> 'custom',
					'meta_key'=> 'metal_v',
					'value'=> $newMetalV,
					'type'=> 'single_line_text_field',					
					'to_create'=> 1,
				];
				$this->db->insert('sh_variant_metafield', $metafieldInsertData);
			}

			// -------------------------------------------------------------
			// custom metafield sizing 

			if(!empty($newSize)) {
				$metafieldInsertData = [
					'variant_id'=> $variant_id,
					'namespace'=> 'custom',
					'meta_key'=> 'sizing',
					'value'=> $newSize,
					'type'=> 'single_line_text_field',					
					'to_create'=> 1,
				];
				$this->db->insert('sh_variant_metafield', $metafieldInsertData);
			}
			// -------------------------------------------------------------
			// custom metafield quality 

// 			if(!empty($newQuality)) {
// 				$metafieldInsertData = [
// 					'variant_id'=> $variant_id,
// 					'namespace'=> 'custom',
// 					'meta_key'=> 'quality',
// 					'value'=> $newQuality,
// 					'type'=> 'single_line_text_field',					
// 					'to_create'=> 1,
// 				];
// 				$this->db->insert('sh_variant_metafield', $metafieldInsertData);
// 			}
		}	
	}

	// save to image upload queue
	private function saveImageToUpload($images, $product_id) {		
		if(empty($images)) {
			return;
		}

		$this->db->update(
			'sh_product', 
			['json_image'=> $images, 'is_image_upload'=> 0],
			['product_id'=> $product_id]
		);	
	}

	private function addProduct($jsonBody) {
		if(empty($jsonBody)) {
			return [];
		}

		$this->delay(1);

		$client = new Client([
		    'base_uri' => SHOP_URL
		]);

		$headers = [
			'Content-Type' => 'application/json',
		  	'X-Shopify-Access-Token' => SHOP_TOKEN
		];
		  
		$response = $client->request('POST', 'products.json', [
			'http_errors' => false,
			'headers' => $headers,
		    'body' => $jsonBody
		]);
		  
		$body = $response->getBody();
		$parsedBody = json_decode($body);

		if($response->getStatusCode() > 300) {
			$dataError = [
				'request' => $jsonBody,
				'response' => json_encode($parsedBody),
				'method' => 'POST',
				'endpoint' => 'products.json',
				'added_at' => date('Y-m-d h:i'),
			];
			$this->db->insert('error_log', $dataError);

		    return [];
		}

		return $parsedBody;
	}

	private function updateProduct($jsonBody, $product_id) {
		if(empty($jsonBody)) {
			return [];
		}
		$this->delay(1);

		$client = new Client([
		    'base_uri' => SHOP_URL
		]);

		$headers = [
			'Content-Type' => 'application/json',
		  	'X-Shopify-Access-Token' => SHOP_TOKEN
		];
		  
		$response = $client->request('PUT', "products/$product_id.json", [
			'http_errors' => false,
			'headers' => $headers,
		    'body' => $jsonBody
		]);
	
		$body = $response->getBody();
		$parsedBody = json_decode($body);

		if($response->getStatusCode() > 300) {
			$dataError = [
				'request' => $jsonBody,
				'response' => json_encode($parsedBody),
				'method' => 'PUT',
				'endpoint' => "products/$product_id.json",
				'added_at' => date('Y-m-d h:i'),
			];
			$this->db->insert('error_log', $dataError);

		    return [];
		}

		return $parsedBody;
	}

	private function addVariant($jsonBody, $product_id) {
		if(empty($jsonBody)) {
			return [];
		}
		$this->delay(1);

		$client = new Client([
		    'base_uri' => SHOP_URL
		]);

		$headers = [
			'Content-Type' => 'application/json',
		  	'X-Shopify-Access-Token' => SHOP_TOKEN
		];
		  
		$response = $client->request('POST', "products/$product_id/variants.json", [
			'http_errors' => false,
			'headers' => $headers,
		    'body' => $jsonBody
		]);
	
		$body = $response->getBody();
		$parsedBody = json_decode($body);

		if($response->getStatusCode() > 300) {
			$dataError = [
				'request' => $jsonBody,
				'response' => json_encode($parsedBody),
				'method' => 'POST',
				'endpoint' => "products/$product_id/variants.json",
				'added_at' => date('Y-m-d h:i'),
			];
			$this->db->insert('error_log', $dataError);

		    return [];
		}

		return $parsedBody;
	}

	private function addMetafield($jsonBody, $type, $item_id) {
		if(empty($jsonBody)) {
			return [];
		}

		$this->delay(1);

		$client = new Client([
		    'base_uri' => SHOP_URL
		]);

		$headers = [
			'Content-Type' => 'application/json',
		  	'X-Shopify-Access-Token' => SHOP_TOKEN
		];
		  
		$endpoint = "$type/$item_id/metafields.json";

		$response = $client->request('POST', $endpoint, [
			'http_errors' => false,
			'headers' => $headers,
		    'body' => $jsonBody
		]);
	
		$body = $response->getBody();
		$parsedBody = json_decode($body);

		if($response->getStatusCode() > 300) {
			$dataError = [
				'request' => $jsonBody,
				'response' => json_encode($parsedBody),
				'method' => 'POST',
				'endpoint' => $endpoint,
				'added_at' => date('Y-m-d h:i'),
			];
			$this->db->insert('error_log', $dataError);

		    return [];
		}

		return $parsedBody;
	}

// 	private function updateMetafield($jsonBody, $type, $item_id, $metafield_id) {
// 		if(empty($jsonBody)) {
// 			return [];
// 		}

// 		$this->delay(1);

// 		$client = new Client([
// 		    'base_uri' => SHOP_URL
// 		]);

// 		$headers = [
// 			'Content-Type' => 'application/json',
// 		  	'X-Shopify-Access-Token' => SHOP_TOKEN
// 		];

// 		$endpoint = "$type/$item_id/metafields/$metafield_id.json";
		  
// 		$response = $client->request('PUT', $endpoint, [
// 			'http_errors' => false,
// 			'headers' => $headers,
// 		    'body' => $jsonBody
// 		]);
	
// 		$body = $response->getBody();
// 		$parsedBody = json_decode($body);

// 		if($response->getStatusCode() > 300) {
//         $dataError = [
//             'request' => json_encode($jsonBody),
//             'response' => json_encode($parsedBody),
//             'method' => 'PUT',
//             'endpoint' => $endpoint,
//             'added_at' => date('Y-m-d h:i'),
//         ];
//         $this->db->insert('error_log', $dataError);
//         return [];
//     }

//     return $parsedBody;
// }

private function updateMetafield($jsonBody, $type, $item_id, $metafield_id) {
    if (empty($jsonBody)) {
        return [];
    }

    // Check if the value is empty and delete the metafield
    if (empty($jsonBody['metafield']['value'])) {
        // Prepare DELETE request to Shopify API to remove the metafield
        $client = new Client([
            'base_uri' => SHOP_URL
        ]);

        $headers = [
            'Content-Type' => 'application/json',
            'X-Shopify-Access-Token' => SHOP_TOKEN
        ];

        $endpoint = "$type/$item_id/metafields/$metafield_id.json";
        
        // Log the request details
        error_log("DELETE Request Endpoint: $endpoint");
        error_log("DELETE Request Headers: " . print_r($headers, true));
        
        // Send DELETE request to Shopify API
        $response = $client->request('DELETE', $endpoint, [
            'http_errors' => false,
            'headers' => $headers,
        ]);

        // Log the DELETE response for debugging
        $body = $response->getBody();
        $parsedBody = json_decode($body);
        error_log("DELETE Status Code: " . $response->getStatusCode());
        error_log("DELETE Response Body: " . $body);

        // If the response is an error, log the error and return an empty array
        if ($response->getStatusCode() > 300) {
            $dataError = [
                'request' => json_encode($jsonBody),
                'response' => json_encode($parsedBody),
                'method' => 'DELETE',
                'endpoint' => $endpoint,
                'added_at' => date('Y-m-d h:i'),
            ];
            $this->db->insert('error_log', $dataError);
            return [];
        }

        return $parsedBody;
    }

    // If value is not empty, proceed with the PUT request (updating the metafield)
    if (isset($jsonBody['metafield']['value']) && $jsonBody['metafield']['value'] === '') {
        $jsonBody['metafield']['value'] = null;  // Or use " " if you prefer to leave a blank space
    }

    // Proceed with the PUT request to update the metafield
    $this->delay(1);

    $client = new Client([
        'base_uri' => SHOP_URL
    ]);

    $headers = [
        'Content-Type' => 'application/json',
        'X-Shopify-Access-Token' => SHOP_TOKEN
    ];

    $endpoint = "$type/$item_id/metafields/$metafield_id.json";

    $response = $client->request('PUT', $endpoint, [
        'http_errors' => false,
        'headers' => $headers,
        'body' => json_encode($jsonBody)
    ]);

    $body = $response->getBody();
    $parsedBody = json_decode($body);

    // If the response status code is an error (greater than 300), log it
    if ($response->getStatusCode() > 300) {
        $dataError = [
            'request' => json_encode($jsonBody),
            'response' => json_encode($parsedBody),
            'method' => 'PUT',
            'endpoint' => $endpoint,
            'added_at' => date('Y-m-d h:i'),
        ];
        $this->db->insert('error_log', $dataError);
        return [];
    }

    return $parsedBody;
}

	private function updateInventory($jsonBody) {
		if(empty($jsonBody)) {
			return [];
		}
		
		$this->delay(1);

		$client = new Client([
		    'base_uri' => SHOP_URL
		]);

		$headers = [
			'Content-Type' => 'application/json',
		  	'X-Shopify-Access-Token' => SHOP_TOKEN
		];
		  
		$response = $client->request('POST', "inventory_levels/set.json", [
			'http_errors' => false,
			'headers' => $headers,
		    'body' => $jsonBody
		]);
	
		$body = $response->getBody();
		$parsedBody = json_decode($body);

		if($response->getStatusCode() > 300) {
			$dataError = [
				'request' => $jsonBody,
				'response' => json_encode($parsedBody),
				'method' => 'POST',
				'endpoint' => "inventory_levels/set.json",
				'added_at' => date('Y-m-d h:i'),
			];
			$this->db->insert('error_log', $dataError);

		    return [];
		}

		return $parsedBody;
	}

	private function updateProductImage($jsonBody, $product_id) {
		if(empty($jsonBody)) {
			return [];
		}

		$client = new Client([
		    'base_uri' => SHOP_URL
		]);

		$headers = [
			'Content-Type' => 'application/json',
		  	'X-Shopify-Access-Token' => SHOP_TOKEN
		];
		  
		$response = $client->request('PUT', "products/$product_id.json", [
			'http_errors' => false,
			"headers" => $headers,
		    "body" => $jsonBody
		]);
		  
		$body = $response->getBody();
		$parsedBody = json_decode($body);

		if($response->getStatusCode() > 300) {
			$dataError = [
				'request' => $jsonBody,
				'response' => json_encode($parsedBody),
				'method' => 'PUT',
				'endpoint' => "products/$product_id.json",
				'added_at' => date('Y-m-d h:i'),
			];
			$this->db->insert('error_log', $dataError);

		    return [];
		}

		return $parsedBody;
	}	

	private function saveHistory($jsonBody, $args) {
		if(empty($jsonBody)) {
			return;
		}

		$data = [			
			'sku' => $args['sku'],			
			'product_status' => $args['product_status'],
			'type' => $args['type'],
			'added_at' => date('Y-m-d h:i')
		];

		$this->db->delete('last_upload_log', ['sku' => $args['sku']]);
		$this->db->insert('last_upload_log', $data);

		$data['json_data'] = json_encode($jsonBody);
		$this->db->insert('sh_upload_history', $data);
	}

	private function delay($sec) {
		sleep($sec);
	}


}