<?php

namespace App\Modules\Fraud\MaxMind;

use App\Services\Fraud\Contracts\FraudModuleResponse;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class Request
{
    protected ?string $accountId = null;
    protected ?string $licenseKey = null;
    protected string $serviceType = 'score';

    const URL = 'https://minfraud.maxmind.com/minfraud/v2.0/';

    public function setAccountId(string $accountId): self
    {
        $this->accountId = $accountId;
        return $this;
    }

    public function setLicenseKey(string $licenseKey): self
    {
        $this->licenseKey = $licenseKey;
        return $this;
    }

    public function setServiceType(string $serviceType): self
    {
        $serviceType = strtolower($serviceType);

        if (!in_array($serviceType, ['score', 'insights', 'factors'])) {
            throw new \Exception("Invalid service type: {$serviceType}");
        }

        $this->serviceType = $serviceType;
        return $this;
    }

    public function call(array $data): FraudModuleResponse
    {
        $url = $this->getApiEndpointUrl();

        try {
            $response = Http::withBasicAuth($this->accountId, $this->licenseKey)
                ->timeout(10)
                ->post($url, $data);

            $statusCode = $response->status();
            $body = $response->json();

            // SEC PRC-263 (KVKK Art. 12): `$data` checkout payload — ip, email,
            // billing address, kart BIN, full name içerir. PII raw log'a yazılmaz.
            // Yalnızca operasyonel metadata: URL, status, payload hash (cross-
            // request correlation için), gönderilen üst-seviye section'lar.
            Log::info('MaxMind API Request', [
                'url' => $url,
                'status' => $statusCode,
                'payload_hash' => substr(hash('sha256', json_encode($data) ?: ''), 0, 12),
                'sections' => array_keys($data),
                'response_code' => is_array($body) ? ($body['code'] ?? null) : null,
            ]);

            if (!$body) {
                throw new \Exception('Empty response from MaxMind API');
            }

            // Check if successful
            $successful = $statusCode === 200 && !isset($body['code']);

            return new FraudModuleResponse($body, $statusCode, $successful);

        } catch (\Exception $e) {
            Log::error('MaxMind API Error', [
                'error' => $e->getMessage(),
                'url' => $url,
            ]);

            throw $e;
        }
    }

    protected function getApiEndpointUrl(): string
    {
        return self::URL . $this->serviceType;
    }
}
