<?php
declare(strict_types=1);

namespace App\Modules\Settings;

use RuntimeException;

final class AllegroStatusDiscoveryService
{
    public function __construct(
        private readonly AllegroTokenManager $tokenManager,
        private readonly AllegroApiClient $apiClient,
        private readonly AllegroStatusMappingRepository $statusMappings
    ) {
    }

    /**
     * @return array{discovered:int, samples:int}
     */
    public function discoverAndStoreStatuses(int $maxPages = 3, int $pageLimit = 100): array
    {
        [$accessToken, $env] = $this->tokenManager->resolveToken();

        $unique = [];
        $safePages = max(1, min(10, $maxPages));
        $safeLimit = max(1, min(100, $pageLimit));
        $offset = 0;
        $samples = 0;

        for ($page = 0; $page < $safePages; $page++) {
            try {
                $response = $this->apiClient->listCheckoutForms($env, $accessToken, $safeLimit, $offset);
            } catch (RuntimeException $exception) {
                if (trim($exception->getMessage()) !== 'ALLEGRO_HTTP_401') {
                    throw $exception;
                }
                [$accessToken, $env] = $this->tokenManager->resolveToken();
                $response = $this->apiClient->listCheckoutForms($env, $accessToken, $safeLimit, $offset);
            }

            $forms = is_array($response['checkoutForms'] ?? null) ? $response['checkoutForms'] : [];
            if ($forms === []) {
                break;
            }

            foreach ($forms as $form) {
                if (!is_array($form)) {
                    continue;
                }
                $rawStatus = strtolower(trim((string) ($form['fulfillment']['status'] ?? $form['status'] ?? '')));
                if ($rawStatus === '') {
                    continue;
                }
                $samples++;
                $unique[$rawStatus] = $this->prettifyStatusName($rawStatus);
            }

            if (count($forms) < $safeLimit) {
                break;
            }

            $offset += $safeLimit;
        }

        foreach ($unique as $code => $name) {
            $this->statusMappings->upsertDiscoveredStatus((string) $code, (string) $name);
        }

        return [
            'discovered' => count($unique),
            'samples' => $samples,
        ];
    }

    private function prettifyStatusName(string $statusCode): string
    {
        $normalized = str_replace(['_', '-'], ' ', strtolower(trim($statusCode)));
        return ucfirst($normalized);
    }
}
