<?php
// https://services.us.tiktokshop.com/open/authorize?service_id=7172**********70150  
// &state=xaoegsefowuf

// Set timezone
date_default_timezone_set('Asia/Jakarta');

use Picqer\Barcode\BarcodeGeneratorPNG;

function TiktokGetAuth($code)
{
    // Include the config file to access app_key, app_secret, and base URL
    $baseUrl = 'https://auth.tiktok-shops.com/'; // Correct TikTok base URL
    $appKey = TIKTOK_APP_KEY;    // App key from config
    $appSecret = TIKTOK_APP_SECRET;  // App secret from config

    // Prepare parameters for signature generation
    $params = [
        'app_key' => $appKey,
        'app_secret' => $appSecret,
        'auth_code' => $code,
        'grant_type' => 'authorized_code',
    ];

    // API Endpoint
    $endpoint = '/api/v2/token/get';


    // Call the executeCurl function (assuming this is already defined)
    return executeCurl($baseUrl, $endpoint, $params, null, 'GET', null);
}

function TiktokRefreshToken($refreshToken)
{
    // Base URL for TikTok API
    $baseUrl = 'https://auth.tiktok-shops.com/'; // Correct TikTok base URL
    $appKey = TIKTOK_APP_KEY;    // App key from config
    $appSecret = TIKTOK_APP_SECRET;  // App secret from config

    // Parameters for the API call
    $params = [
        'app_key' => $appKey,
        'app_secret' => $appSecret,
        'refresh_token' => $refreshToken,
        'grant_type' => 'refresh_token',
    ];

    // API Endpoint
    $endpoint = '/api/v2/token/refresh';

    // Build the full URL with query parameters
    $url = $baseUrl . $endpoint . '?' . http_build_query($params);

    // Initialize cURL
    $ch = curl_init();

    // Set cURL options
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);

    // Execute cURL request
    $response = curl_exec($ch);

    // Check for cURL errors
    if (curl_errno($ch)) {
        echo 'cURL error: ' . curl_error($ch);
        return null;
    }

    // Close cURL session
    curl_close($ch);

    // Decode the response (assuming JSON format)
    $decodedResponse = json_decode($response, true);

    // Return the response
    return $decodedResponse;
}

function TiktokSaveAuthShopData($data, $shop_id, $code)
{
    global $db;

    // Pastikan ada 'data' dan 'access_token' dalam respons
    if (isset($data['data']['access_token'])) {
        // Ambil access_token dari data
        $accessToken = $data['data']['access_token'];
        $refreshToken = $data['data']['refresh_token'];
        $sellerName = $data['data']['seller_name'];
        $platform_id = 2;  // Misalnya platform_id tetap 2 (Tiktok)
        // Extract detail shop

        // Cek apakah shop sudah ada dalam database
        $sql = "SELECT * FROM shop WHERE shop_id = ? AND platform_id = ?";
        $stmt = $db->prepare($sql);
        $stmt->bind_param("ii", $shop_id, $platform_id);
        $stmt->execute();
        $result = $stmt->get_result();

        // Jika shop sudah ada, lakukan update
        if ($result->num_rows > 0) {
            $sql = "UPDATE shop 
            SET access_token = '{$accessToken}', 
                refresh_token = '{$refreshToken}', 
                code = '{$code}', 
                shop_name = '{$sellerName}' 
            WHERE shop_id = {$shop_id} AND platform_id = {$platform_id}";

            if ($db->query($sql)) {
                return [true]; // Berhasil melakukan update
            } else {
                return ["", false]; // Gagal melakukan update
            }
        } else {
            // Jika shop belum ada, lakukan insert
            $shop_id = (int)$shop_id;  // Pastikan shop_id adalah integer
            $platform_id = (int)$platform_id;  // Pastikan platform_id adalah integer
            $accessToken = $db->escape($accessToken);  // Escape untuk menghindari SQL Injection
            $refreshToken = $db->escape($refreshToken);  // Escape untuk menghindari SQL Injection
            $code = $db->escape($code);  // Escape untuk menghindari SQL Injection
            $sellerName = $db->escape($sellerName);  // Escape untuk menghindari SQL Injection


            $sql = "INSERT INTO shop (shop_id, access_token, refresh_token, code, shop_name, platform_id)
                    VALUES ($shop_id, '$accessToken', '$refreshToken', '$code', '$sellerName', '$platform_id')";

            if ($db->query($sql)) {
                return [true]; // Berhasil melakukan insert
            } else {
                return ["", false]; // Gagal melakukan insert
            }
        }
        return [true]; // Sukses
    }

    return ["Invalid data", false]; // Jika data tidak lengkap atau tidak ada shop list
}


function TiktokGetShopInfo($accessToken, $shopId)
{
    $baseUrl = TIKTOK_BASE_URL; // Correct TikTok base URL
    $appKey = TIKTOK_APP_KEY;
    $appSecret = TIKTOK_APP_SECRET;
    $timestamp = time(); // Use current timestamp
    $version = '202212'; // Version is given in the curl request

    // Prepare parameters for signature generation
    $params = [
        'app_key' => $appKey,
        'timestamp' => $timestamp,
        'shop_id' => $shopId,
        'access_token' => $accessToken,
        'version' => $version,  // Add version to params
    ];

    // API Endpoint
    $endpoint = '/api/shop/get_authorized_shop';

    // Generate the sign using the generateSign function
    $sign = TiktokGenerateSign([
        'uri' => $baseUrl . $endpoint,  // Full URL including endpoint
        'qs' => $params  // Query parameters
    ], $appSecret);

    // Query parameters to be added to the URL
    $queryParams = [
        'access_token' => $accessToken,
        'app_key' => $appKey,
        'shop_id' => $shopId,
        'sign' => $sign,
        'timestamp' => $timestamp,
        'version' => $version
    ];

    // Set headers for the request
    $headers = [
        'Content-Type: application/json',
        "x-tts-access-token: {$accessToken}"  // This header is important, similar to the curl example
    ];

    // Call the executeCurl function
    return executeCurl($baseUrl, $endpoint, $queryParams, $headers, 'GET', null);
}
function TiktokSaveShopData($data, $accessToken)
{
    global $db;
    // Check if 'data' contains shop list
    if (isset($data['data']['shop_list']) && is_array($data['data']['shop_list'])) {
        // Iterate through the shop list
        foreach ($data['data']['shop_list'] as $shop) {
            // Extract necessary shop details
            $shop_id = $shop['shop_id'];
            $shop_name = $shop['shop_name'];
            $shop_cipher = $shop['shop_cipher'];
            $region = $shop['region'];
            $type = $shop['type'];
            $platform_id = 2;

            // Prepare SQL to insert or update the shop record
            $sql = "SELECT * FROM shop WHERE shop_id = ? AND platform_id = ?";
            $stmt = $db->prepare($sql);
            $stmt->bind_param("ii", $shop_id, $platform_id);
            $stmt->execute();
            $result = $stmt->get_result();

            // Step 2: If record exists, update it, otherwise insert
            if ($result->num_rows > 0) {
                // Record exists, so update it
                $sql = "UPDATE shop 
            SET shop_cipher = ?, access_token = ? 
            WHERE shop_id = ? AND platform_id = ?";
                $stmt = $db->prepare($sql);
                $stmt->bind_param(
                    "ssii",
                    $shop_cipher,
                    $accessToken,
                    $shop_id,
                    $platform_id
                );
                if (!$stmt->execute()) {
                    return ["", false]; // Failed to insert or update shop
                }
            } else {
                // Record does not exist, so insert it
                $sql = "INSERT INTO shop (shop_id, shop_name, shop_cipher, region, type, platform_id, access_token)
            VALUES (?, ?, ?, ?, ?, ?, ?)";
                $stmt = $db->prepare($sql);
                $stmt->bind_param(
                    "isssiss",
                    $shop_id,
                    $shop_name,
                    $shop_cipher,
                    $region,
                    $type,
                    $platform_id,
                    $accessToken
                );
                if (!$stmt->execute()) {
                    return ["", false]; // Failed to insert or update shop
                }
            }

            // Optionally, you can update queue_shipment table here as well (similar to your original example)
            $sqlQueue = "UPDATE queue_shipment SET shop_name = ?, shop_cipher = ?, region = ?, access_token = ?
                         WHERE shop_id = ? AND platform_id = ? AND flag_delete = 0";
            $stmtQueue = $db->prepare($sqlQueue);
            $stmtQueue->bind_param("ssssii", $shop_name, $shop_cipher, $region, $accessToken, $shop_id, $platform_id);

            // Execute the statement for queue_shipment table
            if (!$stmtQueue->execute()) {
                return ["", false]; // Failed to update queue_shipment table
            }
        }

        return [true]; // Success
    }

    return ["Invalid data", false]; // If no shop list found in the response
}

function getTikTokShopsAndPerformAction()
{
    global $db;
    // Prepare SQL to select access_token, shop_cipher, platform_id, and shop_name for platform_id = 2
    $sql = "SELECT access_token, shop_cipher, platform_id, shop_name, shop_id FROM shop WHERE platform_id = 2";

    // Initialize an array to store the results
    $shops = [];

    // Prepare and execute the query
    if ($stmt = $db->prepare($sql)) {
        $stmt->execute();

        // Bind the result variables to be fetched from the query
        $stmt->bind_result($access_token, $shop_cipher, $platform_id, $shop_name, $shop_id);

        // Loop through the result set and store each row in the $shops array
        while ($stmt->fetch()) {
            // Add each shop's information as an associative array
            $shops[] = [
                'access_token' => $access_token,
                'shop_cipher' => $shop_cipher,
                'platform_id' => $platform_id,
                'shop_name' => $shop_name,
                'shop_id' => $shop_id
            ];
        }

        // Close the prepared statement
        $stmt->close();
    } else {
        echo "Error in database query execution: " . $db->error;
    }

    // Return the array of shops
    return $shops;
}

function TiktokGenerateSign($requestOptions, $appSecret)
{
    // Step 1: Extract all query parameters excluding 'sign' and 'access_token'. Reorder the parameter keys in alphabetical order.
    $excludeKeys = ['access_token', 'sign'];
    $params = isset($requestOptions['qs']) ? $requestOptions['qs'] : [];

    // Filter and sort parameters alphabetically
    $sortedParams = [];
    foreach ($params as $key => $value) {
        if (!in_array($key, $excludeKeys)) {
            $sortedParams[] = ['key' => $key, 'value' => $value];
        }
    }
    usort($sortedParams, function ($a, $b) {
        return strcmp($a['key'], $b['key']);
    });

    // Step 2: Concatenate all the parameters in the format {key}{value}
    $paramString = '';
    foreach ($sortedParams as $param) {
        $paramString .= $param['key'] . $param['value'];
    }

    // Step 3: Append the string from Step 2 to the API request path
    $url = isset($requestOptions['uri']) ? $requestOptions['uri'] : '';
    $parsedUrl = parse_url($url);
    $pathname = isset($parsedUrl['path']) ? $parsedUrl['path'] : '';

    $signString = $pathname . $paramString;

    // Step 4: If the request header content-type is not multipart/form-data, append the API request body to the string from Step 3
    if (
        isset($requestOptions['headers']['content-type']) && $requestOptions['headers']['content-type'] !== 'multipart/form-data'
        && isset($requestOptions['body'])
    ) {
        $body = json_encode($requestOptions['body']);
        $signString .= $body;
    }

    // Step 5: Wrap the string generated in Step 4 with the app_secret
    $signString = $appSecret . $signString . $appSecret;

    // Step 6: Encode the wrapped string using HMAC-SHA256
    $sign = hash_hmac('sha256', $signString, $appSecret);

    return $sign;
}

function getRefreshTokenTiktok($appKey, $appSecret, $refreshToken)
{
    // Base URL dan Endpoint
    $baseUrl = "https://auth.tiktok-shops.com";
    $endpoint = "/api/v2/token/refresh";

    // Query Params
    $queryParams = [
        'app_key' => $appKey,
        'app_secret' => $appSecret,
        'refresh_token' => $refreshToken,
        'grant_type' => 'refresh_token'
    ];

    // Headers
    $headers = [
        'Content-Type: application/json'
    ];

    // Eksekusi permintaan menggunakan template executeCurl
    return executeCurl($baseUrl, $endpoint, $queryParams, $headers, 'POST', null);
}




function TiktokShipPackage($accessToken, $shopCipher, $shopId, $packageId)
{
    $baseUrl = TIKTOK_BASE_URL; // base URL
    $appKey = TIKTOK_APP_KEY;  // Your app's key
    $appSecret = TIKTOK_APP_SECRET; // Your app's secret key
    $endpoint = "/fulfillment/202309/packages/{$packageId}/ship";  // Package shipping endpoint
    $timestamp = time();
    $version = 202309;

    // Data to send in POST request body (same structure as in the cURL example)
    $data = json_encode([
        'handover_method' => 'PICKUP'
    ]);

    // Prepare parameters for signature generation
    $params = [
        'app_key' => $appKey,
        'shop_cipher' => $shopCipher,
        'shop_id' =>  $shopId,
        'timestamp' => $timestamp,
        'version' => $version,
    ];

    // Set headers for the request
    $headers = [
        'Content-Type: application/json',
        "x-tts-access-token: {$accessToken}"
    ];

    // Generate the sign using the generateSign function
    $sign = TiktokGenerateSign([
        'uri' => $baseUrl . $endpoint,  // Full URL including endpoint
        'qs' => $params,                // Query parameters
        'body' => $data, // Parse the body data to array
        'headers' => [
            'content-type' => 'application/json',
        ]
    ], $appSecret);  // Your app's secret key


    // Query parameters to be added to the URL
    $queryParams = [
        'access_token' => $accessToken,
        'app_key' => $appKey,
        'shop_cipher' => $shopCipher,
        'shop_id' =>  $shopId,
        'timestamp' => $timestamp,
        'version' => $version,
        'sign' => $sign
    ];

    // Execute the cURL request using the executeCurl function
    return executeCurl($baseUrl, $endpoint, $queryParams, $headers, 'POST', $data);
}

function TiktokGetOrders($accessToken, $shopCipher, $pageSize = 1)
{
    $baseUrl = TIKTOK_BASE_URL; // TikTok base URL
    $appKey = TIKTOK_APP_KEY;
    $appSecret = TIKTOK_APP_SECRET;
    $timestamp = time(); // Current timestamp
    $version = '202212'; // API version

    // Prepare parameters for signature generation
    $params = [
        'app_key' => $appKey,
        'timestamp' => $timestamp,
        'shop_cipher' => $shopCipher,
        'page_size' => $pageSize,
        'order_status' => 'AWAITING_SHIPMENT',
        'version' => $version, // Add version to params
        'sort_field' => 'create_time'
    ];

    // API Endpoint for getting orders
    $endpoint = '/order/202309/orders/search';

    // Generate the sign using the generateSign function
    $sign = TiktokGenerateSign([
        'uri' => $baseUrl . $endpoint,  // Full URL including endpoint
        'qs' => $params  // Query parameters
    ], $appSecret);

    // Query parameters to be added to the URL
    $queryParams = [
        'app_key' => $appKey,
        'shop_cipher' => $shopCipher,
        'sign' => $sign,
        'timestamp' => $timestamp,
        'page_size' => $pageSize,
        'order_status' => 'AWAITING_SHIPMENT',
        'version' => $version,
        'sort_field' => 'create_time'
    ];

    // Set headers for the request
    $headers = [
        'Content-Type: application/json',
        "x-tts-access-token: {$accessToken}"  // TikTok-specific header
    ];

    // Call the executeCurl function to get order details
    return executeCurl($baseUrl, $endpoint, $queryParams, $headers, 'POST', null);
}

function TiktokGetOrdersNextPage($accessToken, $shopCipher, $pageSize = 1, $tokenNext = '')
{
    $baseUrl = TIKTOK_BASE_URL; // TikTok base URL
    $appKey = TIKTOK_APP_KEY;
    $appSecret = TIKTOK_APP_SECRET;
    $timestamp = time(); // Current timestamp
    $version = '202212'; // API version

    // Prepare parameters for signature generation
    $params = [
        'app_key' => $appKey,
        'timestamp' => $timestamp,
        'shop_cipher' => $shopCipher,
        'page_size' => $pageSize,
        'order_status' => 'AWAITING_SHIPMENT',
        'version' => $version, // Add version to params
        'page_token' => $tokenNext
    ];

    // API Endpoint for getting orders
    $endpoint = '/order/202309/orders/search';

    // Generate the sign using the generateSign function
    $sign = TiktokGenerateSign([
        'uri' => $baseUrl . $endpoint,  // Full URL including endpoint
        'qs' => $params  // Query parameters
    ], $appSecret);

    // Query parameters to be added to the URL
    $queryParams = [
        'app_key' => $appKey,
        'shop_cipher' => $shopCipher,
        'sign' => $sign,
        'timestamp' => $timestamp,
        'page_size' => $pageSize,
        'order_status' => 'AWAITING_SHIPMENT',
        'version' => $version,
        'page_token' => $tokenNext
    ];

    // Set headers for the request
    $headers = [
        'Content-Type: application/json',
        "x-tts-access-token: {$accessToken}"  // TikTok-specific header
    ];

    // Call the executeCurl function to get order details
    return executeCurl($baseUrl, $endpoint, $queryParams, $headers, 'POST', null);
}

function TiktokgetOrderDetails($accessToken, $shopCipher, $orderIds = [])
{
    $baseUrl = TIKTOK_BASE_URL; // TikTok base URL
    $appKey = TIKTOK_APP_KEY;
    $appSecret = TIKTOK_APP_SECRET;
    $timestamp = time(); // Current timestamp
    $version = '202309'; // API version

    // Prepare parameters for signature generation
    $params = [
        'app_key' => $appKey,
        'timestamp' => $timestamp,
        'shop_cipher' => $shopCipher,
        'version' => $version,
        'ids' => implode(',', $orderIds) // Encode order IDs as JSON
    ];

    // API Endpoint for getting order details
    $endpoint = '/order/202309/orders';

    // Generate the sign using the generateSign function
    $sign = TiktokGenerateSign([
        'uri' => $baseUrl . $endpoint,  // Full URL including endpoint
        'qs' => $params  // Query parameters
    ], $appSecret); // Use the correct app secret

    // Query parameters to be added to the URL
    $queryParams = [
        'app_key' => $appKey,
        'shop_cipher' => $shopCipher,
        'sign' => $sign,
        'timestamp' => $timestamp,
        'version' => $version,
        'ids' => implode(',', $orderIds) // Pass the order IDs as JSON
    ];

    // Set headers for the request
    $headers = [
        'Content-Type: application/json',
        "x-tts-access-token: {$accessToken}"  // TikTok-specific header
    ];

    // Execute the curl function to get the order details
    return executeCurl($baseUrl, $endpoint, $queryParams, $headers, 'GET', '{}');
}

function TiktokGetFulfillmentDetails($accessToken, $shopCipher, $shopId, $packageId)
{
    $baseUrl = TIKTOK_BASE_URL; // TikTok base URL
    $appKey = TIKTOK_APP_KEY;  // Your app's key
    $appSecret = TIKTOK_APP_SECRET; // Your app's secret key
    $timestamp = time(); // Current timestamp
    $version = '202212'; // API version

    // Prepare parameters for signature generation
    $params = [
        'access_token' => $accessToken,
        'app_key' => $appKey,
        'timestamp' => $timestamp,
        'shop_cipher' => $shopCipher,
        'shop_id' => $shopId,
        'version' => $version,
        'shop_id' => $shopId,
        'package_id' => $packageId
    ];

    // API Endpoint for getting fulfillment details
    $endpoint = '/api/fulfillment/detail';  // The endpoint for fulfillment details

    // Generate the sign using the generateSign function
    $sign = TiktokGenerateSign([
        'uri' => $baseUrl . $endpoint,  // Full URL including endpoint
        'qs' => $params  // Query parameters
    ], $appSecret);  // Your app's secret key

    // Query parameters to be added to the URL
    $queryParams = array_merge($params, ['sign' => $sign]);

    // Set headers for the request
    $headers = [
        'Content-Type: application/json',
        "x-tts-access-token: {$accessToken}"  // TikTok-specific header
    ];

    // Execute the curl function to get the fulfillment details
    return executeCurl($baseUrl, $endpoint, $queryParams, $headers, 'GET', '{}');
}

function TiktokgetWarehouseList($accessToken, $shopCipher, $shopId)
{
    $baseUrl = TIKTOK_BASE_URL; // TikTok base URL
    $appKey = TIKTOK_APP_KEY;
    $appSecret = TIKTOK_APP_SECRET;
    $timestamp = time(); // Current timestamp
    $version = '202212'; // API version for logistics

    // Prepare parameters for signature generation
    $params = [
        'access_token' => $accessToken,
        'app_key' => $appKey,
        'timestamp' => $timestamp,
        'shop_cipher' => $shopCipher,
        'shop_id' =>  $shopId,
        'version' => $version
    ];

    // API Endpoint for getting warehouse list
    $endpoint = '/api/logistics/get_warehouse_list';

    // Generate the sign using the generateSign function
    $sign = TiktokGenerateSign([
        'uri' => $baseUrl . $endpoint,  // Full URL including endpoint
        'qs' => $params  // Query parameters
    ], $appSecret); // Use the correct app secret

    // Query parameters to be added to the URL
    $queryParams = [
        'access_token' => $accessToken,
        'app_key' => $appKey,
        'timestamp' => $timestamp,
        'shop_cipher' => $shopCipher,
        'shop_id' =>  $shopId,
        'version' => $version,
        'sign' => $sign
    ];

    // Set headers for the request
    $headers = [
        'Content-Type: application/json',
        "x-tts-access-token: {$accessToken}"  // TikTok-specific header
    ];

    // Execute the curl function to get the warehouse list
    return executeCurl($baseUrl, $endpoint, $queryParams, $headers, 'GET', '{}');
}

function TikTokGetShippingDocumentsV2($accessToken, $packageId, $shopCipher, $shopId, $documentType, $documentSize, $trackingNumber)
{
    $baseUrl = TIKTOK_BASE_URL;
    $appKey = TIKTOK_APP_KEY;
    $appSecret = TIKTOK_APP_SECRET;

    $timestamp = time(); // Get the current timestamp
    $version = '202309'; // Version for the request
    $endpoint = '/fulfillment/202309/packages/' . $packageId . '/shipping_documents';
    $url = $baseUrl . $endpoint;

    // Prepare parameters for signature generation
    $params = [
        'access_token' => $accessToken,
        'app_key' => $appKey,
        'document_size' => $documentSize,
        'document_type' => $documentType,
        'shop_cipher' => $shopCipher,
        'shop_id' => $shopId,
        'timestamp' => $timestamp,
        'version' => $version,
    ];

    // Generate the sign using TiktokGenerateSign function
    $sign = TiktokGenerateSign([
        'uri' => $url,  // Full URL including endpoint
        'qs' => $params  // Query parameters
    ], $appSecret);

    // Add the sign to query parameters
    $params['sign'] = $sign;

    // Build the query string for the request
    $queryParams = http_build_query($params);

    // Create the full request URL
    $requestUrl = $url . '?' . $queryParams;

    // Set headers for the request
    $headers = [
        'x-tts-access-token: ' . $accessToken
    ];

    // Make the cURL request using the reusable function
    $decodedResponse = executeCurl($baseUrl, $endpoint, $params, $headers, 'GET', '{}');

    // Check if the document URL exists
    if (isset($decodedResponse['data']['doc_url']) && !empty($decodedResponse['data']['doc_url'])) {
        return $decodedResponse;
    }

    // If tracking number doesn't match, retry the request
    if (isset($decodedResponse['data']['tracking_number']) && $trackingNumber !== $decodedResponse['data']['tracking_number']) {
        echo $decodedResponse['data']['tracking_number'] . "\n";
        echo $trackingNumber . "\n";
        echo "Tracking number mismatch, retrying...\n";

        // sleep(60); // Wait 1 minute before retrying
        return TikTokGetShippingDocumentsV2($accessToken, $packageId, $shopCipher, $shopId, $documentType, $documentSize, $trackingNumber);
    }

    // Return the response
    return $decodedResponse;
}

function TikTokGetShippingDocuments($accessToken, $packageId, $shopCipher, $shopId, $documentType = 1)
{

    $baseUrl = TIKTOK_BASE_URL;
    $appKey = TIKTOK_APP_KEY;
    $appSecret = TIKTOK_APP_SECRET;

    $timestamp = time(); // Get the current timestamp
    $endpoint = '/api/fulfillment/shipping_document';
    $url = $baseUrl . $endpoint;

    $version = 202212;

    $params = [
        'access_token' => $accessToken,
        'app_key' => $appKey,
        'document_type' => $documentType,
        'package_id' => $packageId,
        'shop_cipher' => $shopCipher,
        'shop_id' => $shopId,
        'timestamp' => $timestamp,
        'version' => $version,
    ];


    $sign = TiktokGenerateSign([
        'uri' => $url,  // Full URL including endpoint
        'qs' => $params  // Query parameters
    ], $appSecret);

    // Build the query parameters
    $queryParams = [
        'access_token' => $accessToken,
        'app_key' => $appKey,
        'document_type' => $documentType,
        'package_id' => $packageId,
        'shop_cipher' => $shopCipher,
        'shop_id' => $shopId,
        'timestamp' => $timestamp,
        'version' => $version,
        'sign' => $sign,
    ];


    // Set headers for the request
    $headers = [
        'x-tts-access-token: ' . $accessToken
    ];

    // Make the cURL request using the reusable function
    // return executeCurl($url, 'GET', $headers);
    return executeCurl($baseUrl, $endpoint, $queryParams, $headers, 'GET', '{}');
}


function TiktokInsertOrderData($orderData, $shop_id)
{
    global $db;

    // Check if the 'orders' array is present
    if (isset($orderData['data']['orders']) && !empty($orderData['data']['orders'])) {
        foreach ($orderData['data']['orders'] as $order) {
            // Extract necessary order information
            if (isset($order['id'], $order['status'], $order['create_time'], $order['payment']['total_amount'], $order['payment']['currency'])) {

                // Convert timestamps to datetime format
                $create_time = date('Y-m-d H:i:s', $order['create_time']);
                $total_amount = $order['payment']['total_amount'];
                $currency = $order['payment']['currency'];

                // Generate order_sn (Order ID or a custom identifier)
                $order_sn = $order['id'];  // Assuming 'id' is a unique order identifier

                // Optional fields
                $buyer_user_id = isset($order['user_id']) ? $order['user_id'] : null;
                $order_status = isset($order['status']) ? $order['status'] : null;
                $payment_method = isset($order['payment_method_name']) ? $order['payment_method_name'] : null;

                // Escape the values for SQL query
                $order_sn = $db->escape($order_sn);
                $shop_id = $db->escape($shop_id);
                $buyer_user_id = $db->escape($buyer_user_id);
                $order_status = $db->escape($order_status);
                $payment_method = $db->escape($payment_method);
                $total_amount = $db->escape($total_amount);
                $currency = $db->escape($currency);
                $create_time = $db->escape($create_time);

                // First, count if this order already exists
                $count_sql = "SELECT COUNT(*) AS count FROM orders WHERE order_sn = '$order_sn' AND shop_id = '$shop_id'";
                $count_result = $db->query($count_sql);
                $count_data = $count_result->fetch_assoc();

                // If the order doesn't exist, insert a new order, else update the existing order
                if ($count_data['count'] == 0) {
                    // Insert new order
                    $sql = "INSERT INTO orders 
                            (order_sn, shop_id, buyer_user_id, order_status, payment_method, total_amount, currency, create_time)
                         VALUES 
                            ('$order_sn', '$shop_id', '$buyer_user_id', '$order_status', '$payment_method', '$total_amount', '$currency', '$create_time')";

                    if ($db->query($sql)) {
                        $order_id = $db->insert_id();
                        TiktokInsertOrderDetails($order['line_items'], $order_id, $order_sn);
                    } else {
                        echo "Error inserting order: " . $db->error;
                    }
                } else {
                    // Update existing order
                    $sql = "UPDATE orders 
                            SET 
                                shop_id = '$shop_id', 
                                buyer_user_id = '$buyer_user_id', 
                                order_status = '$order_status', 
                                payment_method = '$payment_method', 
                                total_amount = '$total_amount', 
                                currency = '$currency', 
                                create_time = '$create_time'
                            WHERE order_sn = '$order_sn' AND shop_id = '$shop_id'";

                    if ($db->query($sql)) {
                        // Optionally update the order details here if needed
                        // TiktokInsertOrderDetails($order['line_items'], $order['id'], $order_sn);
                        // return true;
                    } else {
                        // echo "Error updating order: " . $db->error;
                        // return false;
                    }
                }
            } else {
                return false;
            }
        }
    } else {
        die("Error inserting order: " . $db->error);
    }

    return false;  // Return false if data is incomplete or insert/update fails
}


function TiktokInsertOrderDetails($lineItems, $order_id, $order_sn)
{
    global $db;
    // Loop through line items and insert them into the `order_detail` table
    foreach ($lineItems as $item) {
        $order_item_id = $item['id'] ?? 0;  // Assuming this is unique for each item in the order
        $item_name = $item['product_name'] ?? '';
        $sale_price = $item['sale_price'] ?? 0;
        $original_price = $item['original_price'] ?? 0;
        // $currency = $item['currency'] ?? 'Rp';
        $image_url = $item['sku_image'] ?? '';
        $model_sku = isset($item['seller_sku']) ? $item['seller_sku'] : null;
        $item_sku = isset($item['sku_id']) ? $item['sku_id'] : null;
        $weight = isset($item['weight']) ? $item['weight'] : null;

        $order_id = (int)$order_id;
        $order_sn = (int)$order_sn;
        $order_item_id = (int)$order_item_id;
        $item_name = (string)$item_name;
        $sale_price = (float)$sale_price;
        $original_price = (float)$original_price;
        $image_url = (string)$image_url;
        $model_sku = (string)$model_sku;
        $item_sku = (string)$item_sku;
        $weight = (float)$weight;
        $quantity_purchased = 1;

        // Insert order item details into `order_detail` table
        $sql = "INSERT INTO order_detail 
        (order_id, order_sn, order_item_id, item_name, model_id, model_quantity_purchased, 
        model_discounted_price, model_original_price, image_url, model_sku, item_sku, weight)
        VALUES (
            '" . (int)$order_id . "',
            '" . (int)$order_sn . "',
            '" . (int)$order_item_id . "',
            '" . $db->escape($item_name) . "',
            '" . (int)$order_item_id . "',
            '" . (int)$quantity_purchased . "',
            '" . (float)$sale_price . "',
            '" . (float)$original_price . "',
            '" . $db->escape($image_url) . "',
            '" . $db->escape($model_sku) . "',
            '" . $db->escape($item_sku) . "',
            '" . (float)$weight . "'
        )";

        if ($db->query($sql)) {
            // echo "Order detail inserted successfully!";
            return true;
            // continue;  // Continue to the next item in the loop if insert is successful
        } else {
            echo "Error inserting order detail: " . $db->error;
            die();

            return false;
        }
    }
}

function TiktokGetWarehouseZipcode($warehouse_id, $warehouseList)
{
    // Loop through each warehouse in the list
    foreach ($warehouseList as $warehouse) {
        if ($warehouse['warehouse_id'] == $warehouse_id) {
            // Return the zipcode based on the city
            $city = $warehouse['warehouse_address']['city'];

            // Mapping city to corresponding zipcode
            $zipcodeMapping = [
                'Sidoarjo Regency' => '61256',
                'Tangerang City' => '15151',
                'Makassar City' => '90223',
                'Denpasar City' => '80114',
                'Bandung Regency' => '40256',
                'Semarang City' => '50248'
            ];

            return isset($zipcodeMapping[$city]) ? $zipcodeMapping[$city] : null;
        }
    }

    return null; // If no matching warehouse_id found
}

function TiktokGetStartNextUnixTimestamp()
{
    // Get the current time
    $currentTime = time(); // Current Unix timestamp

    // Add 1 hour to the current time
    $nextHourTimestamp = strtotime('+1 hour', $currentTime);

    // Check if the current time is after 4 PM today
    if (date('H', $currentTime) >= 16) {
        // If it's after 4 PM, return the Unix timestamp for tomorrow at 12 PM (noon)
        return strtotime('tomorrow 08:00 AM');
    }

    // If it's before 4 PM, return the timestamp for 1 hour from now
    return $nextHourTimestamp;
}

function TiktokGetEndNextUnixTimestamp()
{
    // Get the current time
    $currentTime = time(); // Current Unix timestamp

    // Add 1 hour to the current time
    $nextHourTimestamp = strtotime('+3 hour', $currentTime);

    // Check if the current time is after 3 PM today
    if (date('H', $currentTime) >= 15) {
        // If it's after 4 PM, return the Unix timestamp for tomorrow at 12 PM (noon)
        return strtotime('tomorrow 12:00 AM');
    }

    // If it's before 4 PM, return the timestamp for 1 hour from now
    return $nextHourTimestamp;
}

function insertQueueShipmentTiktokMulti($data)
{
    global $db;

    // Validasi bahwa data tidak kosong dan berupa array
    if (empty($data) || !is_array($data)) {
        return false;
    }

    // Menyiapkan array untuk menyimpan nilai yang akan dimasukkan ke dalam query
    $values = [];

    // Loop melalui setiap elemen data untuk memvalidasi dan mempersiapkan query
    foreach ($data as $shipment) {
        // Validasi masing-masing elemen
        if (empty($shipment['errorJson']) || json_decode($shipment['errorJson']) === null) {
            $shipment['errorJson'] = json_encode(['error' => 'Invalid or empty JSON']);
        }

        // Escape setiap elemen untuk menghindari SQL Injection
        $shopId = $db->escape($shipment['shopId']);
        $accessToken = $db->escape($shipment['accessToken']);
        $refreshToken = $db->escape($shipment['refreshToken']);
        $orderSN = $db->escape($shipment['orderSN']);
        $errorJson = $db->escape($shipment['errorJson']);
        $platform = (int)$shipment['platform']; // Pastikan platform adalah integer
        $packageId = $db->escape($shipment['packageId']);
        $zipcode = $db->escape($shipment['zipcode']);
        $trackingNumber = $db->escape($shipment['trackingNumber']);
        $shopCipher = $db->escape($shipment['shopCipher']);

        // Tambahkan set nilai untuk setiap baris
        $values[] = "('$orderSN', '$shopId', '$accessToken', '$refreshToken', '$errorJson', $platform, 0, '$packageId', '$zipcode', '$trackingNumber', '$shopCipher')";
    }

    // Jika tidak ada data untuk diinsert, kembalikan false
    if (empty($values)) {
        return false;
    }

    // Gabungkan semua nilai dalam satu query multi-insert
    $query = "
        INSERT INTO queue_shipment (order_sn, shop_id, access_token, refresh_token, log_json, platform_id, flag_delete, packageId, zipcode, tracking_number, shop_cipher)
        VALUES " . implode(', ', $values);

    // Eksekusi query
    if ($db->query($query)) {
        return true; // Jika berhasil
    } else {
        return false; // Jika gagal
    }
}

function insertQueueShipmentTiktok($shopId, $accessToken, $refreshToken, $orderSN, $errorJson, $platform, $shopCipher, $packageId, $trackingNumber, $zipcode)
{
    global $db;

    // Validasi errorJson jika kosong atau tidak valid
    if (empty($errorJson) || json_decode($errorJson) === null) {
        $errorJson = json_encode(['error' => 'Invalid or empty JSON']);
    }

    // Escape semua input untuk menghindari SQL Injection
    $shopId = $db->escape($shopId);
    $accessToken = $db->escape($accessToken);
    $refreshToken = $db->escape($refreshToken);
    $orderSN = $db->escape($orderSN);
    $errorJson = $db->escape($errorJson);
    $platform = (int)$platform; // Pastikan platform adalah integer
    $packageId = $db->escape($packageId);
    $zipcode = $db->escape($zipcode);
    $trackingNumber = $db->escape($trackingNumber);
    $shopCipher = $db->escape($shopCipher);

    // Query SQL untuk memasukkan data
    $query = "
    INSERT INTO queue_shipment (order_sn, shop_id, access_token, refresh_token, log_json, platform_id, flag_delete, packageId, zipcode, tracking_number, shop_cipher)
    VALUES ('$orderSN', '$shopId', '$accessToken', '$refreshToken', '$errorJson', $platform, 0, '$packageId', '$zipcode', '$trackingNumber', '$shopCipher')
  ";

    // Eksekusi query
    if ($db->query($query)) {
        return true; // Jika berhasil
    } else {
        return false; // Jika gagal
    }
}
