<?php
declare(strict_types=1);

namespace App\Modules\Shipments;

use App\Modules\Settings\ApaczkaApiClient;
use App\Modules\Settings\ApaczkaIntegrationRepository;
use Throwable;

final class ApaczkaTrackingService implements ShipmentTrackingInterface
{
    public function __construct(
        private readonly ApaczkaApiClient $apiClient,
        private readonly ApaczkaIntegrationRepository $integrationRepository
    ) {
    }

    public function supports(string $provider): bool
    {
        return $provider === 'apaczka';
    }

    public function getDeliveryStatus(array $package): ?array
    {
        $shipmentId = trim((string) ($package['shipment_id'] ?? ''));
        if ($shipmentId === '' || !ctype_digit($shipmentId)) {
            return null;
        }

        $credentials = $this->resolveCredentials();
        if ($credentials === null) {
            return null;
        }

        return $this->fetchStatus($shipmentId, $credentials[0], $credentials[1]);
    }

    /**
     * @return array{0: string, 1: string}|null
     */
    private function resolveCredentials(): ?array
    {
        try {
            $credentials = $this->integrationRepository->getApiCredentials();
            if ($credentials === null) {
                return null;
            }

            $appId = trim((string) ($credentials['app_id'] ?? ''));
            $appSecret = trim((string) ($credentials['app_secret'] ?? ''));

            return ($appId !== '' && $appSecret !== '') ? [$appId, $appSecret] : null;
        } catch (Throwable) {
            return null;
        }
    }

    private function fetchStatus(string $shipmentId, string $appId, string $appSecret): ?array
    {
        try {
            $details = $this->apiClient->getOrderDetails($appId, $appSecret, (int) $shipmentId);
            $order = is_array($details['response']['order'] ?? null) ? $details['response']['order'] : [];
            $rawStatus = (string) ($order['status'] ?? '');
            if ($rawStatus === '') {
                return null;
            }

            return [
                'status' => DeliveryStatus::normalize('apaczka', $rawStatus),
                'status_raw' => $rawStatus,
                'description' => DeliveryStatus::description('apaczka', $rawStatus),
            ];
        } catch (Throwable) {
            return null;
        }
    }
}
