<?php

namespace App\Http\Controllers;

use App\Models\Venta;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class ImprimirTicketController extends Controller
{
    /**
     * Imprimir ticket de una venta
     * Si IMPRIMIR_DIRECTO=true, envía la petición al endpoint externo
     * Si no, retorna el contenido formateado para impresión local
     */
    public function imprimir(Request $request, Venta $venta): JsonResponse
    {
        try {
            // Cargar relaciones necesarias
            $venta->load([
                'sucursal',
                'cliente',
                'ventaDetalle.producto',
                'ventaDetalle.tratamiento',
                'ventaDetalle.vale'
            ]);

            // Construir el contenido del ticket
            $contenido = $this->construirContenidoTicket($venta);

            // Verificar si se debe imprimir directamente
            $imprimirDirecto = env('IMPRIMIR_DIRECTO', false) === true || env('IMPRIMIR_DIRECTO', 'false') === 'true';

            if ($imprimirDirecto) {
                // Enviar al endpoint externo
                return $this->enviarAEndpointExterno($contenido, $request);
            }

            // Retornar contenido para impresión local
            return response()->json([
                'success' => true,
                'data' => [
                    'contenido' => $contenido,
                    'venta_id' => $venta->id
                ]
            ]);

        } catch (\Exception $e) {
            Log::error('Error al imprimir ticket: ' . $e->getMessage(), [
                'venta_id' => $venta->id ?? null,
                'trace' => $e->getTraceAsString()
            ]);

            return response()->json([
                'success' => false,
                'message' => 'Error al procesar la impresión del ticket',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Construir el contenido del ticket desde el modelo Venta
     */
    private function construirContenidoTicket(Venta $venta): string
    {
        $lineas = [];

        // Dirección de la sucursal
        if ($venta->sucursal && $venta->sucursal->direccion) {
            $lineas[] = $venta->sucursal->direccion;
        }

        $lineas[] = ""; // Línea vacía
        $lineas[] = "----------";

        // Encabezado de productos
        $lineas[] = "Producto";
        $lineas[] = "precio";
        $lineas[] = "---";
        $lineas[] = "00";
        $lineas[] = "----------";

        // Detalles de la venta
        foreach ($venta->ventaDetalle as $detalle) {
            $lineas[] = "Cantidad";
            $lineas[] = $detalle->descripcion;
            $lineas[] = $detalle->cantidad . " $" . number_format($detalle->total, 2, '.', ',') . ".";
        }

        // Total
        $lineas[] = "Total:";
        $lineas[] = "$" . number_format($venta->total, 2, '.', ',') . ".00";

        // Pie de página
        $lineas[] = "===========================";
        $lineas[] = "¡GRACIAS POR SU VISITA!";
        $lineas[] = "YA QUE NO SE ACEPTAN";
        $lineas[] = "RECLAMACIONES NI DEVOLUCIONES";
        $lineas[] = "===========================";

        // Código postal - intentar extraer de la dirección si está disponible
        // Por ahora, si hay dirección, intentamos extraer el CP o usar un formato estándar
        if ($venta->sucursal && $venta->sucursal->direccion) {
            // Si la dirección contiene "C.P." o código postal, extraerlo
            if (preg_match('/C\.?P\.?\s*(\d{5})/i', $venta->sucursal->direccion, $matches)) {
                $lineas[] = "C.P. " . $matches[1];
            }
        }

        // Folio y fecha
        $fechaFormateada = $venta->fecha_registro 
            ? date('d-m-Y h A', strtotime($venta->fecha_registro))
            : date('d-m-Y h A');
        
        $lineas[] = "F-" . $venta->id . " - " . $fechaFormateada;
        $lineas[] = "===========================";
        $lineas[] = "ESTE COMPROBANTE NO TIENE VALIDEZ FISCAL";
        $lineas[] = "POR FAVOR REVISE SUS PRODUCTOS";
        $lineas[] = "===========================";

        return implode("\n", $lineas);
    }

    /**
     * Enviar el contenido al endpoint externo de impresión
     */
    private function enviarAEndpointExterno(string $contenido, Request $request): JsonResponse
    {
        $endpointUrl = env('IMPRESION_ENDPOINT_URL', 'http://localhost:8081/api');
        $url = rtrim($endpointUrl, '/') . '/imprimir-ticket';

        // Obtener parámetros de la petición o usar valores por defecto
        $nombreImpresora = $request->input('nombreImpresora', 'ticket');
        $tipoTicket = $request->input('tipoTicket', 'Venta');
        $anchoPapel = $request->input('anchoPapel', 600);

        $payload = [
            'nombreImpresora' => $nombreImpresora,
            'contenido' => $contenido,
            'tipoTicket' => $tipoTicket,
            'anchoPapel' => (int)$anchoPapel
        ];

        try {
            $response = Http::timeout(30)->post($url, $payload);

            if ($response->successful()) {
                return response()->json([
                    'success' => true,
                    'message' => $response->json()['message'] ?? 'Ticket enviado correctamente',
                    'data' => $response->json()
                ]);
            }

            return response()->json([
                'success' => false,
                'message' => 'Error al enviar el ticket al servicio de impresión',
                'error' => $response->body(),
                'status_code' => $response->status()
            ], $response->status());

        } catch (\Illuminate\Http\Client\ConnectionException $e) {
            Log::error('Error de conexión al servicio de impresión: ' . $e->getMessage());
            
            return response()->json([
                'success' => false,
                'message' => 'No se pudo conectar al servicio de impresión',
                'error' => $e->getMessage()
            ], 503);

        } catch (\Exception $e) {
            Log::error('Error al enviar ticket al endpoint externo: ' . $e->getMessage());
            
            return response()->json([
                'success' => false,
                'message' => 'Error al enviar el ticket',
                'error' => $e->getMessage()
            ], 500);
        }
    }
}

