<?php
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    header("Access-Control-Allow-Origin: *");
    header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
    header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With");
    http_response_code(204); // Sin contenido
    exit;
}

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE");
header("Access-Control-Allow-Headers: Content-Type, Authorization");

error_reporting(E_ALL);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', '/logs/error.log');


require __DIR__ . '/vendor/autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\PrintConnectors\WindowsPrintConnector;
use Mike42\Escpos\EscposImage;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;

// Recibir datos - puede venir como JSON string o como objeto serializado por jQuery
$dataPrint = null;

if(isset($_POST["dataPrint"])){
    // Si es string JSON, decodificar
    if(is_string($_POST["dataPrint"])){
        $dataPrint = json_decode($_POST["dataPrint"]);
    } else {
        // Si jQuery ya lo deserializó como array, convertir a objeto
        $dataPrint = json_decode(json_encode($_POST["dataPrint"]));
    }
}

if($dataPrint){
    //Printer Name
    $PRINTER_NAME = $dataPrint->printer ?? 'POS-80C';
    //CONFIGURACIONES
    $maxDescripcion = 25; //Maximo de caracteres por linea para la descripcion del producto
    $iscEmpresa = $dataPrint->isc ?? "demo";
    //DATOS
    $nombreEmpresa = $dataPrint->nombre_empresa;
    $razonSocial = $dataPrint->rsocial_empresa;
    $giro = $dataPrint->giro_empresa;
    $documentoDueno = "NRC: ".$dataPrint->nrc_empresa." | NIT: ".$dataPrint->nit_empresa;
    $direccion = $dataPrint->direcion_empresa;

    $documento = strToUpper($dataPrint->documento) ?? null;

    $fecha = $dataPrint->fecha;
    $caja = $dataPrint->caja;

    $clienteNombre = $dataPrint->cliente;
    $clienteDocumento = $dataPrint->clienteDoc ?? null;
    if($clienteDocumento && $dataPrint->clienteDocNum){
        $clienteDocumento = $clienteDocumento.": ".$dataPrint->clienteDocNum;
    }
    $clienteNRC = $dataPrint->clienteNRC ?? null;

    $productos = $dataPrint->productos_normal;

    $totalGravado = $dataPrint->totalGrabadas;
    $totalExento = $dataPrint->totalExento;
    $totalNoSujeto = $dataPrint->totalNS;
    $totalFinal = $dataPrint->totales->totalTotal;
    $totalCambio = floatval($dataPrint->efectivo) - $totalFinal;

    $dteNControl = $dataPrint->dte_numero_control;
    $dteCodGen = $dataPrint->dte_codigo_generacion;

    $disclaimer = "Este comprobante no es un documento fiscal. Su DTE será enviado al correo electrónico proporcionado.";
    $qrMessage = "También puedes escanear el código QR para ver y descargar tu factura electrónica en línea.";

    $mensaje = $dataPrint->mensaje_ticket." \n ¡Gracias por su compra!" ?? "¡Gracias por su compra!";
    $urlQR = "https://consultadte.factuexpress.com.sv/$iscEmpresa/$dteCodGen";

    $numeroReferencia = $dataPrint->referencia;


    try {
        $connector = new WindowsPrintConnector($PRINTER_NAME);
        $printer = new Printer($connector);
        // ENCABEZADO
        $printer->setJustification(Printer::JUSTIFY_CENTER);
        $printer->setTextSize(2, 2);
        $printer->text("$nombreEmpresa\n");
        $printer->setTextSize(1, 1);
        $printer->text("$razonSocial\n");
        $printer->text("$giro\n");
        $printer->text("$documentoDueno\n");
        $printer->text("$direccion\n");
        $printer->text(str_repeat("-", 45) . "\n");
        //DOCUMENTO
        if($documento){
            $printer->setEmphasis(true);
            $printer->text("$documento\n");
            $printer->setEmphasis(false);
             $printer->text(str_repeat("-", 45) . "\n");
        }
        //GENERAL
        $printer->setJustification(Printer::JUSTIFY_LEFT);
        $printer->setEmphasis(true);
        $printer->text("Fecha: ");
        $printer->setEmphasis(false);
        $printer->text("$fecha");
        $printer->setEmphasis(true);
        $printer->text("  Caja: ");
        $printer->setEmphasis(false);
        $printer->text("$caja\n");
        //CLIENTE
        if($clienteNombre && $clienteNombre != ""){
            $printer->setEmphasis(true);
            $printer->text("Cliente:\n");
            $printer->setEmphasis(false);
            $printer->text("$clienteNombre\n");
        }
        if($clienteDocumento){
            $printer->text("$clienteDocumento\n");
        }
        if($clienteNRC){
            $printer->text("NRC: $clienteNRC\n");
        }
        $printer->text("\n");
        //PRODUCTOS
        $printer->setEmphasis(true);
        $printer->text("Cant  Descripcion                 Precio  Total\n");
        $printer->text(str_repeat("-", 45) . "\n");
        $printer->setEmphasis(false);
    
        foreach ($productos as $producto) {
            $totalUnitario = $producto->cant * $producto->costo;
            $cantidad = str_pad(number_format($producto->cant, 2), 4, " ", STR_PAD_RIGHT);
            $precio = str_pad(number_format($producto->costo, 2), 7, " ", STR_PAD_LEFT);
            $descuento = $producto->descuento && $producto->descuento > 0 ? $producto->descuento : null;
            $total = str_pad(number_format($totalUnitario, 2), 7, " ", STR_PAD_LEFT);

            // Dividir la descripción en líneas
            $descripcion = wordwrap($producto->sku.' '.$producto->desc, $maxDescripcion, "\n", true);
            $lineasDescripcion = explode("\n", $descripcion);

            // Imprimir primera línea con cantidad, precio y total
            $printer->text("$cantidad " . str_pad($lineasDescripcion[0], $maxDescripcion, " ") . " $precio $total\n");

            // Imprimir líneas adicionales de la descripción (si hay más)
            for ($i = 1; $i < count($lineasDescripcion); $i++) {
                $printer->text("     " . str_pad($lineasDescripcion[$i], $maxDescripcion) . "\n");
            }
            // Imprimir línea de descuento si existe
            if ($descuento) {
                $printer->text(str_pad("        Descuento:", $maxDescripcion, " ") . str_pad("-" . number_format($descuento, 2), 21, " ", STR_PAD_LEFT) . "\n");
            }   
        }
        
        $printer->text(str_repeat("-", 45) . "\n");
        
        // TOTALES
        $printer->setJustification(Printer::JUSTIFY_RIGHT);
        
        // Propina (si aplica)
        $propina = floatval($dataPrint->totales->propina ?? 0);
        if ($propina > 0) {
            // Si hay propina, mostrar subtotal primero
            $subtotal = $totalFinal - $propina;
            $printer->text("SUBTOTAL       $" . number_format($subtotal, 2) . "\n");
            $printer->text("PROPINA        $" . number_format($propina, 2) . "\n");
        }
        
        $printer->setEmphasis(true);
        $printer->setTextSize(2, 1);
        $printer->text("TOTAL $" . number_format($totalFinal, 2) . "\n");
        $printer->setTextSize(1, 1);
        $printer->setEmphasis(false);
        
        // FORMA DE PAGO
        $efectivo = floatval($dataPrint->efectivo ?? 0);
        $pos = floatval($dataPrint->pos ?? 0);
        
        if ($efectivo > 0 && $pos > 0) {
            // Pago mixto
            $printer->text("EFECTIVO       $" . number_format($efectivo, 2) . "\n");
            $printer->text("POS            $" . number_format($pos, 2) . "\n");
            $totalCambio = max(0, $efectivo - ($totalFinal - $pos));
            $printer->text("CAMBIO         $" . number_format($totalCambio, 2) . "\n");
        } elseif ($pos > 0) {
            // Solo POS
            $printer->text("POS            $" . number_format($pos, 2) . "\n");
            $printer->text("CAMBIO         $0.00\n");
        } else {
            // Solo efectivo
            $printer->text("EFECTIVO       $" . number_format($efectivo, 2) . "\n");
            $totalCambio = max(0, $efectivo - $totalFinal);
            $printer->text("CAMBIO         $" . number_format($totalCambio, 2) . "\n");
        }

        $printer->text(str_repeat("_", 45) . "\n");

        //DTE
        $printer->setJustification(Printer::JUSTIFY_LEFT);
        $printer->text("NUMERO DE CONTROL: \n$dteNControl\n");
        $printer->text("CÓDIGO DE GENERACION: \n$dteCodGen\n\n");

        $printer->setJustification(Printer::JUSTIFY_CENTER);
        // DISCLAIMER
        $lineasDisclaimer = wordwrap($disclaimer, 45, "\n", true);
        foreach (explode("\n", $lineasDisclaimer) as $linea) {
            $printer->text($linea . "\n");
        }
        
        // CÓDIGO QR
        $printer->text("$qrMessage\n");
        $printer->qrCode($urlQR, Printer::QR_ECLEVEL_L, 5);

        $printer->text("\n$mensaje\n");

        // REFERENCIA
        $printer->text("\nRef: $numeroReferencia\n");
        $printer->setBarcodeHeight(40);
        $printer->setBarcodeWidth(4); 
        $printer->barcode($numeroReferencia, Printer::BARCODE_CODE39);

        // CORTAR PAPEL Y CERRAR IMPRESORA
        $printer->feed(2);
        $printer->cut();
        $printer->pulse(); //Abrir gaveta
        $printer->close();

        //echo "Ticket impreso correctamente.";
        echo json_encode([
            "status" => "success",
            "message" => "Ticket impreso correctamente."
        ]);

    } catch (Exception $e) {
        //echo "Error al imprimir: " . $e->getMessage();
        echo json_encode([
            "status" => "error",
            "message" => "Error al imprimir: " . $e->getMessage()
        ]);
    }
}else{
    echo json_encode([
        "status" => "error",
        "message" => "No se recibieron datos para imprimir."
    ]);
}