<?php

namespace App\Service;

use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Contracts\HttpClient\HttpClientInterface;

// Fournit un accès à l’API OSM
class OpenStreetMapClient
{
    public function __construct(
        private ClientRegistry $clientRegistry,
        private HttpClientInterface $client,
        private RequestStack $requestStack,
    ) {
    }

    protected function query(string $method, string $path, array $params = [])
    {
        $session = $this->requestStack->getSession();
        $accessToken = $session->get('access_token');
        /*
        if ($accessToken->hasExpired()) {
            $accessToken = $this->clientRegistry->getClient('openstreetmap')->refreshAccessToken($accessToken->getRefreshToken());
            $session->set('access_token', $accessToken);
        }
         */
        $token = $accessToken->getToken();

        $response = $this->client->request($method, 'https://api.openstreetmap.org/api/0.6/'.$path, [
            'auth_bearer' => $token,
            'query' => $params,
        ]);

        $isStatusCodeOk = (200 === $response->getStatusCode());

        if (!$isStatusCodeOk) {
            throw new \RuntimeException();
        }

        return $response->getContent();
    }

    /* Cf <https://wiki.openstreetmap.org/wiki/API_v0.6#Query:_GET_/api/0.6/changesets> */
    public function getChangesets(?string $username = null, ?\DateTimeInterface $since = null, ?\DateTimeInterface $then = null)
    {
        $changesets = [];

        $params = [];

        if (!is_null($username)) {
            $params['display_name'] = $username;
        }

        if (!is_null($since) and !is_null($then)) {
            $params['time'] = implode(',', [
                $since->format(\DateTimeInterface::ISO8601),
                $then->format(\DateTimeInterface::ISO8601),
            ]);
        } elseif (!is_null($since) and is_null($then)) {
            $params['time'] = $since->format(\DateTimeInterface::ISO8601);
        }

        $response = $this->query('GET', 'changesets', $params);
        $xml = new \DOMDocument();
        $xml->loadXML($response);
        $xpath = new \DOMXPath($xml);
        $changesetNodes = $xpath->query('/osm/changeset');
        foreach ($changesetNodes as $changesetNode) {
            $changeset = [];
            foreach ($changesetNode->attributes as $attribute) {
                $changeset[$attribute->name] = $attribute->value;
            }
            $tagNodes = $xpath->query('./tag', $changesetNode);
            foreach ($tagNodes as $tagNode) {
                $changeset[$tagNode->getAttribute('k')] = $tagNode->getAttribute('v');
            }
            $changesets[] = $changeset;
        }

        return $changesets;
    }
}
