<?php

namespace WMS\Controllers;

use WMS\Core\Request;
use WMS\Core\Response;
use WMS\Middleware\AuthMiddleware;
use WMS\Services\ZplService;
use WMS\Helpers\Validator;

/**
 * Controlador de impresion ZPL / Zebra.
 *
 * Endpoints:
 *   POST /api/print/product-label    - Etiqueta de producto/lote
 *   POST /api/print/bin-label        - Etiqueta de ubicacion
 *   POST /api/print/container-label  - Etiqueta de contenedor/LPN
 *   POST /api/print/delivery-label   - Etiqueta de envio/despacho
 *   POST /api/print/send             - Enviar ZPL crudo a impresora
 */
class PrintController
{
    /**
     * POST /api/print/product-label
     * Body: {item_code, item_name, batch_number, supplier_lot, expiry_date, quantity, uom, copies, printer_ip}
     */
    public static function productLabel(): void
    {
        $body = Request::body();
        $v = (new Validator($body))->required(['item_code']);
        if (!$v->passes()) {
            Response::error('Datos invalidos', 422, $v->errors());
            return;
        }

        try {
            $service = new ZplService();
            $copies  = max(1, (int) ($body['copies'] ?? 1));
            $result  = $service->productLabel($body, $copies);

            // Si se pide envio directo a impresora
            if (!empty($body['send_to_printer'])) {
                $service->sendToPrinter(
                    $result['zpl'],
                    $body['printer_ip'] ?? null,
                    (int) ($body['printer_port'] ?? 9100)
                );
                $result['printed'] = true;
            }

            Response::success($result, 'Etiqueta de producto generada');
        } catch (\RuntimeException $e) {
            Response::error($e->getMessage());
        }
    }

    /**
     * POST /api/print/bin-label
     * Body: {bin_code, warehouse_name, zone_name, printer_ip}
     */
    public static function binLabel(): void
    {
        $body = Request::body();
        $v = (new Validator($body))->required(['bin_code']);
        if (!$v->passes()) {
            Response::error('Datos invalidos', 422, $v->errors());
            return;
        }

        try {
            $service = new ZplService();
            $result  = $service->binLabel($body);

            if (!empty($body['send_to_printer'])) {
                $service->sendToPrinter(
                    $result['zpl'],
                    $body['printer_ip'] ?? null,
                    (int) ($body['printer_port'] ?? 9100)
                );
                $result['printed'] = true;
            }

            Response::success($result, 'Etiqueta de ubicacion generada');
        } catch (\RuntimeException $e) {
            Response::error($e->getMessage());
        }
    }

    /**
     * POST /api/print/container-label
     * Body: {container_code, contents_summary, printer_ip}
     */
    public static function containerLabel(): void
    {
        $body = Request::body();
        $v = (new Validator($body))->required(['container_code']);
        if (!$v->passes()) {
            Response::error('Datos invalidos', 422, $v->errors());
            return;
        }

        try {
            $service = new ZplService();
            $result  = $service->containerLabel($body);

            if (!empty($body['send_to_printer'])) {
                $service->sendToPrinter(
                    $result['zpl'],
                    $body['printer_ip'] ?? null,
                    (int) ($body['printer_port'] ?? 9100)
                );
                $result['printed'] = true;
            }

            Response::success($result, 'Etiqueta de contenedor generada');
        } catch (\RuntimeException $e) {
            Response::error($e->getMessage());
        }
    }

    /**
     * POST /api/print/delivery-label
     * Body: {customer_name, order_number, items_count, printer_ip}
     */
    public static function deliveryLabel(): void
    {
        $body = Request::body();
        $v = (new Validator($body))->required(['customer_name', 'order_number']);
        if (!$v->passes()) {
            Response::error('Datos invalidos', 422, $v->errors());
            return;
        }

        try {
            $service = new ZplService();
            $result  = $service->deliveryLabel($body);

            if (!empty($body['send_to_printer'])) {
                $service->sendToPrinter(
                    $result['zpl'],
                    $body['printer_ip'] ?? null,
                    (int) ($body['printer_port'] ?? 9100)
                );
                $result['printed'] = true;
            }

            Response::success($result, 'Etiqueta de envio generada');
        } catch (\RuntimeException $e) {
            Response::error($e->getMessage());
        }
    }

    /**
     * POST /api/print/send
     * Body: {zpl, printer_ip, printer_port}
     * Envia ZPL crudo a la impresora.
     */
    public static function sendToPrinter(): void
    {
        $body = Request::body();
        $v = (new Validator($body))->required(['zpl']);
        if (!$v->passes()) {
            Response::error('Datos invalidos', 422, $v->errors());
            return;
        }

        try {
            $service = new ZplService();
            $service->sendToPrinter(
                $body['zpl'],
                $body['printer_ip'] ?? null,
                (int) ($body['printer_port'] ?? 9100)
            );
            Response::success(['printed' => true], 'ZPL enviado a impresora');
        } catch (\RuntimeException $e) {
            Response::error($e->getMessage());
        }
    }
}
