<?php

namespace App\Http\Middleware;

use App\Models\BiometricDevice;
use App\Models\Company;
use App\Services\CompanyResolver;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;

class AuthenticateBiometricDevice
{
    public function __construct(
        protected CompanyResolver $companyResolver
    ) {}

    public function handle(Request $request, Closure $next): Response
    {
        $username = (string) $request->getUser();
        $password = (string) $request->getPassword();

        if ($username === '' || $password === '') {
            return $this->unauthorized();
        }

        $device = BiometricDevice::withoutGlobalScopes()
            ->where('api_username', $username)
            ->first();

        if (! $device || ! $device->is_active) {
            Log::warning('zkteco.auth_failed', [
                'username' => $username,
                'ip' => $request->ip(),
                'reason' => $device ? 'inactive' : 'unknown_user',
            ]);

            return $this->unauthorized();
        }

        if (! Hash::check($password, $device->api_password_hash)) {
            Log::warning('zkteco.auth_failed', [
                'username' => $username,
                'ip' => $request->ip(),
                'reason' => 'bad_password',
            ]);

            return $this->unauthorized();
        }

        if (! $device->allowsIp($request->ip())) {
            Log::warning('zkteco.auth_failed', [
                'username' => $username,
                'ip' => $request->ip(),
                'reason' => 'ip_not_allowed',
            ]);

            return response()->json(['message' => 'IP not allowed for this device.'], 403);
        }

        $company = Company::withoutGlobalScopes()->find($device->company_id);
        if (! $company) {
            return $this->unauthorized();
        }

        $this->companyResolver->setCompany($company);
        $request->attributes->set('biometric_device', $device);
        $request->attributes->set('biometric_company', $company);

        return $next($request);
    }

    protected function unauthorized(): Response
    {
        return response()->json(['message' => 'Unauthenticated.'], 401, [
            'WWW-Authenticate' => 'Basic realm="ZKTeco"',
        ]);
    }
}
