<?php

namespace App\Http\Controllers\API\v1\Voter;

use Illuminate\Http\Request;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Validation\Rule;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Util;
use App\Services\PhysicalAttendanceGateCode;
use App\Voter;

class AttendanceController extends Controller
{
    //
    public function __invoke(Request $request, $id)
    {
    	$this->validateRequest($request, $id);
    	$this->assertPhysicalGateCode($request);
    	$this->updateAttendance($request, $id);
    	return response()->json([
    		'status' => 'success',
    		'message' => 'Kehadiran anda telah disahkan.'
    	]);
    }

    private function validateRequest($request, $id)
    {
    	$rules = [
    		'name' => [
                'required', 
                Rule::unique('voter')->ignore($id)->where(function($query){
                    $query->where('election_id', Util::getCurrentElection());
                })
            ],
    		'no_kp' => [
                'required', 
                Rule::unique('voter')->ignore($id)->where(function($query){
                    $query->where('election_id', Util::getCurrentElection());
                })
            ],

    		'unit' => 'required',

            'no_anggota' => [
                'required', 
                Rule::unique('voter')->ignore($id)->where(function($query){
                    $query->where('election_id', Util::getCurrentElection());
                })
            ],

            'kehadiran' => 'required',
    	];

    	if (config('physical_attendance_gate.enabled')) {
    		$rules['physical_gate_code'] = 'required_if:kehadiran,1|string|max:64';
    	}

    	$this->validate($request, $rules);
    }

    /**
     * When gate is enabled, Fizikal (kehadiran = 1) must match the rotating counter code.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    private function assertPhysicalGateCode(Request $request)
    {
    	if (!config('physical_attendance_gate.enabled')) {
    		return;
    	}

    	if ((int) $request->input('kehadiran') !== 1) {
    		return;
    	}

    	$gate = app(PhysicalAttendanceGateCode::class);
    	if (!$gate->isConfigured()) {
    		throw new HttpResponseException(response()->json([
    			'status' => 'failed',
    			'message' => 'Pengesahan kod fizikal tidak dikonfigurasi dengan betul.',
    		], 503));
    	}

    	if (!$gate->validates(Util::getCurrentElection(), (string) $request->input('physical_gate_code'))) {
    		throw new HttpResponseException(response()->json([
    			'status' => 'failed',
    			'message' => 'Kod kaunter tidak sah atau telah tamat tempoh. Sila semak skrin pendaftaran dan cuba lagi.',
    		], 422));
    	}
    }

    private function updateAttendance($request, $id)
    {
    	$voter = Voter::findOrFail($id);
    	$voter->fill($request->only(['name', 'no_kp', 'no_anggota', 'unit', 'kehadiran']));

        // Skip admin verification phase for Fizikal.
        // When Fizikal is selected and (optionally) the counter gate code is valid, we auto-verify.
        // For non-Fizikal attendance, keep this field cleared.
    	if ((int) $voter->kehadiran === 1) {
    		$voter->fizikal_registration_verified_at = now();
    	} else {
            $voter->fizikal_registration_verified_at = null;
        }

    	$voter->save();

        $mode = ((int) $voter->kehadiran === 1) ? 'physical' : 'online';

        activity()
            ->performedOn($voter)
            ->withProperties([
                'voter_id' => $voter->id,
                'voter_name' => $voter->name,
                'election_id' => Util::getCurrentElection(),
                'attendance_mode' => $mode,
                'ip' => request()->ip(),
                'user_agent' => request()->userAgent(),
            ])
            ->log("confirm attendance ({$mode}): {$voter->name}");
    }

}
