<?php

namespace App\Modules\Pilkades\Services;

use App\Modules\Pilkades\Models\Voter;
use App\Modules\Pilkades\Models\VoterSearchLog;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;

class VoterSearchService
{
    public function search(Request $request, string $desaId, string $type, string $query): Collection
    {
        $results = $type === 'nik'
            ? Voter::with('tps')->where('desa_id', $desaId)->where('nik_hash', Voter::hashNik($query))->get()
            : Voter::with('tps')->where('desa_id', $desaId)->where('nama', 'like', '%'.$query.'%')->limit(20)->get();

        $this->logSearch($request, $desaId, $type, $query, $results->count());

        return $results->map(fn (Voter $voter) => [
            'nama' => $voter->nama,
            'nik_masked' => Voter::maskNik($voter->nik),
            'tps' => $voter->tps ? "TPS {$voter->tps->nomor} - {$voter->tps->nama_lokasi}" : '-',
            'rt' => $voter->rt,
            'rw' => $voter->rw,
            'status_terdaftar' => $voter->status_terdaftar,
        ]);
    }

    /**
     * FR-036: record every public voter search for anti-scraping audit —
     * IP hash + timestamp + masked query, never the raw query or results.
     */
    protected function logSearch(Request $request, string $desaId, string $type, string $query, int $resultCount): void
    {
        $masked = $type === 'nik'
            ? Voter::maskNik($query)
            : (mb_strlen($query) > 2 ? mb_substr($query, 0, 2).str_repeat('*', max(mb_strlen($query) - 2, 0)) : $query);

        VoterSearchLog::create([
            'desa_id' => $desaId,
            'ip_hash' => hash('sha256', $request->ip()),
            'query_type' => $type,
            'query_masked' => $masked,
            'result_count' => $resultCount,
        ]);
    }
}
