<?php

namespace App\Service;

use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;

/**
 * @phpstan-type NafEntry array{id: string, label: string}
 */
class SiretService
{
    private const API_URL = 'https://recherche-entreprises.api.gouv.fr/search';

    private const NATURE_JURIDIQUE = [
        '1000' => 'Entrepreneur individuel',
        '5410' => 'SARL',
        '5499' => 'SARL unipersonnelle',
        '5505' => 'SA a conseil d\'administration',
        '5510' => 'SA a directoire',
        '5599' => 'SA a conseil d\'administration',
        '5710' => 'SAS',
        '5720' => 'SASU',
        '6540' => 'Societe cooperative',
        '9210' => 'Association non declaree',
        '9220' => 'Association declaree',
        '9221' => 'Association declaree d\'insertion',
        '9222' => 'Association intermediaire',
        '9223' => 'Association reconnue d\'utilite publique',
        '9224' => 'Association de droit local',
        '9230' => 'Association en justice',
        '9240' => 'Association agree d\'education populaire',
        '9260' => 'Association sportive agree',
        '9300' => 'Fondation',
    ];

    /** @var array<string, string>|null */
    private ?array $nafCodes = null;

    public function __construct(
        private HttpClientInterface $httpClient,
        #[Autowire(service: 'siret.cache')] private CacheInterface $cache,
        #[Autowire('%kernel.project_dir%')] private string $projectDir,
    ) {
    }

    /**
     * @return array<string, mixed>|null
     */
    public function lookup(string $siret): ?array
    {
        return $this->cache->get('siret_'.$siret, function (ItemInterface $item) use ($siret): ?array {
            $item->expiresAfter(86400);

            try {
                $response = $this->httpClient->request('GET', self::API_URL, [
                    'query' => ['q' => $siret, 'per_page' => 1],
                ]);

                $result = $response->toArray(false);

                if (isset($result['results'][0])) {
                    $data = $result['results'][0];
                    $data['libelle_nature_juridique'] = self::NATURE_JURIDIQUE[$data['nature_juridique'] ?? ''] ?? null;
                    $data['libelle_activite_principale'] = $this->getNafLabel($data['activite_principale'] ?? '');

                    return $data;
                }
            } catch (\Throwable) {
                // Entreprise API unavailable, return null to cache empty result
            }

            return null;
        });
    }

    /**
     * @return array<string, mixed>|null
     */
    public function lookupRna(string $rna): ?array
    {
        return $this->cache->get('rna_'.$rna, function (ItemInterface $item) use ($rna): ?array {
            $item->expiresAfter(86400);

            try {
                $response = $this->httpClient->request('GET', 'https://journal-officiel-datadila.opendatasoft.com/api/records/1.0/search/', [
                    'query' => ['dataset' => 'jo_associations', 'q' => $rna, 'rows' => 1],
                ]);

                $result = $response->toArray(false);

                if (isset($result['records'][0]['fields'])) {
                    return $result['records'][0]['fields'];
                }
            } catch (\Throwable) { // @codeCoverageIgnore
                // JOAFE API unavailable, return null to cache empty result
            }

            return null;
        });
    }

    public function clearCache(string $siret, ?string $rna = null): void
    {
        $this->cache->delete('siret_'.$siret);

        if ($rna) {
            $this->cache->delete('rna_'.$rna);
        }
    }

    public function getNatureJuridiqueLabel(string $code): ?string
    {
        return self::NATURE_JURIDIQUE[$code] ?? null;
    }

    public function getNafLabel(string $code): ?string
    {
        if (null === $this->nafCodes) {
            $path = $this->projectDir.'/naf.json';
            if (!file_exists($path)) {
                return null;
            }

            $json = (string) file_get_contents($path);

            /** @var list<NafEntry> $entries */
            $entries = json_decode($json, true) ?? [];
            $this->nafCodes = [];
            foreach ($entries as $entry) {
                $this->nafCodes[$entry['id']] = $entry['label'];
            }
        }

        return $this->nafCodes[$code] ?? null;
    }
}
