<?php

namespace App\Http\Controllers;

use App\Models\Boleto;
use App\Models\ConfiguracionHardware;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;

class BoletoController extends Controller
{
    public function index(Request $request): JsonResponse
    {
        $query = Boleto::with(['usuarioGenerador', 'usuarioValidador', 'tipoCarga', 'destino']);

        // Filtros
        if ($request->has('estatus')) {
            $query->where('estatus', $request->estatus);
        }

        if ($request->has('usuario_generador_id')) {
            $query->where('usuario_generador_id', $request->usuario_generador_id);
        }

        if ($request->has('folio')) {
            $query->where('folio', 'like', '%' . $request->folio . '%');
        }

        if ($request->has('fecha_desde')) {
            $query->whereDate('fecha_generacion', '>=', $request->fecha_desde);
        }

        if ($request->has('fecha_hasta')) {
            $query->whereDate('fecha_generacion', '<=', $request->fecha_hasta);
        }

        $boletos = $query->orderBy('fecha_generacion', 'desc')->paginate(20);

        return response()->json(['data' => $boletos], JsonResponse::HTTP_OK);
    }

    public function store(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'placa' => ['required', 'string', 'max:20'],
            'conductor' => ['nullable', 'string', 'max:255'],
            'tipo_carga_id' => ['nullable', 'exists:tipos_carga,id'],
            'destino_id' => ['nullable', 'exists:destinos,id'],
            'observaciones' => ['nullable', 'string'],
            'foto_ruta' => ['nullable', 'string'], // Ruta de la foto ya capturada (opcional)
        ], [
            'placa.required' => 'La placa es obligatoria.',
            'placa.max' => 'La placa no debe exceder 20 caracteres.',
        ]);

        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
        }

        // Generar folio único
        $folio = $this->generarFolioUnico();

        // Generar código QR
        $codigoQr = $this->generarCodigoQR($folio);

        $data = [
            'folio' => $folio,
            'codigo_qr' => $codigoQr,
            'estatus' => 'pendiente',
            'foto_ruta' => $request->foto_ruta ?: null,
            'placa' => $request->placa,
            'conductor' => $request->conductor,
            'tipo_carga_id' => $request->tipo_carga_id,
            'destino_id' => $request->destino_id,
            'observaciones' => $request->observaciones,
            'usuario_generador_id' => auth()->id(),
            'fecha_generacion' => now(),
        ];

        $boleto = Boleto::create($data);
        $boleto->load(['usuarioGenerador', 'tipoCarga', 'destino']);

        return response()->json(['data' => $boleto], JsonResponse::HTTP_CREATED);
    }

    public function show(Boleto $boleto): JsonResponse
    {
        $boleto->load(['usuarioGenerador', 'usuarioValidador', 'tipoCarga', 'destino']);
        return response()->json(['data' => $boleto], JsonResponse::HTTP_OK);
    }

    /**
     * Capturar foto desde cámara IP
     */
    public function capturarFoto(Request $request): JsonResponse
    {
        $camara = ConfiguracionHardware::camaras()->activos()->first();

        if (!$camara) {
            return response()->json([
                'errors' => ['camera' => ['No hay cámara IP configurada o activa.']]
            ], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
        }

        try {
            // Construir URL de captura
            $url = $camara->url_snapshot;
            if (!$url) {
                // Construir URL básica si no está configurada
                $protocolo = 'http';
                $credenciales = '';
                if ($camara->usuario && $camara->password) {
                    $credenciales = $camara->usuario . ':' . $camara->password . '@';
                }
                $url = $protocolo . '://' . $credenciales . $camara->ip_url;
                if ($camara->puerto) {
                    $url .= ':' . $camara->puerto;
                }
                $url .= '/snapshot.cgi';
            }

            // Realizar petición HTTP con timeout
            $response = Http::timeout(10)->get($url);

            if (!$response->successful()) {
                throw new \Exception('Error al capturar foto: ' . $response->status());
            }

            // Guardar imagen
            $nombreArchivo = 'volteos/' . Str::uuid() . '.jpg';
            Storage::disk('public')->put($nombreArchivo, $response->body());

            return response()->json([
                'data' => [
                    'foto_ruta' => $nombreArchivo,
                    'foto_url' => asset('storage/' . $nombreArchivo),
                ]
            ], JsonResponse::HTTP_OK);

        } catch (\Exception $e) {
            return response()->json([
                'errors' => ['camera' => ['Error al capturar foto: ' . $e->getMessage()]]
            ], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
        }
    }

    /**
     * Validar boleto (por QR o folio)
     */
    public function validar(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'folio' => ['required_without:codigo_qr', 'string'],
            'codigo_qr' => ['required_without:folio', 'string'],
        ], [
            'folio.required_without' => 'Debe proporcionar el folio o código QR.',
            'codigo_qr.required_without' => 'Debe proporcionar el folio o código QR.',
        ]);

        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
        }

        $query = Boleto::query();

        if ($request->has('folio')) {
            $query->where('folio', $request->folio);
        } elseif ($request->has('codigo_qr')) {
            $query->where('codigo_qr', $request->codigo_qr);
        }

        $boleto = $query->first();

        if (!$boleto) {
            return response()->json([
                'errors' => ['boleto' => ['Boleto no encontrado.']],
                'valido' => false,
            ], JsonResponse::HTTP_NOT_FOUND);
        }

        if ($boleto->estatus !== 'pendiente') {
            return response()->json([
                'errors' => ['boleto' => ['El boleto ya fue utilizado o está cancelado.']],
                'valido' => false,
                'estatus' => $boleto->estatus,
            ], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
        }

        // Marcar como utilizado
        $boleto->update([
            'estatus' => 'utilizado',
            'usuario_validador_id' => auth()->id(),
            'fecha_validacion' => now(),
        ]);

        $boleto->load(['usuarioGenerador', 'tipoCarga', 'destino']);

        return response()->json([
            'data' => $boleto,
            'valido' => true,
            'message' => 'Boleto validado correctamente.',
        ], JsonResponse::HTTP_OK);
    }

    /**
     * Generar folio único
     */
    private function generarFolioUnico(): string
    {
        do {
            $folio = 'BOL-' . date('Ymd') . '-' . strtoupper(Str::random(6));
        } while (Boleto::where('folio', $folio)->exists());

        return $folio;
    }

    /**
     * Generar código QR
     */
    private function generarCodigoQR(string $folio): string
    {
        // Generar código QR como string base64 o JSON
        $qrData = [
            'folio' => $folio,
            'timestamp' => now()->toIso8601String(),
        ];

        return base64_encode(json_encode($qrData));
    }
}

