<?php

declare(strict_types=1);

namespace App\Services\DaData;

use App\Services\DaData\Dto\PartyLookupResult;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\Client\Factory as HttpFactory;

/**
 * Suggestions findById/party — подтяжка организации по ИНН (бесплатный эндпоинт DaData).
 * POST https://suggestions.dadata.ru/suggestions/api/4_1/rs/findById/party
 *   Authorization: Token <api_key> ; body {"query":"<inn>"}
 *
 * Все ошибки (нет ключа / сеть / 4xx / 5xx / пустой ответ) → null (мягко, не бросаем).
 */
final class DaDataPartyClient implements PartyLookup
{
    private const URL = 'https://suggestions.dadata.ru/suggestions/api/4_1/rs/findById/party';

    public function __construct(private readonly HttpFactory $http) {}

    public function findByInn(string $inn): ?PartyLookupResult
    {
        $cfg = (array) config('services.dadata');
        $apiKey = (string) ($cfg['api_key'] ?? '');
        if ($apiKey === '') {
            return null;
        }
        $timeoutSec = max(1, (int) round(((int) ($cfg['timeout_ms'] ?? 2000)) / 1000));

        try {
            $response = $this->http
                ->asJson()
                ->acceptJson()
                ->timeout($timeoutSec)
                ->withHeaders(['Authorization' => 'Token '.$apiKey])
                ->post(self::URL, ['query' => $inn]);
        } catch (ConnectionException) {
            return null;
        }

        if (! $response->successful()) {
            return null;
        }

        return $this->parse($response->json());
    }

    /** @param  mixed  $body */
    private function parse($body): ?PartyLookupResult
    {
        $sug = (is_array($body) && isset($body['suggestions'][0]) && is_array($body['suggestions'][0]))
            ? $body['suggestions'][0]
            : null;
        if ($sug === null) {
            return null;
        }

        $data = is_array($sug['data'] ?? null) ? $sug['data'] : [];
        $name = (string) ($sug['value'] ?? '');
        if ($name === '') {
            return null;
        }

        return new PartyLookupResult(
            legalName: $name,
            kpp: isset($data['kpp']) ? (string) $data['kpp'] : null,
            ogrn: isset($data['ogrn']) ? (string) $data['ogrn'] : null,
            address: isset($data['address']['value']) ? (string) $data['address']['value'] : null,
            type: isset($data['type']) ? (string) $data['type'] : '',
            raw: $sug,
        );
    }
}
