<?php
/* =========================================================
   API: etiquetas_76x50.php  (TCPDF)
   - Soporta: 1..N etiquetas (qty)
   - Página LARGA por defecto (ideal rollo)
   - Si NO cabe, usa paginación por filas (rows_per_page)
   - Barcode C128 centrado REAL (barras + número)
   - No revienta si no existe mbstring (fallback)
   ========================================================= */

/* ========= DEBUG / ERRORES (para no tener 500 vacío) ========= */
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

set_error_handler(function ($severity, $message, $file, $line) {
    http_response_code(500);
    header('Content-Type: text/plain; charset=utf-8');
    echo "PHP ERROR: $message\nFILE: $file\nLINE: $line";
    exit;
});
set_exception_handler(function ($e) {
    http_response_code(500);
    header('Content-Type: text/plain; charset=utf-8');
    echo "PHP EXCEPTION: " . $e->getMessage() . "\n\n" . $e->getTraceAsString();
    exit;
});

require_once __DIR__ . '/../../tcpdf/tcpdf.php';

/* ========= HEALTHCHECK ========= */
if (isset($_GET['ping'])) {
    header('Content-Type: text/plain; charset=utf-8');
    echo 'OK';
    exit;
}

/* ========= INPUT ========= */
$payload = json_decode(file_get_contents('php://input'), true) ?: [];
$items   = $payload['items'] ?? [];
if (!$items || !is_array($items)) {
    http_response_code(400);
    die('JSON inválido: falta items');
}

/* ========= TAMAÑO ETIQUETA ========= */
$LABEL_W = isset($payload['label_w_mm']) ? (float)$payload['label_w_mm'] : 76.0;
$LABEL_H = isset($payload['label_h_mm']) ? (float)$payload['label_h_mm'] : 50.0;

/* ========= COLUMNAS / GAP ========= */
$COLUMNS = isset($payload['columns']) ? (int)$payload['columns'] : 1;
if ($COLUMNS < 1) $COLUMNS = 1;
if ($COLUMNS > 3) $COLUMNS = 3;

$GAP_X = isset($payload['gap_x_mm']) ? (float)$payload['gap_x_mm'] : 0.0;
$GAP_Y = isset($payload['gap_y_mm']) ? (float)$payload['gap_y_mm'] : 4.0; // tu separación vertical

/* ========= ANCHO PAPEL ========= */
$paperWidthMm = isset($payload['paper_width_mm']) ? (float)$payload['paper_width_mm'] : 76.0;

/* ========= OFFSETS / START ========= */
$START_COL   = max(0, (int)($payload['start_col'] ?? 0));
$START_ROW   = max(0, (int)($payload['start_row'] ?? 0));
$OFFSET_X    = (float)($payload['mm_left_offset'] ?? 0.0);
$OFFSET_Y    = (float)($payload['mm_top_offset']  ?? 0.0);
$DRAW_BORDER = !empty($payload['debug']);

/* ========= PAGINACIÓN =========
   - long_page=true: una sola página larga (lo normal para rollo)
   - long_page=false: páginas por filas (rows_per_page)
*/
$LONG_PAGE     = isset($payload['long_page']) ? (bool)$payload['long_page'] : true;
$ROWS_PER_PAGE = (int)($payload['rows_per_page'] ?? 2);  // 👈 por defecto 12 filas (12 etiquetas si 1 col)
if ($ROWS_PER_PAGE < 1) $ROWS_PER_PAGE = 2;

$MAX_PAGE_H_MM  = (float)($payload['max_page_mm'] ?? 1200.0); // driver límite
$EJECT_EXTRA_MM = (float)($payload['eject_extra_mm'] ?? ($LONG_PAGE ? 2.0 : 0.0));

/* ========= MÁRGENES ========= */
$MARGIN_L = 0.0;
$MARGIN_R = 0.0;
$MARGIN_T = 0.0;
$MARGIN_B = 0.0;

/* ========= DPI (alinear a pasos de punto) ========= */
$DPI = (int)($payload['dpi'] ?? 203);
if ($DPI < 100) $DPI = 203;
$DOT_STEP = 25.4 / $DPI;

$toDot = function ($mm) use ($DOT_STEP) {
    return round($mm / $DOT_STEP) * $DOT_STEP;
};

$LABEL_W  = $toDot($LABEL_W);
$LABEL_H  = $toDot($LABEL_H);
$GAP_X    = $toDot($GAP_X);
$GAP_Y    = $toDot($GAP_Y);
$OFFSET_X = $toDot($OFFSET_X);
$OFFSET_Y = $toDot($OFFSET_Y);

$PAGE_W   = $toDot($paperWidthMm);

/* ========= CENTRADO DE GRILLA (si papel > grilla) ========= */
$labelsPerRow = $COLUMNS;
$totalGridW   = $COLUMNS * $LABEL_W + ($COLUMNS - 1) * $GAP_X;
$innerPageW   = $PAGE_W - $MARGIN_L - $MARGIN_R;
$EXTRA_X      = 0.0;

if ($innerPageW > $totalGridW) {
    $EXTRA_X = $toDot(($innerPageW - $totalGridW) / 2.0);
}

/* ========= POSICIONES ========= */
$startColClamped = ($labelsPerRow > 0) ? min($START_COL, $labelsPerRow - 1) : 0;
$printedStart    = ($START_ROW * $labelsPerRow) + $startColClamped;

/* totalQty = cantidad total de etiquetas a imprimir */
$totalQty = 0;
foreach ($items as $it) {
    $q = (int)($it['qty'] ?? ($it['cantidad'] ?? 0));
    if ($q > 0) $totalQty += $q;
}
if ($totalQty < 1) {
    http_response_code(400);
    die('JSON inválido: qty total = 0');
}

$totalPositions = $printedStart + $totalQty;
$totalRows      = (int)ceil(max(1, $totalPositions) / max(1, $labelsPerRow));
if ($totalRows < 1) $totalRows = 1;

/* ========= PDF CREACIÓN ========= */
if ($LONG_PAGE) {

    $PAGE_H0 = $MARGIN_T + $MARGIN_B
        + ($totalRows * $LABEL_H)
        + (($totalRows - 1) * $GAP_Y);

    $PAGE_H = $toDot(min($PAGE_H0 + $EJECT_EXTRA_MM, $MAX_PAGE_H_MM));

    $pdf = new TCPDF('P', 'mm', [$PAGE_W, $PAGE_H], true, 'UTF-8', false);
    $pdf->setPrintHeader(false);
    $pdf->setPrintFooter(false);
    $pdf->SetMargins($MARGIN_L, $MARGIN_T, $MARGIN_R);
    $pdf->SetAutoPageBreak(false, 0);
    $pdf->SetDisplayMode('fullwidth', 'SinglePage');
    $pdf->setViewerPreferences([
        'FitWindow' => true, 'CenterWindow' => true, 'DisplayDocTitle' => true,
        'NonFullScreenPageMode' => 'UseNone', 'PrintScaling' => 'None',
        'ViewArea' => 'CropBox', 'ViewClip' => 'CropBox',
        'PrintArea' => 'CropBox', 'PrintClip' => 'CropBox'
    ]);
    $pdf->AddPage();

    $printed = $printedStart;

    foreach ($items as $it) {
        $qty = (int)($it['qty'] ?? ($it['cantidad'] ?? 0));
        if ($qty <= 0) continue;

        for ($i = 0; $i < $qty; $i++) {
            $pos = $printed;
            $row = (int)floor($pos / $labelsPerRow);
            $col = $pos % $labelsPerRow;

            $x = $MARGIN_L + $EXTRA_X + $OFFSET_X + $col * ($LABEL_W + $GAP_X);
            $y = $MARGIN_T + $OFFSET_Y + $row * ($LABEL_H + $GAP_Y);

            drawLabel76x50($pdf, $x, $y, $LABEL_W, $LABEL_H, $it, $DRAW_BORDER);
            $printed++;
        }
    }

} else {

    /* páginas por filas (ROWS_PER_PAGE) */
    $PAGE_H0 = $MARGIN_T + $MARGIN_B
        + ($ROWS_PER_PAGE * $LABEL_H)
        + (($ROWS_PER_PAGE - 1) * $GAP_Y);

    $PAGE_H = $toDot(min($PAGE_H0 + $EJECT_EXTRA_MM, $MAX_PAGE_H_MM));

    $pdf = new TCPDF('P', 'mm', [$PAGE_W, $PAGE_H], true, 'UTF-8', false);
    $pdf->setPrintHeader(false);
    $pdf->setPrintFooter(false);
    $pdf->SetMargins($MARGIN_L, $MARGIN_T, $MARGIN_R);
    $pdf->SetAutoPageBreak(false, 0);
    $pdf->SetDisplayMode('real', 'OneColumn');
    $pdf->setViewerPreferences([
        'FitWindow' => true, 'CenterWindow' => true, 'DisplayDocTitle' => true,
        'NonFullScreenPageMode' => 'UseNone', 'PrintScaling' => 'None',
        'ViewArea' => 'CropBox', 'ViewClip' => 'CropBox',
        'PrintArea' => 'CropBox', 'PrintClip' => 'CropBox'
    ]);
    $pdf->AddPage();

    $labelsPerPage = $labelsPerRow * $ROWS_PER_PAGE;
    $printed       = $printedStart;

    foreach ($items as $it) {
        $qty = (int)($it['qty'] ?? ($it['cantidad'] ?? 0));
        if ($qty <= 0) continue;

        for ($i = 0; $i < $qty; $i++) {
            if ($printed > 0 && ($printed % $labelsPerPage) === 0) {
                $pdf->AddPage();
            }

            $pos = $printed % $labelsPerPage;
            $row = (int)floor($pos / $labelsPerRow);
            $col = $pos % $labelsPerRow;

            $x = $MARGIN_L + $EXTRA_X + $OFFSET_X + $col * ($LABEL_W + $GAP_X);
            $y = $MARGIN_T + $OFFSET_Y + $row * ($LABEL_H + $GAP_Y);

            drawLabel76x50($pdf, $x, $y, $LABEL_W, $LABEL_H, $it, $DRAW_BORDER);
            $printed++;
        }
    }
}

/* ========= DIBUJO 76x50 ========= */
function drawLabel76x50(TCPDF $pdf, $x, $y, $w, $h, $item, $drawBorder = false)
{
    if ($drawBorder) {
        $pdf->SetDrawColor(200, 200, 200);
        $pdf->Rect($x, $y, $w, $h);
    }

    // Padding
    $padT = 2.5;
    $padB = 2.0;
    $padL = 3.0;
    $padR = 3.0;

    $innerW = $w - $padL - $padR;

    // ==== NOMBRE (arriba, max 2 líneas) ====
    $nombre = trim((string)($item['descripcion'] ?? ''));
    if ($nombre === '') $nombre = 'SIN DESCRIPCIÓN';

    $pdf->SetFont('helvetica', 'B', 9);
    $maxLines = (mb_strlen($nombre) > 38 ? 3 : 2);
    $lineH    = 4.2;

    $nombreFit = ajustarTexto2Lineas($pdf, $nombre, $innerW, $maxLines);

    $numLines = max(1, min($maxLines, $pdf->getNumLines($nombreFit, $innerW)));
    $nameH    = $numLines * $lineH;

    $pdf->SetXY($x + $padL, $y + $padT);
    $pdf->MultiCell($innerW, $nameH, $nombreFit, 0, 'C', false, 0);

    // ==== PRECIO (centro grande) ====
    $precioRaw = $item['precio'] ?? ($item['precio_str'] ?? null);
    if ($precioRaw !== null && $precioRaw !== '') {

        $precioTxt = is_numeric($precioRaw)
            ? ('S/ ' . number_format((float)$precioRaw, 2, '.', ''))
            : (stripos(trim((string)$precioRaw), 's/') === false
                ? 'S/ ' . trim((string)$precioRaw)
                : trim((string)$precioRaw));

        $zonaTop = ($y + $padT + $nameH + 0.4);
        $zonaBot = ($y + $h - $padB - 1.5 - (16.0 + 6.0));
        $priceH  = 10.0;

        $priceY = $zonaTop + max(0, (($zonaBot - $zonaTop) - $priceH) / 2);

        $pdf->SetFont('helvetica', 'B', 20);
        $pdf->SetXY($x + $padL, $priceY);
        $pdf->Cell($innerW, $priceH, $precioTxt, 0, 0, 'C', false);
    }

    // ==== CÓDIGO DE BARRAS (C128) CENTRADO REAL + NÚMERO ====
    $valorBarcode = (string)($item['codigo_barras'] ?? ($item['id'] ?? ''));
    $valorBarcode = trim($valorBarcode);
    if ($valorBarcode === '') $valorBarcode = '000000';

    $barcodeH   = 16.0;
    $codeTextH  = 6.0;
    $bottomSafe = 1.5;

    $barcodeY = $y + $h - $padB - $bottomSafe - ($barcodeH + $codeTextH);

    // Ancho fijo del bloque de barras (centrado perfecto)
    $BAR_W = 54.0;
    $bx    = $x + ($w - $BAR_W) / 2.0;

    $style = [
        'position' => '',
        'align'    => 'C',
        'stretch'  => false,
        'fitwidth' => false,
        'border'   => false,
        'hpadding' => 0,
        'vpadding' => 0,
        'fgcolor'  => [0, 0, 0],
        'bgcolor'  => false,
        'text'     => false, // texto lo ponemos nosotros
    ];

    $xScale = 0.45;

    $pdf->write1DBarcode(
        $valorBarcode,
        'C128',
        $bx,
        $barcodeY,
        $BAR_W,
        $barcodeH,
        $xScale,
        $style,
        'N'
    );

    // Número centrado debajo
    $pdf->SetFont('helvetica', 'B', 18);
    $pdf->SetXY($x, $barcodeY + $barcodeH + 0.2);
    $pdf->Cell($w, $codeTextH, $valorBarcode, 0, 0, 'C', false);
}

/* ========= Texto a 2 líneas (sin depender de mbstring) ========= */
function ajustarTexto2Lineas(TCPDF $pdf, string $txt, float $w, int $maxLines = 2): string
{
    $txt = trim(preg_replace('/\s+/', ' ', $txt));
    if ($txt === '') return $txt;

    if ($pdf->getNumLines($txt, $w) <= $maxLines) return $txt;

    $ellipsis = '…';

    $len = function_exists('mb_strlen') ? mb_strlen($txt) : strlen($txt);
    $substr = function ($s, $n) {
        if (function_exists('mb_substr')) return mb_substr($s, 0, $n);
        return substr($s, 0, $n);
    };

    $lo = 0;
    $hi = $len;

    while ($lo < $hi) {
        $mid  = intdiv($lo + $hi + 1, 2);
        $cand = rtrim($substr($txt, $mid)) . $ellipsis;

        if ($pdf->getNumLines($cand, $w) <= $maxLines) $lo = $mid;
        else $hi = $mid - 1;
    }

    return rtrim($substr($txt, $lo)) . $ellipsis;
}

/* ========= OUTPUT ========= */
$pdfContent = $pdf->Output('etiquetas_76x50.pdf', 'S');
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="etiquetas_76x50.pdf"');
header('Content-Length: ' . strlen($pdfContent));
echo $pdfContent;
