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

use GuzzleHttp\Client;

class JewelryUpdate extends CI_Controller {

    public function __construct() {
        parent::__construct();
    }

	private function getJewelryPr($params) {
		$record = [];

		$client = new Client();

		$headers = [];
		  
		$response = $client->request('GET', 'https://shop.simplexdiam.com/admin/auto_shopify_api', [
			'http_errors' => false,
			'headers' => $headers,
		    'query' => $params
		]);
		  
		if($response->getStatusCode() > 300) {
		    return $record;
		}

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

		$record = $parsedBody['records'];

// 		$dataLog = [
//             'request' => json_encode($params),
//             'response' => json_encode($parsedBody),
//             'method' => 'GET',
//             'endpoint' => "https://shop.simplexdiam.com/admin/auto_shopify_api",
//             'added_at' => date('Y-m-d h:i'),
//         ];
//         $this->db->insert('external_api_log', $dataLog);

		return $record;
	}

private function splitJewelryByStoneTypePr($jewelryRecords) {
     // $currentDateTime = date('Y-m-d H:i:s');
    //  echo $currentDateTime;
	 //   die;
    $result = [];

    // Map metal codes to full metal names
    $metalMap = [
        'KW' => 'White Gold',
        'KY' => 'Yellow Gold',
        'KR' => 'Rose Gold',
        'TT' => 'Two Tone'
    ];

    foreach ($jewelryRecords as $item) {
        if (!isset($item['variants']) || empty($item['variants'])) {
            $result[] = $item;
            continue;
        }

        $labGrownVariants = [];
        $naturalDiamondVariants = [];

        // Group images by metal for easy lookup
        $imagesByMetal = [];
        if (isset($item['images']) && is_array($item['images'])) {
            foreach ($item['images'] as $img) {
                $metalName = $img['metal'] ?? '';
                $imagesByMetal[$metalName][] = $img['src'];
            }
        }

        // Classify variants and handle image checks
        foreach ($item['variants'] as $variant) {
            $variantMetal = $variant['metal'] ?? '';
            $metalCode = substr($variantMetal, -2); // e.g., "KW"
            $metalName = $metalMap[$metalCode] ?? '';
           // echo 'website_stonetype'. $variant['metal_v'].'=>'.$variant['website_stonetype']."<br>";
            // If no image for this metal, set inventory_quantity = 0
            $hasImage = isset($imagesByMetal[$metalName]) && !empty($imagesByMetal[$metalName]);
            if (!$hasImage) {
                $variant['inventory_quantity'] = 0;
            }

            // Normalize stone type
            $stonetypeRaw = isset($variant['website_stonetype']) ? trim($variant['website_stonetype']) : '';
            $stonetype = strtolower($stonetypeRaw);
          //  echo  $variant['metal_v'].'=>'.$stonetype."<br>";
            // Lab Grown check
            if (strpos($stonetype, 'lab grown') !== false) {
                //echo 'lab grown'. $variant['metal_v'].'=>'.$stonetype."<br>";;
                $labGrownVariants[] = $variant;
            }
            else{
                //  echo 'else'. $variant['metal_v'].'=>'.$stonetype."<br>";
                 $naturalDiamondVariants[] = $variant;
            }
        }

        // Create Lab Grown record if exists
        if (!empty($labGrownVariants)) {
            $labItem = $item;
            $labItem['variants'] = $labGrownVariants;
            $labItem['sku'] = rtrim($labItem['sku'], '/') . '/Lab';
            $labItem['setcode'] = rtrim($labItem['setcode'], '/') . '/Lab';
            $labItem['stone_type'] = 'Lab Grown';
            $result[] = $labItem;
        }

        // Create Natural Diamond record if exists
        if (!empty($naturalDiamondVariants)) {
            $naturalItem = $item;
            $naturalItem['variants'] = $naturalDiamondVariants;
            $naturalItem['stone_type'] = 'Natural Diamond';
            $result[] = $naturalItem;
        }
    }
    $this->checkAndUpdateShopify($result);

    return $result;
}


    public function run() {
    echo "Fetching records...\n";
    $records = $this->getJewelryPr([]);
    if (empty($records)) {
        echo "No records found.\n";
        return;
    }

    echo "Processing records...\n";
    $processed = $this->splitJewelryByStoneTypePr($records);

    echo "Done.\n";
}
private function checkAndUpdateShopify($jewelryRecords) {
    echo "Fetching records...\n";
    $shopifyProducts = $this->fetchShopifyActiveProducts();
    echo "Processing records...\n";

    // Collect all SKUs from jewelry records for comparison
    $jewelrySkus = [];
    foreach ($jewelryRecords as $record) {
        if (isset($record['stone_type']) && stripos($record['stone_type'], 'diamonds') !== false) {
            if (isset($record['variants']) && is_array($record['variants'])) {
                foreach ($record['variants'] as $variant) {
                    if (isset($variant['metal_v'])) {
                        $jewelrySkus[] = $variant['metal_v'];
                    }
                }
            }
        }
    }

    // Iterate over Shopify products and check variants
    foreach ($shopifyProducts as $product) {
        if (isset($product['variants']) && is_array($product['variants'])) {
            foreach ($product['variants'] as $variant) {
                $shopifySku = $variant['sku'] ?? '';
               // print_ex($product);
    //              if (isset($product['Type']) && $product['Type'] == 'diamonds') {
    //     continue;
    // }
                // Ensure stone_type contains "diamonds"
                if ($product['id'] == '7772279537748') {
                    $productId =$product['id'] ;
                    $this->db->where('product_id', $productId)->delete('sh_product');
                    $this->db->where('product_id', $productId)->delete('sh_product_image');
                    $this->db->where('product_id', $productId)->delete('sh_product_metafield');
            
                    // Find and delete product variants and their metafields from the database
                    $result = $this->db->select('*')->where('product_id', $productId)->get('sh_product_variant')->result_array();
                    if (!empty($result)) {
                        foreach ($result as $value) {
                            // Delete variant metafields from the database
                            $this->db->where('variant_id', $value['variant_id'])->delete('sh_variant_metafield');
                        }
                    }
                    $checkVariantsku = $this->db->query(
                            "SELECT sku FROM sh_product_variant 
                             WHERE product_id = ? 
                             ORDER BY id LIMIT 1", 
                            [$productId]
                        )->result();
                        
                        //print_ex($checkVariantsku);  // Assuming this prints nicely
                        
                        // Check if SKU was found before attempting delete
                        if (!empty($checkVariantsku) && isset($checkVariantsku[0]->sku)) {
                            $sku = $checkVariantsku[0]->sku;
                            // Delete the record in sh_product_raw table matching this SKU
                            $this->db->where('sku', $sku)->delete('sh_product_raw');
                        } else {
                            echo "No SKU found for product_id: $productId";
                        }
        //             // Delete product variants from the database
                    $this->db->where('product_id', $productId)->delete('sh_product_variant_deleted');
                    $this->db->where('product_id', $productId)->delete('sh_product_variant');
        //             // Delete from Shopify
                         $this->deleteProductFromShopify($productId);
                    
                    // Check if the SKU is in jewelry records
                   // if (!in_array(strtolower(trim($shopifySku)), array_map('strtolower', array_map('trim', $jewelrySkus)))) {
                        // $this->db->query(
                        //         "INSERT INTO sh_product_variant_deleted 
                        //         SELECT * FROM sh_product_variant
                        //         WHERE product_id = '{$product['id']}' 
                        //         AND variant_id = '{$variant['id']}'"
                        //     );
                        echo "SKU {$shopifySku} is not found in jewelry records. Marking for deletion.<br>";
                      echo "<br>";
                        // Optional: Delete variant from Shopify
                    //   $this->deleteVariantFromShopify($variant['id'],$product['id']);
                    //     $this->db->query(
                    //             "DELETE FROM sh_product_variant 
                    //             WHERE product_id = '{$product['id']}' 
                    //             AND variant_id = '{$variant['id']}'"
                    //         );
                  //  }
                }
            }
        }
    }

    echo "Done.\n";
}
private function deleteProductFromShopify($productId) {
    $client = new Client([
        'base_uri' => SHOP_URL, // Your Shopify store API base URL
    ]);

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

    try {
        $response = $client->request('DELETE', "products/{$productId}.json", [
            'headers' => $headers
        ]);

        if ($response->getStatusCode() == 200 || $response->getStatusCode() == 204) {
            echo "Product with ID {$productId} deleted successfully from Shopify.\n";
            return true;
        } else {
            echo "Failed to delete product with ID {$productId}. Status Code: " . $response->getStatusCode() . "\n";
            return false;
        }
    } catch (\Exception $e) {
        echo "Error deleting product with ID {$productId}: " . $e->getMessage() . "\n";
        return false;
    }
}

private function deleteVariantFromShopify($variantId, $productId)
{
  
$shopifyDomain = 'samayajewelry.myshopify.com'; // Your Shopify store domain
$accessToken = SHOP_TOKEN ; // Your Shopify API access token
echo "shopifyDomain".$shopifyDomain."accessToken". $accessToken."<br>";
$url = "https://$shopifyDomain/admin/api/2025-07/products/$productId/variants/$variantId.json";
echo $url."<br>";
$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'DELETE',
    CURLOPT_HTTPHEADER => [
        "X-Shopify-Access-Token: $accessToken",
        'Content-Type: application/json',
        'Accept: application/json',
    ],
]);

$response = curl_exec($curl);

$httpStatus = curl_getinfo($curl, CURLINFO_HTTP_CODE);

curl_close($curl);
print_pre($response);
// echo "HTTP Status: $httpStatus\n";
// echo "Response: $response\n";



  
}



private function fetchShopifyActiveProducts() {
    $client = new Client([
        'base_uri' => SHOP_URL  // Shopify Store URL (e.g., https://your-store-name.myshopify.com/admin/api/)
    ]);

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

    $products = [];
    $perPage = 250;  // Shopify API limit per page, you can adjust as needed

    try {
        $url = 'products.json?status=active&limit=' . $perPage;

        do {
            // Request for the products on the current page
            $response = $client->request('GET', $url, [
                'headers' => $headers
            ]);

            // Parse the response
            $body = $response->getBody();
            $data = json_decode($body, true);

            // Check if there are products on the current page
            if (isset($data['products'])) {
                $products = array_merge($products, $data['products']);
            }

            // Log the current page and the number of products fetched
            echo "Fetched Products: " . count($data['products']) . "\n";

            // Check if there is a next page link in the response headers
            $linkHeader = $response->getHeader('Link');
            $nextUrl = $this->getNextPageUrlFromLinkHeader($linkHeader);

            if ($nextUrl) {
                // If there is a next page, update the URL for the next request
                $url = $nextUrl;
            } else {
                // No more pages to fetch
                break;
            }

        } while ($nextUrl);  // Continue fetching as long as there's a next page

        echo "Total Products Fetched: " . count($products) . "\n";
        return $products;  // Return all fetched products

    } catch (\Exception $e) {
        echo "Error fetching Shopify products: " . $e->getMessage() . "<br>";
        return [];
    }
}

/**
 * Helper function to extract the next page URL from the 'Link' header.
 */
private function getNextPageUrlFromLinkHeader($linkHeader) {
    if ($linkHeader) {
        // The 'Link' header will contain a URL with rel="next" for pagination
        $links = explode(',', $linkHeader[0]);
        foreach ($links as $link) {
            if (strpos($link, 'rel="next"') !== false) {
                preg_match('/<(.*?)>/', $link, $matches);
                return $matches[1] ?? null;  // Return the URL of the next page
            }
        }
    }
    return null;  // No next page
}





// private function checkAndUpdateShopify($jewelryRecords) {
//     print_ex($jewelryRecords);
//     // Iterate over all jewelry records
//     foreach ($jewelryRecords as $record) {
//         // Example: Check if the jewelry barcode matches a specific one
            
//   if ($record['jewelrybarcode'] == '362878' ) {   
// //   if ($record['jewelrybarcode'] == '362878' || $record['jewelrybarcode'] == '199526' || $record['jewelrybarcode'] == '479612' ) {
//             // Check if the variants are present and valid
//             if (isset($record['variants']) && is_array($record['variants'])) {
//                 foreach ($record['variants'] as $variant) {
//                     // Get the Shopify SKU from the 'metal_v' field in the jewelry record
//                     $shopifySku = $variant['metal_v'] ?? '';  // Jewelry record's 'metal_v' corresponds to Shopify SKU
//                     echo "Checking SKU: " . $shopifySku . "<br>"; // This is where the output buffering will help
                    
//                     if (!$shopifySku) {
//                         continue; // Skip if no metal_v (Shopify SKU) in the jewelry record
//                     }

//                     // Check if the product exists in the database (sh_product_variant table) and get the variant_id
//                     $checkVariant = $this->db->query(
//                         "SELECT variant_id, product_id,inventory_item_id FROM sh_product_variant 
//                          WHERE TRIM(sim_sku) = TRIM(BINARY '$shopifySku') 
//                          ORDER BY id LIMIT 1"
//                     )->result();

//                     // Skip if no variant_id is found in the database
//                     if (empty($checkVariant)) {
//                         echo "No matching variant_id found for SKU: $shopifySku<br>";
//                         continue; // Skip if no matching variant_id is found
//                     }

//                     $variant_id = $checkVariant[0]->variant_id;
//                     $inventory_item_id = $checkVariant[0]->inventory_item_id;
//                     // Fetch product details from Shopify using the product_id
//                     $shopifyProduct = $this->getShopifyProductById($checkVariant[0]->product_id);  // Fetch product using product_id
                    
//                     // Debugging: print the fetched Shopify product info
//                     echo "Fetched Shopify Product for SKU: " . $shopifySku . "<br>";
//                   // print_pre($shopifyProduct);  // Print the full product response for debugging
//                   // echo "product_id". $checkVariant[0]->product_id;
//                     if (!$shopifyProduct) {
//                         echo "Product not found for SKU: $shopifySku<br>";
//                         continue; // Skip if product is not found in Shopify
//                     }

//                     // Loop through all variants in the Shopify product
//                     // $variantFound = false;
//                     foreach ($shopifyProduct['variants'] as $shopifyVariant) {
//                         // Compare the SKU of the variant with the jewelry variant SKU
//                         // if ($shopifyVariant['sku'] == $shopifySku) {
//                         //     $variantFound = true; // Set flag to true if the variant exists          
//                             $shopifyPrice = $shopifyVariant['price'] ?? null;
//                             $shopifyInventoryQty = $shopifyVariant['inventory_quantity'] ?? null;

//                             // Initialize mismatch flag
//                             $mismatch = false;
//                             $compare_at_price = null;
//                             echo "SKU:". $shopifySku ."shopifyPrice:". $shopifyPrice ."for variantprice:". $variant['price']." <br>";
//                             // If price mismatch, log and update
//                             if ($shopifyPrice != $variant['price']) {
//                                 $price = floatval($variant['price']);
//                                 // Determine the price increase based on the price range
//                                 if ($price < 200) {
//                                     $increase = 50; 
//                                 } elseif ($price >= 200 && $price < 500) {
//                                     $increase = 60; 
//                                 } elseif ($price >= 500 && $price < 1000) {
//                                     $increase = 67; 
//                                 } elseif ($price >= 1000 && $price < 2000) {
//                                     $increase = 73; 
//                                 } elseif ($price >= 2000 && $price < 5000) {
//                                     $increase = 80; 
//                                 } else {
//                                     $increase = 100;  
//                                 }
//                                 // Avoid division by zero
//                                 if ($increase == 100) {
//                                     $compare_at_price = $price * 2; // 100% increase means double the price
//                                 } else {
//                                     $compare_at_price = $price / (1 - $increase / 100);
//                                 }

//                                 // Round the compare_at_price
//                                 $compare_at_price = round($compare_at_price);

//                                 $mismatch = true;
//                                 echo "Price mismatch for SKU: $shopifySku <br>";
//                                 echo "Shopify Price: $shopifyPrice, Jewelry Price: " . $variant['price'] . "<br>";
//                             }

//                             // If inventory mismatch, log and update
//                             if ($shopifyInventoryQty != $variant['inventory_quantity']) {
//                                 $mismatch = true;
//                                 echo "Inventory mismatch for SKU: $shopifySku\n";
//                                 echo "Shopify Inventory: $shopifyInventoryQty, Jewelry Inventory: " . $variant['inventory_quantity'] . "\n";
//                                 // if (isset($shopifyVariant['inventory_item_id']) && isset($shopifyVariant['inventory_item_id']) && $shopifyVariant['inventory_item_id']) {
//                                     	$updateLocal = [];
//                                 	$dataInventory = [
//                             			    "location_id"=> SHOP_LOCATION,
//                             			    "inventory_item_id"=> $inventory_item_id,
//                             			    "available"=> $variant['inventory_quantity']  ?: 0
//                             			];
//                             			$updatedRecord = $this->updateInventory(json_encode($dataInventory));
                            
//                             			if(empty($updatedRecord)) {
//                             				$updateLocal[] = [
//                             					'variant_id'=> $variant_id,
//                             					'is_quantity_update'=> 1,
//                             				];
                            
//                             				continue;
//                             			}
                            
//                                 		$updateLocal[] = [
//                             				'variant_id'=> $variant_id,
//                             				'is_quantity_update'=> 1,
//                             			];
//                             		  if (!empty($updateLocal)) {
//                             			$this->db->update_batch('sh_product_variant', $updateLocal, 'variant_id');
//                             		}
                                    
//                             }

//                             // If there's any mismatch in price or inventory, update only the variant in Shopify and the database
//                             if ($mismatch) {
                                
//                                 // Prepare the JSON body for the Shopify API update request
//                                 $jsonBody = json_encode([
//                                     'variant' => [
//                                         'id' => $variant_id,  // Shopify variant ID
//                                         'price' => $variant['price'],  // New price
//                                         'compare_at_price' => $compare_at_price,  // New compare_at_price
//                                         'inventory_quantity' => $variant['inventory_quantity']  // New inventory quantity
//                                     ]
//                                 ]);

//                                 // Call the Shopify API directly to update the variant
//                                 $this->updateVariantInShopify($variant_id, $jsonBody);
//                             }
//                         }
//                     }

                   
//                 }
//             }
//         }
//   }

    // End output buffering and send the output

// use this Function to update inventory in Shopify
private function updateInventory($jsonBody) {
     sleep(1);
    if (empty($jsonBody)) {
        return [];
    }

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

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

    try {
        // Send POST request to update inventory level
        $response = $client->request('POST', "inventory_levels/set.json", [
            'http_errors' => false,
            'headers' => $headers,
            'body' => $jsonBody
        ]);

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

        // Check for response status and log errors
        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;
    } catch (\Exception $e) {
        echo "Error updating inventory: " . $e->getMessage() . "<br>";
        return [];
    }
}
// use thi
private function updateVariantInShopify($variant_id, $jsonBody) {
    sleep(1);
    $client = new Client([
        'base_uri' => SHOP_URL,  // Your Shopify store URL (e.g., https://your-shop-name.myshopify.com)
    ]);

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

    try {
        // Send the PUT request to update the variant
        $response = $client->request('PUT', "/admin/api/2025-07/variants/{$variant_id}.json", [
            'headers' => $headers,
            'body' => $jsonBody
        ]);

        // Check if the request was successful
        if ($response->getStatusCode() == 200) {
            echo "Variant updated successfully: Variant ID {$variant_id}<br>";
        } else {
            echo "Failed to update variant. Status code: " . $response->getStatusCode() . "<br>";
        }
    } catch (\Exception $e) {
        echo "Error updating variant: " . $e->getMessage() . "<br>";
    }
}

// use this
private function getShopifyProductById($product_id) {
    sleep(5);
    $client = new Client([
        'base_uri' => SHOP_URL  // Shopify store URL (set in your config)
    ]);

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

    $maxRetries = 5;  // Number of retries on failure
    $retryDelay = 1;  // Initial delay in seconds (for exponential backoff)
    $retryCount = 0;

    while ($retryCount < $maxRetries) {
        try {
            // Fetch product by ID
            $response = $client->request('GET', "products/{$product_id}.json", [
                'http_errors' => false,
                'timeout' => 10,  // Set timeout for the request
                'headers' => $headers
            ]);

            $statusCode = $response->getStatusCode();
            $body = $response->getBody();
            
            if ($statusCode == 200) {
                $product = json_decode($body, true);

                if ($product === null) {
                    echo "Error decoding JSON response: " . json_last_error_msg() . "\n";
                    return null;
                }

                return $product['product'] ?? null;  // Return product details
            } elseif ($statusCode == 429) {
                // Handle rate limiting (429)
                $retryAfter = $response->getHeaderLine('Retry-After');
                $retryDelay = $retryAfter ? (int) $retryAfter : $retryDelay * 2; // Exponential backoff
                echo "Rate limit exceeded. Retrying after {$retryDelay} seconds...\n";

                // Sleep for the delay before retrying
                sleep($retryDelay);
                $retryCount++;
            } else {
                echo "Failed to fetch product. Status Code: " . $statusCode . "\n";
                echo "Response Body: " . $body . "\n";  // Log body for debugging
                return null;
            }
        } catch (\GuzzleHttp\Exception\RequestException $e) {
            echo "Error fetching Shopify product by ID: " . $e->getMessage() . "\n";
            return null;
        }
    }

    echo "Max retries reached. Could not fetch the product.\n";
    return null;  // Return null if all retries fail
}


  
}
