<?php
/**
 * Cron Job / Manual Script - Get & Sync Services from Provider API
 *
 * Mengambil data layanan dari API provider dan melakukan INSERT/UPDATE
 * ke tabel 'categories' dan 'services' lokal.
 * Script ini bisa diakses manual via URL untuk testing.
 *
 * TODO: Amankan akses ke script ini di lingkungan produksi!
 */

set_time_limit(600); // 10 menit
ini_set('memory_limit', '256M');

error_reporting(E_ALL);
ini_set('display_errors', 1);

require_once __DIR__ . '/../config/config.php';
require_once __DIR__ . '/../includes/db_connect.php';
require_once __DIR__ . '/../includes/functions.php';

$providerId = 1; 

echo "<h1>Memulai Sinkronisasi Layanan dari Provider ID: {$providerId}</h1>";
echo "<pre>"; 

if (!isset($pdo) || !$pdo instanceof PDO) {
    die("FATAL ERROR: Koneksi database (\$pdo) tidak tersedia setelah include db_connect.php. Periksa log error PHP dan detail koneksi di config/database.php.");
}
try {
    $stmtProvider = $pdo->prepare("SELECT api_url, api_id, api_key, secret_key FROM providers WHERE id = :pid AND status = 'active'");
    $stmtProvider->bindParam(':pid', $providerId, PDO::PARAM_INT);
    $stmtProvider->execute();
    $provider = $stmtProvider->fetch(PDO::FETCH_ASSOC);
    if (!$provider) { die("Error: Provider ID {$providerId} tidak ditemukan/aktif."); }

    $apiServiceUrl = $provider['api_url']."services";
    if (empty($apiServiceUrl) || !filter_var($apiServiceUrl, FILTER_VALIDATE_URL) || strpos($apiServiceUrl, 'services') === false) {
         die("Error: URL API Provider (ID: {$providerId}) di database tidak valid atau bukan endpoint services (Harus: https://.../api/services). URL saat ini: " . htmlspecialchars($apiServiceUrl));
    }
    echo "Provider Ditemukan: Menggunakan API URL: " . htmlspecialchars($apiServiceUrl) . "\n";

} catch (\PDOException $e) { die("Error DB saat ambil provider: " . $e->getMessage()); }

$apiUrl = $apiServiceUrl; 
$postData = ['api_id' => $provider['api_id'], 'api_key' => $provider['api_key'], 'secret_key' => $provider['secret_key']];

echo "Mengirim request ke API...\n";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 120); // Timeout 2 menit
$apiResultJson = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);

if ($curlError) { die("Error cURL: " . $curlError); }
if ($httpCode !== 200) { echo "API HTTP Status: " . $httpCode . "\n"; echo "Response: " . htmlspecialchars(substr($apiResultJson, 0, 500)) . "...\n"; die("Gagal menghubungi API."); }

echo "Respons API diterima (HTTP {$httpCode}). Mencoba decode JSON...\n";
$apiResult = json_decode($apiResultJson, true);
if (json_last_error() !== JSON_ERROR_NONE) { echo "Respons mentah: \n" . htmlspecialchars($apiResultJson) . "\n"; die("Error decode JSON: " . json_last_error_msg()); }

if (!isset($apiResult['response']) || $apiResult['response'] !== true || !isset($apiResult['data']) || !is_array($apiResult['data'])) {
    $errorMessage = $apiResult['data']['msg'] ?? 'Format respons API tidak sesuai atau gagal.';
    echo "Respons API (gagal):\n"; print_r($apiResult); die("Error dari API Provider: " . htmlspecialchars($errorMessage));
}

$apiServices = $apiResult['data'];
echo "API Sukses! Jumlah layanan diterima: " . count($apiServices) . "\n";
echo "Memulai proses sinkronisasi ke database lokal...\n";

$categoriesAdded = 0;
$servicesAdded = 0;
$servicesUpdated = 0;
$servicesDeactivated = 0;
$servicesSkipped = 0;
$localCategories = []; 
$processedProviderServiceIds = []; 
$pdo->beginTransaction();

try {
    $stmtCheckCat = $pdo->prepare("SELECT id FROM categories WHERE name = :name LIMIT 1");
    $stmtInsertCat = $pdo->prepare("INSERT INTO categories (name, status, icon_class) VALUES (:name, 'active', :icon)");
    $stmtCheckSvc = $pdo->prepare("SELECT id, name, price_per_1000, min_order, max_order, note, status FROM services WHERE provider_id = :pid AND provider_service_id = :psid LIMIT 1");
    $stmtInsertSvc = $pdo->prepare("INSERT INTO services (category_id, provider_id, provider_service_id, name, note, price_per_1000, min_order, max_order, status, created_at, updated_at) VALUES (:cid, :pid, :psid, :name, :note, :price, :min, :max, 'active', NOW(), NOW())");
    $stmtUpdateSvc = $pdo->prepare("UPDATE services SET category_id = :cid, name = :name, note = :note, price_per_1000 = :price, min_order = :min, max_order = :max, status = 'active', updated_at = NOW() WHERE id = :id");

    foreach ($apiServices as $apiService) {
        if (!isset($apiService['id'], $apiService['category_name'], $apiService['service_name'], $apiService['price'], $apiService['min'], $apiService['max'])) {
            echo "WARNING: Melewati layanan karena data tidak lengkap: ID Provider " . ($apiService['id'] ?? 'N/A') . "\n";
            $servicesSkipped++;
            continue;
        }

        $providerServiceId = $apiService['id'];
        $categoryName = trim($apiService['category_name']);
        $serviceName = trim($apiService['service_name']);
        $price = $apiService['price'];
        $rate = $apiService['rate'] ?? 1000;
        $pricePer1000 = is_numeric($price) && is_numeric($rate) && $rate != 0 ? round(($price / $rate) * 1000, 2) : 0;
        $minOrder = filter_var($apiService['min'], FILTER_VALIDATE_INT) ?: 0;
        $maxOrder = filter_var($apiService['max'], FILTER_VALIDATE_INT) ?: 0;
        $note = $apiService['description'] ?? null;

        $processedProviderServiceIds[] = $providerServiceId;

        $localCategoryId = null;
        if (isset($localCategories[$categoryName])) {
            $localCategoryId = $localCategories[$categoryName];
        } else {
            $stmtCheckCat->bindParam(':name', $categoryName);
            $stmtCheckCat->execute();
            $existingCategory = $stmtCheckCat->fetch(PDO::FETCH_ASSOC);
            if ($existingCategory) {
                $localCategoryId = $existingCategory['id'];
            } else {
                $iconClass = 'fas fa-star'; 
                if (stripos($categoryName, 'instagram') !== false) $iconClass = 'fab fa-instagram'; elseif (stripos($categoryName, 'facebook') !== false) $iconClass = 'fab fa-facebook'; elseif (stripos($categoryName, 'tiktok') !== false) $iconClass = 'fab fa-tiktok'; elseif (stripos($categoryName, 'youtube') !== false) $iconClass = 'fab fa-youtube';

                $stmtInsertCat->bindParam(':name', $categoryName);
                $stmtInsertCat->bindParam(':icon', $iconClass);
                if ($stmtInsertCat->execute()) {
                    $localCategoryId = $pdo->lastInsertId();
                    $categoriesAdded++;
                    echo "INFO: Kategori baru: '{$categoryName}' (ID: {$localCategoryId})\n";
                } else {
                    echo "ERROR: Gagal insert kategori '{$categoryName}'.\n";
                    $servicesSkipped++; continue;
                }
            }
            $localCategories[$categoryName] = $localCategoryId;
        }

        if ($localCategoryId) {
            $stmtCheckSvc->bindParam(':pid', $providerId, PDO::PARAM_INT);
            $stmtCheckSvc->bindParam(':psid', $providerServiceId);
            $stmtCheckSvc->execute();
            $existingService = $stmtCheckSvc->fetch(PDO::FETCH_ASSOC);

            $needsUpdate = false;
            if ($existingService) {
                if ( $existingService['name'] != $serviceName || $existingService['status'] != 'active' ) { $needsUpdate = true; }
                if ($needsUpdate) {
                    $stmtUpdateSvc->bindParam(':cid', $localCategoryId, PDO::PARAM_INT); $stmtUpdateSvc->bindParam(':name', $serviceName); $stmtUpdateSvc->bindParam(':note', $note); $stmtUpdateSvc->bindParam(':price', $pricePer1000); $stmtUpdateSvc->bindParam(':min', $minOrder, PDO::PARAM_INT); $stmtUpdateSvc->bindParam(':max', $maxOrder, PDO::PARAM_INT); $stmtUpdateSvc->bindParam(':id', $existingService['id'], PDO::PARAM_INT);
                    if ($stmtUpdateSvc->execute()) { $servicesUpdated++; } else {  $servicesSkipped++; }
                } else { $servicesSkipped++; }
            } else {
                $stmtInsertSvc->bindParam(':cid', $localCategoryId, PDO::PARAM_INT); $stmtInsertSvc->bindParam(':pid', $providerId, PDO::PARAM_INT); $stmtInsertSvc->bindParam(':psid', $providerServiceId); $stmtInsertSvc->bindParam(':name', $serviceName); $stmtInsertSvc->bindParam(':note', $note); $stmtInsertSvc->bindParam(':price', $pricePer1000); $stmtInsertSvc->bindParam(':min', $minOrder, PDO::PARAM_INT); $stmtInsertSvc->bindParam(':max', $maxOrder, PDO::PARAM_INT);
                if ($stmtInsertSvc->execute()) { $servicesAdded++;  } else {  $servicesSkipped++; }
            }
        }
    } 

    if (!empty($processedProviderServiceIds)) {
        $placeholders = implode(',', array_fill(0, count($processedProviderServiceIds), '?'));
        $sqlDeactivate = "UPDATE services SET status = 'inactive', updated_at = NOW() WHERE provider_id = ? AND provider_service_id NOT IN ($placeholders) AND status = 'active'";
        $stmtDeactivate = $pdo->prepare($sqlDeactivate);
        $params = array_merge([$providerId], $processedProviderServiceIds);
        if ($stmtDeactivate->execute($params)) { $servicesDeactivated = $stmtDeactivate->rowCount(); if ($servicesDeactivated > 0) { /* echo ... */ } }
        else {  
            echo "ERROR: Gagal deactivate services.\n";
            $servicesSkipped += $stmtDeactivate->rowCount();
        }
    }

    $pdo->commit();
    echo "\n=====================================\n";
    echo "Sinkronisasi Selesai!\n";

} catch (\Exception $e) {
    if ($pdo->inTransaction()) { $pdo->rollBack(); } 
    echo "\n=====================================\n";
    echo "ERROR SELAMA SINKRONISASI!\n";
    die("Proses dihentikan.");
}

echo "</pre>";
?>
