<?php

declare(strict_types=1);

namespace App\Services\Identity;

use App\Models\IdentityVerification;
use App\Services\Compliance\AuditLogger;

class IdentityRouter
{
    public function __construct(private readonly AuditLogger $auditLogger)
    {
    }

    public function gateway(string $provider): IdentityProviderInterface
    {
        $config = ['mock' => $this->isMockMode($provider)];

        return match ($provider) {
            'nice' => new NiceProvider($config),
            'siren24' => new Siren24Provider($config),
            default => throw new \InvalidArgumentException("Unsupported identity provider: {$provider}"),
        };
    }

    public function request(string $provider, ?string $userId = null, array $context = []): IdentityVerification
    {
        $gw = $this->gateway($provider);
        $res = $gw->buildRequest($context);

        $tenantId = app()->bound('currentTenant') ? app('currentTenant')->id : null;

        $verification = IdentityVerification::create([
            'tenant_id' => $tenantId,
            'user_id' => $userId,
            'provider' => $provider,
            'request_id' => $res['request_id'],
            'status' => IdentityVerification::STATUS_PENDING,
            'expired_at' => now()->addMinutes(15),
        ]);

        $verification->setAttribute('standard_url', $res['standard_url']);
        $this->auditLogger->log('identity.request', null, [
            'provider' => $provider,
            'request_id' => $res['request_id'],
        ]);

        return $verification;
    }

    public function handleCallback(string $provider, array $payload): IdentityVerification
    {
        $gw = $this->gateway($provider);
        $parsed = $gw->parseCallback($payload);

        $requestId = $payload['request_id'] ?? ($parsed['raw']['request_id'] ?? null);
        if (! $requestId) {
            throw new \DomainException('Missing request_id in callback.');
        }

        $verification = IdentityVerification::where('provider', $provider)
            ->where('request_id', $requestId)
            ->firstOrFail();

        $isVerified = ($parsed['status'] ?? null) === 'verified';
        $verification->forceFill([
            'ci' => $parsed['ci'] ?? null,
            'di' => $parsed['di'] ?? null,
            'name' => $parsed['name'] ?? null,
            'birthdate' => $parsed['birthdate'] ?? null,
            'gender' => $parsed['gender'] ?? null,
            'mobile' => $parsed['mobile'] ?? null,
            'carrier' => $parsed['carrier'] ?? null,
            'status' => $isVerified ? IdentityVerification::STATUS_VERIFIED : IdentityVerification::STATUS_FAILED,
            'verified_at' => $isVerified ? now() : null,
        ])->save();

        $this->auditLogger->log('identity.callback', null, [
            'provider' => $provider,
            'request_id' => $requestId,
            'status' => $verification->status,
        ]);

        return $verification->refresh();
    }

    public function isMockMode(string $provider): bool
    {
        $perProvider = env('IDENTITY_'.strtoupper($provider).'_MOCK');
        if ($perProvider !== null) {
            return (bool) $perProvider;
        }
        return (bool) env('IDENTITY_MOCK', '1');
    }
}
