<?php
// import_v2.php
require __DIR__ . '/../vendor/autoload.php';
require_once 'config/db.php';

use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;

// 1) Recuperar credenciales
function getCredentials($conn)
{
    $stmt = $conn->prepare("
        SELECT user_id, access_token, refresh_token, expires_in, updated_at
          FROM tb_marketplace_tokens
         WHERE idMP = 1
         ORDER BY updated_at DESC
         LIMIT 1
    ");
    $stmt->execute();
    $stmt->bind_result($user_id, $access_token, $refresh_token, $expires_in, $updated_at);
    $stmt->fetch();
    $stmt->close();
    return compact('user_id', 'access_token', 'refresh_token', 'expires_in', 'updated_at');
}

// 2) Refrescar token si caducó
function refreshTokenIfNeeded(Client $http, array &$creds, $conn)
{
    $expireTs = strtotime($creds['updated_at']) + $creds['expires_in'];
    if (time() < $expireTs - 60) {
        return;
    }
    $resp = $http->post('/oauth/token', [
        'form_params' => [
            'grant_type'    => 'refresh_token',
            'client_id'     => '3658695067033012',
            'client_secret' => 'GZBg63xJNM9Eeb2cOhF9JwsOEv6vTxo7',
            'refresh_token' => $creds['refresh_token'],
        ],
        'headers' => ['Accept' => 'application/json']
    ]);
    $data = json_decode($resp->getBody(), true);

    // Actualizar credenciales en BD
    $creds['access_token']  = $data['access_token'];
    $creds['refresh_token'] = $data['refresh_token'];
    $creds['expires_in']    = $data['expires_in'];

    $stmt = $conn->prepare("
        UPDATE tb_marketplace_tokens
           SET access_token=?, refresh_token=?, expires_in=?, updated_at=NOW()
         WHERE idMP = 1
    ");
    $stmt->bind_param(
        'ssis',
        $creds['access_token'],
        $creds['refresh_token'],
        $creds['expires_in'],
        $creds['user_id']
    );
    $stmt->execute();
    $stmt->close();
}

// 3) Importar todos los ítems usando SCAN + scroll_id
function importAllItems($conn)
{
    $creds = getCredentials($conn);
    if (empty($creds['access_token'])) {
        die("No hay token en tb_tokens. Ejecuta authorize.php primero.\n");
    }
    $http = new Client([
        'base_uri' => 'https://api.mercadolibre.com',
        'timeout'  => 30
    ]);

    session_start();
    refreshTokenIfNeeded($http, $creds, $conn);

    $token = $creds['access_token'];
    $user  = $creds['user_id'];
    $limit = 50;

    // Primera petición (scan sin offset)
    $resp = $http->get("/users/{$user}/items/search", [
        'headers' => [
            'Authorization' => "Bearer {$token}",
            'Accept'        => 'application/json',
        ],
        'query' => [
            'search_type' => 'scan',
            'limit'       => $limit,
            // opcional: 'status'=>'active'|'paused'|'closed'
        ]
    ]);
    $data     = json_decode($resp->getBody(), true);
    $total    = intval($data['paging']['total'] ?? 0);
    $results  = $data['results'] ?? [];
    $scrollId = $data['scroll_id'] ?? null;

    if ($total < 1) {
        echo "No hay productos para importar.\n";
        return;
    }
    echo "Total de productos a importar: {$total}\n";

    // Bucle de scroll
    while (!empty($results)) {
        // Procesar lote de IDs
        $chunks = array_chunk($results, 20);
        foreach ($chunks as $c) {
            $batchResp = $http->get('/items', [
                'headers' => [
                    'Authorization' => "Bearer {$token}",
                    'Accept'        => 'application/json',
                ],
                'query' => [
                    'ids' => implode(',', $c),
                ]
            ]);
            $batch = json_decode($batchResp->getBody(), true);
            foreach ($batch as $entry) {
                saveOrUpdateProduct($conn, $entry['body'], $http, $token);
            }
        }
        echo "  Procesados " . count($results) . " ítems (scroll)\n";

        // Siguiente página con scroll_id
        if (!$scrollId) {
            break;
        }
        $resp    = $http->get("/users/{$user}/items/search", [
            'headers' => [
                'Authorization' => "Bearer {$token}",
                'Accept'        => 'application/json',
            ],
            'query' => [
                'search_type' => 'scan',
                'scroll_id'   => $scrollId,
                'limit'       => $limit,
                // opcional: 'status'=>'active'
            ]
        ]);
        $data     = json_decode($resp->getBody(), true);
        $results  = $data['results'] ?? [];
        $scrollId = $data['scroll_id'] ?? null;
    }

    echo "Importación completada: {$total} ítems procesados.\n";
}

/**
 * Extrae el SKU principal de un ítem.
 */
function extractSkuBase(array $item): string
{
    if (!empty($item['attributes'])) {
        foreach ($item['attributes'] as $attr) {
            if (($attr['id'] ?? '') === 'SELLER_SKU') {
                return $attr['value_name'] ?? '';
            }
        }
    }
    if (!empty($item['seller_custom_field'])) {
        return $item['seller_custom_field'];
    }
    // (fallback) primera variación...
    if (!empty($item['variations'][0]['seller_custom_field'])) {
        return $item['variations'][0]['seller_custom_field'];
    }
    return '';
}

/**
 * Extrae el SKU de una variación.
 */
function extractVariantSku(array $variation): string
{
    if (!empty($variation['attributes'])) {
        foreach ($variation['attributes'] as $attr) {
            if (($attr['id'] ?? '') === 'SELLER_SKU') {
                return $attr['value_name'] ?? '';
            }
        }
    }
    return $variation['seller_custom_field'] ?? '';
}

// 4) Guardar/actualizar producto individual e incluir descripción
function saveOrUpdateProduct($conn, $p, Client $http, $token)
{
    $id          = $p['id'];
    $title       = $p['title'];
    $category_id = $p['category_id'];
    $price       = $p['price'] ?? 0.0;
    $status      = $p['status'] ?? '';
    $have_variants = !empty($p['variations']) ? 1 : 0;

    // **Obtener la descripción** (endpoint dedicado)
    try {
        $descResp = $http->get("/items/{$id}/description", [
            'headers' => [
                'Authorization' => "Bearer {$token}",
                'Accept'        => 'application/json',
            ]
        ]);
        $descData    = json_decode($descResp->getBody(), true);
        $description = $descData['plain_text'] ?? '';
    } catch (\Exception $e) {
        // Si falla (sin descripción), dejar vacío
        $description = '';
    }

    // Extraer SKU
    $sku = extractSkuBase($p);

    // Obtener listing prices
    $listingResp = $http->get('/sites/MCO/listing_prices', [
        'query'   => ['price' => $price, 'category_id' => $category_id],
        'headers' => ['Accept' => 'application/json']
    ]);
    $lpData = json_decode($listingResp->getBody(), true);
    if (isset($lpData['listing_type_id'])) {
        $lpData = [$lpData];
    }
    $first = $lpData[0] ?? [];

    // Mapear cargos
    $listing_type_id      = $first['listing_type_id']       ?? null;
    $listing_fee_amount   = (float)($first['listing_fee_amount'] ?? 0);
    $sale_fee_amount      = (float)($first['sale_fee_amount']    ?? 0);
    $currency_id          = $first['currency_id']           ?? null;
    $details              = $first['sale_fee_details']      ?? [];
    $financing_add_fee    = (float)($details['financing_add_on_fee']  ?? 0);
    $fixed_fee            = (float)($details['fixed_fee']             ?? 0);
    $gross_amount         = (float)($details['gross_amount']          ?? 0);
    $meli_percentage_fee  = (float)($details['meli_percentage_fee']   ?? 0);
    $percentage_fee       = (float)($details['percentage_fee']        ?? 0);

    // INSERT / UPDATE en tb_products (incluye description)
    $sql = "
        INSERT INTO tb_products (
            id, title, description, category_id, price, sku, status, have_variants,
            listing_type_id, listing_fee_amount, sale_fee_amount, currency_id,
            financing_add_on_fee, fixed_fee, gross_amount, meli_percentage_fee, percentage_fee
        ) VALUES (
            ?, ?, ?, ?, ?, ?, ?, ?,
            ?, ?, ?, ?,
            ?, ?, ?, ?, ?
        )
        ON DUPLICATE KEY UPDATE
            title=VALUES(title),
            description=VALUES(description),
            category_id=VALUES(category_id),
            price=VALUES(price),
            sku=VALUES(sku),
            status=VALUES(status),
            have_variants=VALUES(have_variants),
            listing_type_id=VALUES(listing_type_id),
            listing_fee_amount=VALUES(listing_fee_amount),
            sale_fee_amount=VALUES(sale_fee_amount),
            currency_id=VALUES(currency_id),
            financing_add_on_fee=VALUES(financing_add_on_fee),
            fixed_fee=VALUES(fixed_fee),
            gross_amount=VALUES(gross_amount),
            meli_percentage_fee=VALUES(meli_percentage_fee),
            percentage_fee=VALUES(percentage_fee)
    ";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param(
        "ssssdssisddsddddd",
        $id,
        $title,
        $description,
        $category_id,
        $price,
        $sku,
        $status,
        $have_variants,
        $listing_type_id,
        $listing_fee_amount,
        $sale_fee_amount,
        $currency_id,
        $financing_add_fee,
        $fixed_fee,
        $gross_amount,
        $meli_percentage_fee,
        $percentage_fee
    );
    $stmt->execute();
    if ($stmt->error) {
        echo "[ERROR exec tb_products] {$stmt->error}\n";
    }
    $stmt->close();

    // Guardar variantes
    if (!empty($p['variations'])) {
        foreach ($p['variations'] as $variation) {
            saveVariant($conn, $id, $variation);
        }
    }
}

// 5) Guardar cada variación
function saveVariant($conn, $product_id, $variation)
{
    $skuVar     = extractVariantSku($variation);
    $variant_id = $variation['id'];
    $status     = $variation['status']             ?? '';
    $stock      = (int)($variation['available_quantity'] ?? 0);
    $price      = (float)($variation['price']          ?? 0.0);
    $color      = '';
    foreach ($variation['attribute_combinations'] ?? [] as $a) {
        if (($a['id'] ?? '') === 'COLOR') {
            $color = $a['value_name'] ?? '';
            break;
        }
    }

    $stmt = $conn->prepare("
        INSERT INTO tb_product_variants
            (product_id, variant_id, sku, status, stock, price, color)
        VALUES (?, ?, ?, ?, ?, ?, ?)
        ON DUPLICATE KEY UPDATE
            status=VALUES(status),
            stock=VALUES(stock),
            price=VALUES(price),
            color=VALUES(color)
    ");
    $stmt->bind_param(
        "ssssids",
        $product_id,
        $variant_id,
        $skuVar,
        $status,
        $stock,
        $price,
        $color
    );
    $stmt->execute();
    $stmt->close();
}

// ▶️ Ejecutar
importAllItems($conn);
$conn->close();
