<?php

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

use GuzzleHttp\Client;

class ShopifySync extends CI_Controller {

    private $shopifyClient;

    public function __construct() {
        parent::__construct();
        $this->load->database();

        // Initialize Guzzle client to interact with Shopify API
        $this->shopifyClient = new Client([
            'base_uri' => SHOP_URL,
            'headers' => [
                'Content-Type' => 'application/json',
                'X-Shopify-Access-Token' => SHOP_TOKEN
            ]
        ]);
    }

    // Fetch all product IDs from the sh_product table
    private function getDatabaseProductIds() {
        $query = $this->db->select('product_id')->from('sh_product')->get();
        return array_column($query->result_array(), 'product_id');
    }

    // Fetch all product IDs from Shopify
    private function getShopifyProductIds() {
        $shopifyProducts = $this->fetchAllShopifyProducts();
        return array_column($shopifyProducts, 'id'); // Extract only the product IDs
    }

    // Fetch all products from Shopify
    private function fetchAllShopifyProducts() {
        $products = [];
        $nextPageInfo = null;

        do {
            $endpoint = '/admin/api/2024-01/products.json?limit=250';
            if ($nextPageInfo) {
                $endpoint .= "&page_info=" . $nextPageInfo;
            }

            $response = $this->shopifyClient->request('GET', $endpoint, [
                'http_errors' => false
            ]);

            if ($response->getStatusCode() !== 200) {
                die('Error: Shopify API request failed. Status Code: ' . $response->getStatusCode());
            }

            $responseData = json_decode($response->getBody(), true);
            if (isset($responseData['products'])) {
                $products = array_merge($products, $responseData['products']);
            }

            // Check for pagination
            $linkHeader = $response->getHeader('Link');
            if (!empty($linkHeader) && preg_match('/<([^>]+)>;\s*rel="next"/', $linkHeader[0], $matches)) {
                parse_str(parse_url($matches[1], PHP_URL_QUERY), $queryParams);
                $nextPageInfo = $queryParams['page_info'] ?? null;
            } else {
                $nextPageInfo = null;
            }
        } while ($nextPageInfo);

        return $products;
    }

    // Find duplicate products in the database by title
    private function getDuplicateProducts() {
        $query = $this->db->query("SELECT `title`, COUNT(`title`) AS title_count FROM `sh_product` GROUP BY `title` HAVING COUNT(`title`) > 1");
        return $query->result_array();
    }

    // Archive a product in Shopify
    private function archiveShopifyProduct($shopifyProductId) {
        try {
            $this->shopifyClient->request('PUT', "/admin/api/2024-01/products/{$shopifyProductId}.json", [
                'json' => [
                    'product' => [
                        'id' => $shopifyProductId,
                        'status' => 'archived'
                    ]
                ]
            ]);
        } catch (\Exception $e) {
            echo "Error archiving product in Shopify: " . $e->getMessage();
        }
    }

    // Update the status of the product in the database
    private function archiveDatabaseProduct($productId) {
        $this->db->where('product_id', $productId)->update('sh_product', ['status' => 'archived']);
    }

    // Get the corresponding Shopify product ID based on the database product ID
    private function getShopifyProductIdByDbProductId($dbProductId) {
        $shopifyProduct = $this->db->select('product_id')->where('product_id', $dbProductId)->get('sh_product')->row_array();
        return $shopifyProduct ? $shopifyProduct['product_id'] : null;
    }

    // Archive duplicate products
    public function archiveDuplicateProducts() {
        // Fetch duplicate products from the database
        $duplicateProducts = $this->getDuplicateProducts();

        foreach ($duplicateProducts as $duplicate) {
            $productTitle = $duplicate['title'];

            // Fetch the products with the same title from the database
            $dbProducts = $this->db->where('title', $productTitle)->get('sh_product')->result_array();

            foreach ($dbProducts as $dbProduct) {
                $productId = $dbProduct['product_id'];

                // Archive the product in the database
                $this->archiveDatabaseProduct($productId);

                // Find the corresponding Shopify product ID
                $shopifyProductId = $this->getShopifyProductIdByDbProductId($productId);

                if ($shopifyProductId) {
                    // Archive the product in Shopify
                    $this->archiveShopifyProduct($shopifyProductId);
                }
            }
        }

        echo "All duplicate products are archived in both the database and Shopify.";
    }
}

?>
