<?php

namespace App\State;

use App\Entity\LegalForms;
use App\Service\AppParams;
use App\Service\Functions;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\Entity\Professional;
use App\Entity\ProProfession;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use App\Service\ApiSirenService;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\HttpClient\HttpClientInterface;

class SirenProvider implements ProviderInterface
{

    // Déclaration des propriétés pour les dépendances nécessaires
    private $requestStack;
    private $apiSirenService;
    private $client;
    private $em;

    public function __construct(RequestStack $requestStack, ApiSirenService $apiSirenService, HttpClientInterface $client, EntityManagerInterface $em)
    {
        $this->requestStack = $requestStack;
        $this->apiSirenService = $apiSirenService;
        $this->client = $client;
        $this->em = $em;
    }

    // Méthode principale qui détermine l'opération à effectuer en fonction du nom de l'opération
    public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
    {
        if ($operation->getName() === 'fetch-society') {
            return $this->fetchSociety();
        }
        return null;
    }

    // Méthode pour récupérer les informations d'une société via le SIREN
    public function fetchSociety()
    {
        try {

            $request = $this->requestStack->getCurrentRequest();
            $siren = $request->query->get('siren');

            // Vérification si le SIREN est présent dans la requête, sinon renvoie un message d'erreur
            if ($siren == null) {
                return new JsonResponse([
                    'message' => 'Siren est obligatoire !',
                    'data' => null
                ], Response::HTTP_OK);
            }

            // Vérification si la longueur du SIREN est suffisante, sinon renvoie un message d'erreur
            if (strlen($siren) < 3) {
                return new JsonResponse(
                    ['message' => 'Verifiez le numéro de siren !', 'data' => null],
                    Response::HTTP_OK
                );
            }

            // Appel de l'API Siren pour récupérer les informations sur la société
            $company = $this->apiSirenService->fetchSociety($this->client, $siren);

            // Si la société n'existe pas, renvoie un message d'erreur
            if ($company == null) {
                return new JsonResponse([
                    'message' => 'Entreprise n\'existe pas !',
                    'data' => null
                ], Response::HTTP_OK);
            }

            // Récupération du nom de la forme juridique de l'entreprise en fonction du code de la nature juridique
            $legalNatureName = $this->em->getRepository(LegalForms::class)->findOneBy(['code' => $company['nature_juridique']]);

            // Création du tableau de données à renvoyer avec les informations de l'entreprise
            $data['siren'] = $company['siren'];
            $data['name'] = $company['nom_raison_sociale'];
            $data['tva'] = $this->apiSirenService->getNumTva($company['siren']); // Calcul du numéro TVA
            $data['legalNatureCode'] = $company['nature_juridique']; // Ajoute la forme juridique
            $data['legalNatureName'] = $legalNatureName ? $legalNatureName->getLabel() : "";
            $data['postalCode'] = '';
            if (isset($company["siege"])) {
                $siege = $company["siege"];
                $data['postalCode'] = $siege['code_postal'];
                $data['city'] = $siege['libelle_commune'];
                $address = preg_replace('/^\d+\s+/', '', $siege['geo_adresse']);
                $data['address'] = $address;
                $data['cityCode'] = $siege['region'];
                $data['cityName'] = $siege['libelle_commune'];
                $data['trackName'] = $siege['libelle_voie'];
                $data['trackNumber'] = $siege['numero_voie'];
                $data['latitude'] = $siege['latitude'];
                $data['longitude'] = $siege['longitude'];
                $data['codeInsee'] = $siege['commune'];
                // Suppression du code postal et de la ville de l'adresse
                $data['address'] = preg_replace(
                    '/\b' . preg_quote($siege['code_postal'], '/') . '\b\s*' . preg_quote($siege['libelle_commune'], '/') . '/i',
                    '',
                    $data['address']
                );

                // Nettoyage des espaces superflus
                $data['address'] = trim($data['address']);
            }

            // Retourne une réponse JSON avec les informations de l'entreprise récupérée
            return new JsonResponse([
                'message' => 'Entreprise récupérée avec succès.',
                'data' => $data
            ], Response::HTTP_OK);
        } catch (\Exception $e) {

            // Gestion des erreurs, en cas d'exception, retourne une erreur avec le message correspondant
            return new JsonResponse([
                'message' => "Une erreur s\'est produite lors de la récupération de l'entreprise: %s " . $e->getMessage(),
                'data' => null
            ], Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }
}
