<?php
/**
 * csv2xml_new.php — konwersja CSV (podana struktura; delimiter ;) -> XML
 * HTTP:  csv2xml_new.php?url=URL_CSV[&filename=produkty.xml][&download=1]
 * CLI:   php csv2xml_new.php URL_CSV [produkty.xml]
 */
declare(strict_types=1);

$isCli = (php_sapi_name() === 'cli');

if ($isCli) {
    if ($argc < 2) {
        fwrite(STDERR, "Użycie: php {$argv[0]} URL [plik_wyjściowy.xml]\n");
        exit(1);
    }
    $csvUrl   = $argv[1];
    $outName  = $argv[2] ?? 'produkty.xml';
    $download = false;
} else {
    if (!isset($_GET['url']) || !filter_var($_GET['url'], FILTER_VALIDATE_URL)) {
        http_response_code(400);
        echo "Parametr ?url= jest wymagany i musi być poprawnym URL-em.";
        exit;
    }
    $csvUrl  = $_GET['url'];
    $outName = isset($_GET['filename']) && preg_match('/^[\w\-.]+$/', $_GET['filename']) ? $_GET['filename'] : 'produkty.xml';
    $download = isset($_GET['download']) && $_GET['download'] == '1';
}

// ─────────────────────────────────────────────────────────────────────────────
// 1) Pobranie CSV (bez łamania wielowierszowych pól) + zapis do temp
// ─────────────────────────────────────────────────────────────────────────────
$csvRaw = @file_get_contents($csvUrl);
if ($csvRaw === false) {
    $err = error_get_last();
    $msg = $err['message'] ?? 'Nieznany błąd pobierania CSV.';
    if ($isCli) fwrite(STDERR, "Błąd pobierania CSV: $msg\n"); else { http_response_code(502); echo "Błąd pobierania CSV: $msg"; }
    exit(1);
}
$csvRaw = preg_replace('/^\xEF\xBB\xBF/', '', $csvRaw);
if (!mb_check_encoding($csvRaw, 'UTF-8')) {
    $csvRaw = @iconv('WINDOWS-1250', 'UTF-8//TRANSLIT', $csvRaw) ?: $csvRaw;
}
$tmpFile = tempnam(sys_get_temp_dir(), 'csv2xml_');
file_put_contents($tmpFile, $csvRaw);

// ─────────────────────────────────────────────────────────────────────────────
// 2) Odczyt CSV fgetcsv (delimiter ;, enclosure ", obsługa wielowierszowości)
// ─────────────────────────────────────────────────────────────────────────────
$fh = fopen($tmpFile, 'r');
if ($fh === false) {
    if ($isCli) fwrite(STDERR, "Nie można otworzyć pliku tymczasowego.\n"); else { http_response_code(500); echo "Nie można otworzyć pliku tymczasowego."; }
    @unlink($tmpFile);
    exit(1);
}
$rows = [];
while (($row = fgetcsv($fh, 0, ';', '"', '\\')) !== false) {
    if (count($row) === 1 && trim((string)$row[0]) === '') continue;
    $rows[] = $row;
}
fclose($fh);
@unlink($tmpFile);
if (count($rows) < 2) {
    $msg = "CSV nie zawiera danych (brakuje nagłówków lub wierszy).";
    if ($isCli) fwrite(STDERR, $msg . PHP_EOL); else { http_response_code(422); echo $msg; }
    exit(1);
}

// ─────────────────────────────────────────────────────────────────────────────
// 3) Nagłówki + mapowanie do bezpiecznych tagów XML
// ─────────────────────────────────────────────────────────────────────────────
$headers = array_map(function ($h) { return trim((string)$h); }, $rows[0]);
$dataRows = array_slice($rows, 1);

// Napraw znane literówki/nawiasy
$headerFix = function(string $h): string {
    $h = preg_replace('/\}\s*$/', ']', $h);
    $h = preg_replace('/\s+;$/', '', $h);
    $h = preg_replace('/\s{2,}/', ' ', $h);
    return trim($h);
};
$headers = array_map($headerFix, $headers);

function normalize_tag_name(string $name): string {
    $map = ['ą'=>'a','ć'=>'c','ę'=>'e','ł'=>'l','ń'=>'n','ó'=>'o','ś'=>'s','ż'=>'z','ź'=>'z',
            'Ą'=>'A','Ć'=>'C','Ę'=>'E','Ł'=>'L','Ń'=>'N','Ó'=>'O','Ś'=>'S','Ż'=>'Z','Ź'=>'Z'];
    $name = strtr($name, $map);
    $name = preg_replace('/[^\p{L}\p{N}\s_-]+/u', ' ', $name);
    $name = preg_replace('/\s+/', '_', $name);
    $name = preg_replace('/_+/', '_', $name);
    $name = trim($name, '_');
    if ($name === '') $name = 'field';
    if (preg_match('/^\d/', $name)) $name = 'f_' . $name;
    return $name;
}
$tagMap = [];
foreach ($headers as $h) {
    $tagMap[$h] = normalize_tag_name($h);
}

// ▶ WYZNACZ INDEKS KOLUMNY "SYMBOL" (case-insensitive)
$symbolIdx = null;
foreach ($headers as $i => $h) {
    if (mb_strtoupper($h, 'UTF-8') === 'SYMBOL') { $symbolIdx = $i; break; }
}
if ($symbolIdx === null) {
    // Jeśli nie ma kolumny SYMBOL, to lepiej przerwać niż eksportować niekompletne dane
    $msg = "Nie znaleziono kolumny 'SYMBOL' w nagłówkach CSV.";
    if ($isCli) { fwrite(STDERR, $msg . PHP_EOL); exit(1); }
    http_response_code(422);
    echo $msg;
    exit;
}

// ─────────────────────────────────────────────────────────────────────────────
// 4) Helpery
// ─────────────────────────────────────────────────────────────────────────────
function looks_like_html_or_multiline(string $v): bool {
    if (strpos($v, "\n") !== false || strpos($v, "\r") !== false) return true;
    return (bool) preg_match('/<[^>]+>|\&(?:nbsp|lt|gt|amp|quot|#\d+);/i', $v);
}
function addChildWithCDATA(SimpleXMLElement $parent, string $name, string $val): SimpleXMLElement {
    $child = $parent->addChild($name);
    $node  = dom_import_simplexml($child);
    if ($node) $node->appendChild($node->ownerDocument->createCDATASection($val));
    return $child;
}
function is_photo_header(string $h): bool {
    return (bool) preg_match('/(foto|packshot)/i', $h);
}
function split_possible_photos(string $v): array {
    $parts = preg_split('/[;\|,\s]+/u', trim($v));
    $parts = array_values(array_filter(array_map('trim', $parts), fn($x) => $x !== ''));
    return $parts;
}

// ─────────────────────────────────────────────────────────────────────────────
// 5) Budowa XML (pomijamy wiersze bez SYMBOL)
// ─────────────────────────────────────────────────────────────────────────────
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><Products/>');

$skippedNoSymbol = 0;
$exported = 0;

foreach ($dataRows as $row) {
    if (count($row) < count($headers)) $row = array_pad($row, count($headers), '');

    // ---- SPRAWDŹ SYMBOL ----
    $symbolRaw = isset($row[$symbolIdx]) ? (string)$row[$symbolIdx] : '';
    // usuń białe znaki (także wewnątrz) — jeśli po tym jest pusto, pomijamy
    $symbolClean = preg_replace('/\s+/', '', trim($symbolRaw));
    if ($symbolClean === '' || $symbolClean === null) {
        $skippedNoSymbol++;
        continue; // POMIŃ produkt
    }

    $product = $xml->addChild('Product');
    $photosCollected = [];

    foreach ($headers as $i => $header) {
        $rawVal = isset($row[$i]) ? (string)$row[$i] : '';
        $val    = trim($rawVal);
        $tag    = $tagMap[$header] ?? ('field_' . $i);

        if (is_photo_header($header)) {
            if ($val !== '') {
                foreach (split_possible_photos($val) as $u) $photosCollected[] = $u;
            }
            continue;
        }

        if ($val === '') { $product->addChild($tag, ''); continue; }

        if (looks_like_html_or_multiline($val) || preg_match('/\bopis\b/i', $header)) {
            addChildWithCDATA($product, $tag, $val);
        } else {
            if (preg_match('/^(EAN|SYMBOL)$/ui', $header)) {
                $val = preg_replace('/\s+/', '', $val);
            }
            $product->addChild($tag, $val);
        }
    }

    if (!empty($photosCollected)) {
        $pNode = $product->addChild('Photos');
        foreach ($photosCollected as $p) $pNode->addChild('Photo', $p);
    }

    $exported++;
}

// Formatowanie ładnego XML
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($xml->asXML());

// ─────────────────────────────────────────────────────────────────────────────
// 6) Zapis wyniku (CLI → plik; HTTP → exports/ + JSON lub pobranie)
// ─────────────────────────────────────────────────────────────────────────────
if ($isCli) {
    if (@$dom->save($outName) === false) {
        fwrite(STDERR, "Nie udało się zapisać do pliku: {$outName}\n");
        exit(1);
    }
    echo "Zapisano XML do: {$outName}\n";
    echo "Wyeksportowano: {$exported}, pominięto (brak SYMBOL): {$skippedNoSymbol}\n";
    exit(0);
}

$saveDir = __DIR__ . DIRECTORY_SEPARATOR . 'exports';
if (!is_dir($saveDir)) {
    if (!@mkdir($saveDir, 0775, true) && !is_dir($saveDir)) {
        http_response_code(500);
        echo "Nie można utworzyć katalogu zapisu: {$saveDir}";
        exit;
    }
}
$outName = preg_match('/^[\w\-.]+$/', $outName) ? $outName : ('produkty_' . date('Ymd_His') . '.xml');
$savePath = $saveDir . DIRECTORY_SEPARATOR . $outName;

if (@$dom->save($savePath) === false) {
    http_response_code(500);
    echo "Nie udało się zapisać pliku: {$savePath}";
    exit;
}

$basePath  = rtrim(str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME'] ?? '/')), '/');
$publicRel = $basePath . '/exports/' . rawurlencode($outName);
$scheme    = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host      = $_SERVER['HTTP_HOST'] ?? '';
$publicUrl = $host ? ($scheme . '://' . $host . $publicRel) : $publicRel;

if ($download) {
    header('Content-Type: application/xml; charset=UTF-8');
    header('Content-Disposition: attachment; filename="'.$outName.'"');
    readfile($savePath);
    exit;
}

header('Content-Type: application/json; charset=UTF-8');
echo json_encode([
    'status'            => 'ok',
    'message'           => 'Plik XML zapisany na serwerze.',
    'file_path'         => $savePath,
    'file_url'          => $publicUrl,
    'filename'          => $outName,
    'exported'          => $exported,
    'skipped_no_symbol' => $skippedNoSymbol,
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
