<?php
/**
 * Ejemplo de controlador Laravel (8+) — kit FaceID v2.
 *
 * Instalación (sin Composer extra):
 *   1. Copia FaceIDClient.php (clases globales, sin namespace) a app/Services/FaceID/FaceIDClient.php.
 *      Se carga con el require_once de abajo o, si prefieres, con composer.json
 *      "autoload": {"classmap": ["app/Services/FaceID"]} + `composer dump-autoload`.
 *   2. config/services.php:
 *        'faceid' => [
 *            'url' => env('FACEID_URL', 'https://faceapi.epunemi.gob.ec'),
 *            'key' => env('FACEID_API_KEY'),          // en .env, nunca en git
 *        ],
 *   3. routes/web.php (grupo con sesión + CSRF de Laravel):
 *        Route::middleware(['auth'])->group(function () {
 *            Route::post('/faceid/enrolar', [\App\Http\Controllers\FaceIDController::class, 'enrolar']);
 *            Route::post('/faceid/verificar', [\App\Http\Controllers\FaceIDController::class, 'verificar']);
 *        });
 *   4. En la vista Blade: <meta name="csrf-token" content="{{ csrf_token() }}"> + js/ejemplo.html.
 *
 * La identidad sale de Auth::user(), NUNCA de un campo que envíe el navegador.
 */

namespace App\Http\Controllers;

use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

require_once app_path('Services/FaceID/FaceIDClient.php');

class FaceIDController extends Controller
{
    private function cliente(): \FaceIDClient
    {
        return new \FaceIDClient((string)config('services.faceid.key'), config('services.faceid.url'));
    }

    private function foto(Request $request): \CURLFile
    {
        // 5120 KB = 5 MB. La validación falla con 422 y mensajes de Laravel.
        $request->validate(['foto' => ['required', 'file', 'mimes:jpg,jpeg,png,webp', 'max:5120']]);
        $archivo = $request->file('foto');
        return new \CURLFile($archivo->getRealPath(), $archivo->getMimeType() ?: 'image/jpeg', 'captura.jpg');
    }

    private function error(\FaceIDException $e): JsonResponse
    {
        if ($e->status === 403) {
            // API key inválida o empresa desactivada: problema de configuración, no del usuario.
            Log::error('FaceID rechazó la API key: ' . $e->getMessage());
            return response()->json(['isSuccess' => false, 'message' => 'El servicio de verificación no está disponible.']);
        }
        if ($e->noCoincide) {
            return response()->json([
                'isSuccess' => false,
                'message' => 'El rostro no coincide con el registrado. Mejora la luz y vuelve a intentar.',
            ]);
        }
        return response()->json(['isSuccess' => false, 'message' => $e->getMessage()]);
    }

    /** Registra el rostro del usuario autenticado. */
    public function enrolar(Request $request): JsonResponse
    {
        $u = $request->user();
        try {
            $this->cliente()->enrolar($this->foto($request), [
                'cod_number' => (string)$u->getAuthIdentifier(),   // identificador estable de TU sistema
                'username' => (string)($u->username ?? ''),
                'nombre' => (string)($u->name ?? ''),
                'email' => (string)($u->email ?? ''),
                'permite_actualizar' => true,
            ]);
            return response()->json(['isSuccess' => true, 'message' => 'Rostro registrado correctamente.']);
        } catch (\FaceIDException $e) {
            return $this->error($e);
        }
    }

    /** Verifica que quien está frente a la cámara es el usuario autenticado. */
    public function verificar(Request $request): JsonResponse
    {
        try {
            $r = $this->cliente()->verificar($this->foto($request), [
                'cod_number' => (string)$request->user()->getAuthIdentifier(),
            ]);
            if (!empty($r['is_same_person'])) {
                // Aquí registra tu evento (asistencia, inicio de examen…). La decisión es del servidor.
                return response()->json([
                    'isSuccess' => true,
                    'message' => 'Identidad verificada.',
                    'aData' => ['is_same_person' => true, 'similarity_score' => $r['similarity_score'] ?? null],
                ]);
            }
            return response()->json(['isSuccess' => false, 'message' => 'El rostro no coincide.']);
        } catch (\FaceIDException $e) {
            return $this->error($e);
        }
    }
}
