<?php
declare(strict_types=1);

/**
 * Fix GS1 brandName for all products.
 *
 * Fetches all products from MojeGS1 API, finds those with wrong brandName,
 * and updates them to the correct brand.
 *
 * Usage:
 *   php bin/fix_gs1_brand.php [correct_brand]
 *
 * Default correct brand: pomysloweprezenty.pl
 */

$correctBrand = $argv[1] ?? 'pomysloweprezenty.pl';

// --- Load credentials from .env + DB ---
$login = '';
$password = '';

$envFile = dirname(__DIR__) . '/.env';
$env = [];
if (is_file($envFile)) {
    foreach (file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
        $line = trim($line);
        if ($line === '' || $line[0] === '#') {
            continue;
        }
        $pos = strpos($line, '=');
        if ($pos === false) {
            continue;
        }
        $env[trim(substr($line, 0, $pos))] = trim(trim(substr($line, $pos + 1)), "\"'");
    }
}

try {
    $pdo = new PDO(
        sprintf(
            'mysql:host=%s;port=%s;dbname=%s;charset=utf8mb4',
            $env['DB_HOST'] ?? '127.0.0.1',
            $env['DB_PORT'] ?? '3306',
            $env['DB_DATABASE'] ?? 'orderpro'
        ),
        $env['DB_USERNAME'] ?? 'root',
        $env['DB_PASSWORD'] ?? '',
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
    );

    $stmt = $pdo->prepare('SELECT setting_key, setting_value FROM app_settings WHERE setting_key IN (?, ?)');
    $stmt->execute(['gs1_api_login', 'gs1_api_password']);
    foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
        if ($row['setting_key'] === 'gs1_api_login') {
            $login = (string) $row['setting_value'];
        }
        if ($row['setting_key'] === 'gs1_api_password') {
            $password = (string) $row['setting_value'];
        }
    }
} catch (Throwable $e) {
    fwrite(STDERR, "Blad DB: " . $e->getMessage() . "\n");
}

if ($login === '' || $password === '') {
    fwrite(STDERR, "Brak credentials GS1. Sprawdz ustawienia w bazie.\n");
    exit(1);
}

echo "Correct brand: {$correctBrand}\n";
echo "Pobieram produkty z GS1...\n\n";

// --- Fetch all products ---
$allProducts = [];
$page = 1;
$limit = 100;

do {
    $url = "https://mojegs1.pl/api/v2/products?page[offset]={$page}&page[limit]={$limit}&sort=name";
    $response = gs1Request('GET', $url, $login, $password);

    if ($response['status'] < 200 || $response['status'] >= 300) {
        fwrite(STDERR, "Blad pobierania listy (HTTP {$response['status']}): {$response['body']}\n");
        exit(1);
    }

    $decoded = json_decode($response['body'], true);
    $items = is_array($decoded['data'] ?? null) ? $decoded['data'] : [];
    $total = (int) ($decoded['meta']['record-count'] ?? 0);

    foreach ($items as $item) {
        $allProducts[] = $item;
    }

    echo "  Strona {$page}: pobrano " . count($items) . " produktow (lacznie: " . count($allProducts) . " / {$total})\n";
    $page++;
} while (count($items) >= $limit);

echo "\nLacznie pobrano: " . count($allProducts) . " produktow\n\n";

// --- Find and fix products with wrong brand ---
$updated = 0;
$skipped = 0;
$errors = 0;

foreach ($allProducts as $item) {
    $gtin = (string) ($item['id'] ?? '');
    $attrs = is_array($item['attributes'] ?? null) ? $item['attributes'] : [];
    $currentBrand = (string) ($attrs['brandName'] ?? '');

    if ($gtin === '') {
        continue;
    }

    if ($currentBrand === $correctBrand) {
        $skipped++;
        continue;
    }

    echo "  [{$gtin}] brandName: \"{$currentBrand}\" -> \"{$correctBrand}\"";

    $putUrl = "https://mojegs1.pl/api/v2/products/" . urlencode($gtin);
    $payload = json_encode([
        'data' => [
            'type' => 'products',
            'id' => $gtin,
            'attributes' => [
                'brandName' => $correctBrand,
            ],
        ],
    ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

    $putResponse = gs1Request('PUT', $putUrl, $login, $password, $payload);

    if ($putResponse['status'] >= 200 && $putResponse['status'] < 300) {
        echo " OK\n";
        $updated++;
    } else {
        echo " BLAD (HTTP {$putResponse['status']}): " . mb_substr($putResponse['body'], 0, 200) . "\n";
        $errors++;
    }
}

echo "\n--- Podsumowanie ---\n";
echo "Zaktualizowano: {$updated}\n";
echo "Pominieto (juz OK): {$skipped}\n";
echo "Bledy: {$errors}\n";

// --- HTTP helper ---
function gs1Request(string $method, string $url, string $login, string $password, ?string $body = null): array
{
    $curl = curl_init($url);
    if ($curl === false) {
        return ['status' => 0, 'body' => 'cURL init failed', 'error' => 'init'];
    }

    $headers = ['Accept: application/json'];
    if ($body !== null) {
        $headers[] = 'Content-Type: application/json';
    }

    curl_setopt_array($curl, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_USERPWD => $login . ':' . $password,
        CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_CONNECTTIMEOUT => 10,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_SSL_VERIFYHOST => 2,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_MAXREDIRS => 5,
        CURLOPT_CUSTOMREQUEST => $method,
    ]);

    if ($body !== null) {
        curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
    }

    $responseBody = curl_exec($curl);
    $httpCode = (int) curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
    $error = curl_error($curl);
    curl_close($curl);

    return [
        'status' => $httpCode,
        'body' => is_string($responseBody) ? $responseBody : '',
        'error' => $error,
    ];
}
