<?php
/**
 * Fichier  : api/import.php
 * Auteur   : KREMER Régis
 * Version  : 2.2.0
 * Date     : 2026-02-21
 * Description : API REST — Import de produits en masse via fichier CSV
 *
 * Changelog :
 *   v2.2.0 (2026-02-21) — Création : import CSV avec validation, dry-run, rapport d'erreurs
 *
 * Format CSV attendu (séparateur ; ou ,) :
 *   name;sku;barcode;brand;category;description;cost;unitType;safetyStock
 *   Colonnes obligatoires : name
 *   Colonnes optionnelles : toutes les autres
 */
require_once dirname(__DIR__).'/config.php';
startSession(); requireAdmin();
header('Content-Type: application/json; charset=utf-8');

$method = $_SERVER['REQUEST_METHOD'];
if ($method !== 'POST') jsonError('Méthode non supportée.', 405);
csrfCheck();

// ── Read uploaded CSV ─────────────────────────────────────────────────────────
$mode = $_POST['mode'] ?? 'import'; // 'dryrun' or 'import'

if (empty($_FILES['csv']) || $_FILES['csv']['error'] !== UPLOAD_ERR_OK) {
    jsonError('Fichier CSV requis.');
}

$tmpPath = $_FILES['csv']['tmp_name'];
$rawName = $_FILES['csv']['name'];

// Security: check extension
$ext = strtolower(pathinfo($rawName, PATHINFO_EXTENSION));
if (!in_array($ext, ['csv', 'txt'])) {
    jsonError('Seuls les fichiers .csv et .txt sont acceptés.');
}

// Read file — handle BOM and detect separator
$raw = file_get_contents($tmpPath);
if ($raw === false) jsonError('Impossible de lire le fichier.');

// Strip UTF-8 BOM
if (substr($raw, 0, 3) === "\xEF\xBB\xBF") $raw = substr($raw, 3);

$lines = preg_split('/\r?\n/', trim($raw));
if (count($lines) < 2) jsonError('Le fichier doit contenir au moins une ligne d\'en-tête et une ligne de données.');

// Detect separator (; or ,)
$header = $lines[0];
$sep = (substr_count($header, ';') >= substr_count($header, ',')) ? ';' : ',';

// Parse header
$cols = array_map('trim', str_getcsv($header, $sep));
$colMap = array_flip(array_map('strtolower', $cols));

// Required column
if (!isset($colMap['name']) && !isset($colMap['nom'])) {
    jsonError('Colonne "name" (ou "nom") obligatoire dans le CSV.');
}

// Column aliases (FR/EN)
$aliases = [
    'name'        => ['name', 'nom', 'produit'],
    'sku'         => ['sku', 'reference', 'réference', 'ref'],
    'barcode'     => ['barcode', 'codebarre', 'code-barre', 'ean', 'upc'],
    'brand'       => ['brand', 'marque'],
    'category'    => ['category', 'categorie', 'catégorie'],
    'description' => ['description', 'desc'],
    'cost'        => ['cost', 'cout', 'coût', 'prix', 'price'],
    'unitType'    => ['unittype', 'unite', 'unité', 'unit'],
    'safetyStock' => ['safetystock', 'stockmin', 'stock_min', 'seuil', 'minimum'],
    'supplier'    => ['supplier', 'fournisseur'],
];

function resolveCol(array $aliases, array $colMap, string $field): ?int {
    foreach ($aliases[$field] as $alias) {
        if (isset($colMap[$alias])) return $colMap[$alias];
    }
    return null;
}

$fieldIndexes = [];
foreach ($aliases as $field => $_) {
    $fieldIndexes[$field] = resolveCol($aliases, $colMap, $field);
}

// Parse data rows
$existingProducts = loadData('products');
$existingSKUs     = array_flip(array_filter(array_column($existingProducts, 'sku')));
$existingBarcodes = array_flip(array_filter(array_column($existingProducts, 'barcode')));
$categories       = loadData('categories');
$categoryNames    = array_flip(array_column($categories, 'name'));

$results   = [];
$toImport  = [];
$created   = 0;
$skipped   = 0;
$errors    = 0;

for ($i = 1; $i < count($lines); $i++) {
    $line = trim($lines[$i]);
    if ($line === '') continue;

    $cells = str_getcsv($line, $sep);

    // Pad to header length
    while (count($cells) < count($cols)) $cells[] = '';

    $get = fn($field) => isset($fieldIndexes[$field]) && $fieldIndexes[$field] !== null
        ? trim($cells[$fieldIndexes[$field]] ?? '')
        : '';

    $name    = $get('name');
    $sku     = $get('sku');
    $barcode = $get('barcode');

    if ($name === '') {
        $results[] = ['line' => $i + 1, 'status' => 'error', 'message' => 'Nom vide', 'name' => ''];
        $errors++;
        continue;
    }

    // Check for duplicate SKU
    if ($sku !== '' && isset($existingSKUs[$sku])) {
        $results[] = ['line' => $i + 1, 'status' => 'skip', 'message' => "SKU '$sku' déjà existant", 'name' => $name];
        $skipped++;
        continue;
    }

    // Check for duplicate barcode
    if ($barcode !== '' && isset($existingBarcodes[$barcode])) {
        $results[] = ['line' => $i + 1, 'status' => 'skip', 'message' => "Code-barre '$barcode' déjà existant", 'name' => $name];
        $skipped++;
        continue;
    }

    $cost        = (float)str_replace(',', '.', $get('cost'));
    $safetyStock = (float)str_replace(',', '.', $get('safetyStock'));
    $unitType    = $get('unitType') ?: 'piece';
    $category    = $get('category');
    $brand       = $get('brand');

    // Auto-create category if needed (in import mode)
    if ($category !== '' && !isset($categoryNames[$category]) && $mode === 'import') {
        $newCat = addItem('categories', ['name' => $category, 'color' => '#6c757d', 'icon' => '📦']);
        $categoryNames[$category] = $newCat['id'];
        $categories[] = $newCat;
    }

    $product = [
        'name'         => $name,
        'sku'          => $sku,
        'barcode'      => $barcode,
        'brand'        => $brand,
        'category'     => $category,
        'description'  => $get('description'),
        'cost'         => $cost,
        'unitType'     => $unitType,
        'packBaseUnit' => $unitType,
        'safetyStock'  => $safetyStock ?: null,
        'cump'         => $cost,
        'costByUnit'   => [],
        'trackLot'     => false,
        'trackExpiry'  => false,
        'image'        => '',
        'datasheetUrl' => '',
        'msdsUrl'      => '',
    ];

    $results[]  = ['line' => $i + 1, 'status' => 'ok', 'message' => 'OK', 'name' => $name, 'sku' => $sku];
    $toImport[] = $product;
    $created++;

    // Update duplicate check sets
    if ($sku     !== '') $existingSKUs[$sku]         = true;
    if ($barcode !== '') $existingBarcodes[$barcode] = true;
}

// If dry-run, return report without persisting
if ($mode === 'dryrun') {
    jsonResponse([
        'mode'    => 'dryrun',
        'created' => $created,
        'skipped' => $skipped,
        'errors'  => $errors,
        'results' => $results,
    ]);
}

// Real import
foreach ($toImport as $p) {
    addItem('products', $p);
}

jsonResponse([
    'mode'    => 'import',
    'created' => $created,
    'skipped' => $skipped,
    'errors'  => $errors,
    'results' => $results,
]);
