<?php

namespace App\Services;

use App\Entities\Configuracion\ImpresoraEtiquetaEntity;
use App\Models\Configuracion\ImpresoraEtiquetaModel;
use CodeIgniter\Config\BaseService;
use DOMDocument;
use Throwable;
use Exception;

class ImpresoraEtiquetaService extends BaseService
{

    protected ImpresoraEtiquetaModel $impresoraEtiquetaModel;
    protected array $TEST = [
        "printer" => "LABPRINT-1",
        "header" => [
            "_FORMAT" => "E:PEDIDO.ZPL",
            "_QUANTITY" => 1,
            "_PRINBTERNAME" => "Printer 1",
            "_JOBNAME" => "LBL101"
        ],
        "labels" => [
            [
                "cliente" => "Cliente Potencial",
                "titulo" => "[1234] TEST OLIVEROS",
                "cantidad" => 100,
                "tirada" => 50,
                "cajas" => 1,
                "ean" => null,
                "nombre" => "___Nombre___",
                "direccion" => "C/ test n10, Madrid, 12345, España",
                "notas" => "Nota....",
                "refcliente" => "Refclient:1234",
                "npedido" => "1234"
            ]
        ]
    ];

    public function __construct()
    {
        $this->impresoraEtiquetaModel = model(ImpresoraEtiquetaModel::class);
    }
    public function test(): array
    {
        try {
            $status = false;
            $content = "";
            $impresora = $this->impresoraEtiquetaModel->where("name", $this->TEST["printer"])->first();
            if ($impresora) {
                $content = $this->createEtiqueta($this->TEST);
                $status = $this->sendToImpresoraEtiqueta(1234, $content, $impresora);
            }
            return ["impresora" => $impresora, "content" => $content, "status" => $status];
        } catch (Throwable $th) {
            return ["impresora" => $impresora, "content" => $th->getMessage(), "status" => $status];
        }
    }
    public function createEtiqueta(array $data_label = []): ?string
    {
        $xml = new DOMDocument('1.0', 'utf-8');
        $labels = $xml->createElement("labels");
        foreach ($data_label["header"] as $key => $value) {
            $labels->setAttribute($key, $value);
        }
        foreach ($data_label["labels"] as $label) {
            $labelChild = $labels->appendChild($xml->createElement('label'));
            foreach ($label as $attrName => $attributeValue) {
                $variableChild = $labels->appendChild($xml->createElement('variable'));
                $variableChild->setAttribute("name", $attrName);
                $variableChild->append((string) $attributeValue);
                $labelChild->appendChild($variableChild);
            }
        }
        $xml->appendChild($labels);
        return $xml->saveXML();
    }


    public function createEtiquetaTitulos(array $data_label = []): ?string
    {
        $xml = new DOMDocument('1.0', 'utf-8');

        // Crear nodo raíz "labels"
        $labels = $xml->createElement("labels");

        // Establecer atributos de "labels" desde "header"
        foreach ($data_label["header"] as $key => $value) {
            $labels->setAttribute($key, $value);
        }

        // Recorrer grupos de etiquetas
        foreach ($data_label["grupos"] as $grupo) {
            $labelChild = $xml->createElement('label');

            // Crear variables específicas del grupo
            foreach ($grupo as $libro) {
                $prefix = $libro['prefix']==1 ? '' : $libro['prefix'];

                $variables = [
                    "titulo$prefix" => $libro['titulo'],
                    "tirada$prefix" => $libro['tirada'],
                    "ean$prefix" => $libro['ean'],
                    "npedido$prefix" => $libro['npedido'],
                    "refcliente$prefix" => $libro['refcliente'],
                    "textpedido$prefix" => 'Pedido',
                    "textcantidad$prefix" => 'Cantidad:',
                    "textref$prefix" => 'Ref:',
                    "textean$prefix" => 'ISBN',
                ];

                foreach ($variables as $varName => $varValue) {
                    $variableChild = $xml->createElement('variable');
                    $variableChild->setAttribute("name", $varName);
                    $variableChild->appendChild($xml->createTextNode((string) $varValue));
                    $labelChild->appendChild($variableChild);
                }
            }

            // Variables comunes del grupo
            $nombreVariable = $xml->createElement('variable', htmlspecialchars($data_label['nombre']));
            $nombreVariable->setAttribute('name', 'nombre');
            $labelChild->appendChild($nombreVariable);

            $direccionVariable = $xml->createElement('variable', htmlspecialchars($data_label['direccion']));
            $direccionVariable->setAttribute('name', 'direccion');
            $labelChild->appendChild($direccionVariable);

            $labels->appendChild($labelChild);
        }

        $xml->appendChild($labels);
        return $xml->saveXML();
    }

    public function generateEtiquetasEmbalaje($ot_id, $ejemplares_caja, $printer)
    {
        $data = [
            "printer" => $printer->name,
            "header" => [
                "_FORMAT" => "E:PEDIDO.ZPL",
                "_QUANTITY" => 1,
                "_PRINBTERNAME" => $printer->name,
                "_JOBNAME" => "LBL101"
            ],
        ];

        $ot_model = model('App\Models\OrdenTrabajo\OrdenTrabajoModel');
        $datos = $ot_model->select('
            ordenes_trabajo.total_tirada as unidades,
            clientes.nombre as cliente,
            presupuestos.titulo as titulo,
            presupuestos.isbn as isbn,
            presupuestos.referencia_cliente as referencia_cliente,
            pedidos.id as pedido
            ')
            ->join('pedidos', 'ordenes_trabajo.pedido_id = pedidos.id')
            ->join('pedidos_linea', 'pedidos.id = pedidos_linea.pedido_id')
            ->join('presupuestos', 'pedidos_linea.presupuesto_id = presupuestos.id')
            ->join('clientes', 'presupuestos.cliente_id = clientes.id')
            ->where('ordenes_trabajo.id', $ot_id)
            ->first();
        $cajas = ceil($datos->unidades / $ejemplares_caja);
        $cantidad = 0;

        for( $i = 1; $i <= $cajas; $i++) {
            $data["labels"][] = [
                "cliente" => $datos->cliente,
                "titulo" => $datos->titulo,
                "cantidad" => $cantidad + $ejemplares_caja <= $datos->unidades ? $ejemplares_caja : $datos->unidades-$cantidad,
                "tirada" => $datos->unidades,
                "cajas" => $i . '/' . $cajas,
                "ean" => str_replace("-", "", $datos->isbn),
                "nombre" => null,
                "direccion" => null,
                "notas" => "",
                "refcliente" => $datos->referencia_cliente,
                "npedido" => $datos->pedido
            ];

            $cantidad += $ejemplares_caja;
        }

        $servicioImpresora = new ImpresoraEtiquetaService();
        $xml = $servicioImpresora->createEtiqueta($data);
        if ($xml == null) {
            return [
                'status' => false,
                'message' => lang('Logistica.errors.noEtiquetas'),
            ];
        }
        $sk_environment = getenv('SK_ENVIRONMENT');
        if ($sk_environment == 'production') {

            $status = $servicioImpresora->sendToImpresoraEtiqueta("ETIQUETA", $xml, $printer);
            if ($status) {
                return [
                    'status' => true,
                    'message' => lang('Logistica.success.imprimirEtiquetas'),
                    'data' => $xml
                ];
            } else {
                return [
                    'status' => false,
                    'message' => lang('Logistica.errors.noEtiquetas'),
                ];
            }

        } else {
            return [
                'status' => true,
                'message' => lang('Logistica.success.imprimirEtiquetas'),
                'data' => $xml
            ];
        }
    }


    public function sendToImpresoraEtiqueta(string $name, string $content, ImpresoraEtiquetaEntity $impresoraEtiqueta): bool
    {
        $tmpFile = tmpfile();

        fwrite($tmpFile, $content);
        rewind($tmpFile);

        $tmpMetaData = stream_get_meta_data($tmpFile);
        $conn = @ftp_connect($impresoraEtiqueta->ip, $impresoraEtiqueta->port);
        if (!$conn) {
            throw new Exception('Error al establecer conexión FTP');
        }
        $isLoginSuccess = @ftp_login($conn, $impresoraEtiqueta->user, $impresoraEtiqueta->pass);
        if ($isLoginSuccess) {
        } else {
            throw new Exception('Error haciendo login en el servidor FTP');
        }
        if (!ftp_pasv($conn, true)) {
            throw new Exception('Error entrando en modo pasivo');
        }
        if (ftp_put($conn, $name, $tmpMetaData['uri'], FTP_ASCII) === FALSE) {
            $status = false;
            ftp_close($conn);
        } else {
            $status = true;
        }

        return $status;
    }
}
