<?php

namespace App\Modules\Attendance\Controllers;

use App\Core\BaseApiController;
use App\Modules\Face\Models\StudentFaceModel;
use App\Modules\Face\Services\FaceService;
use CodeIgniter\HTTP\ResponseInterface;

/**
 * FaceVerifyController
 *
 * POST /api/attendance/verify-face
 * Body: { "student_id": 123, "image": "data:image/jpeg;base64,..." }
 *
 * Strategi: Option 1 — bandingkan probe hanya dengan embedding milik student_id kandidat.
 */
class FaceVerifyController extends BaseApiController
{
    public function verify(): ResponseInterface
    {
        $payload   = $this->request->getJSON(true) ?? [];
        $studentId = (int) ($payload['student_id'] ?? 0);
        $imageData = (string) ($payload['image'] ?? '');

        if ($studentId < 1) {
            return $this->errorResponse('student_id wajib diisi', null, null, ResponseInterface::HTTP_UNPROCESSABLE_ENTITY);
        }
        if ($imageData === '') {
            return $this->errorResponse('image (base64) wajib diisi', null, null, ResponseInterface::HTTP_UNPROCESSABLE_ENTITY);
        }

        $tmpFile = tempnam(sys_get_temp_dir(), 'probe_');

        try {
            $raw = $this->decodeBase64Image($imageData);
            if ($raw === null) {
                throw new \RuntimeException('Format gambar tidak valid (harus base64)');
            }
            file_put_contents($tmpFile, $raw);

            $faceService = new FaceService();
            $probe       = $faceService->extractEmbeddingWithQuality($tmpFile)['embedding'];

            $faceModel = new StudentFaceModel();
            $rows      = $faceModel->where('student_id', $studentId)->findAll();
            if (empty($rows)) {
                return $this->errorResponse('Belum ada embedding wajah untuk siswa ini', null, null, ResponseInterface::HTTP_NOT_FOUND);
            }

            $bestSim    = -1.0;
            $bestSource = null;

            foreach ($rows as $row) {
                $embedding = json_decode($row['embedding'] ?? '[]', true);
                if (! is_array($embedding) || $embedding === []) {
                    continue;
                }
                $sim = $faceService->cosineSimilarity($probe, array_map('floatval', $embedding));
                if ($sim > $bestSim) {
                    $bestSim    = $sim;
                    $bestSource = $row['source'] ?? null;
                }
            }

            if ($bestSim < 0) {
                return $this->errorResponse('Tidak ada embedding valid untuk siswa ini', null, null, ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);
            }

            $threshold = $faceService->getDefaultThreshold();
            $status    = $bestSim >= $threshold ? 'match' : 'no_match';

            $data = [
                'student_id'    => $studentId,
                'similarity'    => $bestSim,
                'threshold'     => $threshold,
                'matched_source'=> $bestSource,
                'status'        => $status,
            ];

            return $this->successResponse($data, 'Face verification processed');
        } catch (\Throwable $e) {
            return $this->errorResponse('Gagal verifikasi wajah: ' . $e->getMessage(), null, null, ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);
        } finally {
            if (is_file($tmpFile)) {
                @unlink($tmpFile);
            }
        }
    }

    protected function decodeBase64Image(string $input): ?string
    {
        $input = trim($input);
        if ($input === '') {
            return null;
        }
        if (strpos($input, 'base64,') !== false) {
            $parts = explode('base64,', $input, 2);
            $input = $parts[1];
        }
        $data = base64_decode($input, true);
        return $data === false ? null : $data;
    }
}

