<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

class AmlScreeningApiService
{
    private string $baseUrl;
    private ?string $appId;
    private ?string $secret;
    private int $timeout;

    public function __construct()
    {
        $env = config('nin.dojah_env', 'sandbox');

        $this->baseUrl = $env === 'live'
            ? 'https://api.dojah.io'
            : 'https://sandbox.dojah.io';

        $this->appId   = config('nin.dojah_app_id');
        $this->secret  = config('nin.dojah_secret');
        $this->timeout = config('nin.timeout', 30);
    }

    /**
     * Run an AML/PEP screening for an individual.
     *
     * Dojah endpoint: POST /api/v1/aml/v2/screening
     * Schema: individual
     *
     * @param string      $names       Full name
     * @param string|null $dateOfBirth YYYY-MM-DD
     * @param string|null $nationality Country code e.g. "NG"
     * @param string|null $gender      "male" | "female"
     * @return array ['success', 'risk_level', 'match_status', 'total_results', 'total_articles', 'results', 'entity_id', 'service_unavailable'?]
     */
    public function screenIndividual(
        string $names,
        ?string $dateOfBirth = null,
        ?string $nationality = null,
        ?string $gender = null
    ): array {
        $properties = array_filter([
            'names'         => $names,
            'date_of_birth' => $dateOfBirth,
            'nationality'   => $nationality,
            'gender'        => $gender,
        ]);

        return $this->screen('individual', $properties);
    }

    /**
     * Run an AML/PEP screening for an organisation.
     *
     * Dojah endpoint: POST /api/v1/aml/v2/screening
     * Schema: organization
     *
     * @param string      $names               Company name
     * @param string|null $registrationNumber  RC number
     * @param string|null $country             Country code e.g. "NG"
     * @return array
     */
    public function screenOrganization(
        string $names,
        ?string $registrationNumber = null,
        ?string $country = null
    ): array {
        $properties = array_filter([
            'names'                   => $names,
            'registration_number'     => $registrationNumber ? [$registrationNumber] : null,
            'country_of_incorporation'=> $country ? [$country] : null,
        ]);

        return $this->screen('organization', $properties);
    }

    /**
     * Core screening call — builds payload, calls Dojah, parses response.
     */
    private function screen(string $schema, array $properties): array
    {
        $reference    = 'AML_' . now()->format('ymdHis') . '_' . strtoupper(Str::random(6));
        $requestStart = microtime(true);

        $payload = [
            'schema'           => $schema,
            'unique_reference' => $reference,
            'properties'       => $properties,
            'screening_options' => [
                'pep_check'          => true,
                'sanction'           => true,
                'adverse_media_check'=> true,
                'match_threshold'    => 0.85,
            ],
        ];

        try {
            Log::info('AML SCREENING REQUEST', [
                'reference'   => $reference,
                'schema'      => $schema,
                'environment' => config('nin.dojah_env'),
                'endpoint'    => $this->baseUrl . '/api/v1/aml/v2/screening',
            ]);

            $response = Http::withHeaders([
                'AppId'         => $this->appId,
                'Authorization' => $this->secret,
                'Content-Type'  => 'application/json',
            ])
                ->timeout($this->timeout)
                ->post($this->baseUrl . '/api/v1/aml/v2/screening', $payload);

            $duration = round((microtime(true) - $requestStart) * 1000);

            Log::info('AML SCREENING RESPONSE', [
                'reference'   => $reference,
                'status_code' => $response->status(),
                'duration_ms' => $duration,
            ]);

            if ($response->serverError()) {
                Log::error('AML screening service error', [
                    'reference' => $reference,
                    'status'    => $response->status(),
                    'body'      => $response->body(),
                ]);
                return [
                    'success'           => false,
                    'service_unavailable' => true,
                    'message'           => 'AML screening service is currently unavailable.',
                ];
            }

            if ($response->failed()) {
                Log::error('AML screening request failed', [
                    'reference' => $reference,
                    'status'    => $response->status(),
                    'body'      => $response->body(),
                ]);
                return [
                    'success' => false,
                    'message' => 'AML screening request failed.',
                ];
            }

            $body   = $response->json();
            $entity = $body['entity'] ?? null;

            if (! $entity) {
                Log::warning('AML screening returned no entity', [
                    'reference' => $reference,
                    'body'      => $body,
                ]);
                return [
                    'success' => false,
                    'message' => 'AML screening returned an unexpected response.',
                ];
            }

            return [
                'success'        => true,
                'entity_id'      => $entity['entity_id'] ?? null,
                'risk_level'     => $entity['risk_level'] ?? null,
                'match_status'   => $entity['match_status'] ?? null,
                'total_results'  => $entity['total_results'] ?? 0,
                'total_articles' => $entity['total_articles'] ?? 0,
                'results'        => $entity['results'] ?? [],
            ];

        } catch (\Illuminate\Http\Client\ConnectionException $e) {
            Log::error('AML screening connection timeout', [
                'reference' => $reference,
                'error'     => $e->getMessage(),
            ]);
            return [
                'success'             => false,
                'service_unavailable' => true,
                'message'             => 'AML screening service timed out.',
            ];
        } catch (\Exception $e) {
            Log::error('AML screening unexpected error', [
                'reference' => $reference,
                'error'     => $e->getMessage(),
            ]);
            return [
                'success' => false,
                'message' => 'An unexpected error occurred during AML screening.',
            ];
        }
    }
}
