<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\MainBundle\Service\Import;

use League\Csv\Reader;
use League\Csv\Statement;
use Symfony\Contracts\HttpClient\HttpClientInterface;

class AddressReferenceFromBano
{
    public function __construct(private readonly HttpClientInterface $client, private readonly AddressReferenceBaseImporter $baseImporter, private readonly AddressToReferenceMatcher $addressToReferenceMatcher) {}

    public function import(string $departementNo, ?string $sendAddressReportToEmail = null): void
    {
        if (!is_numeric($departementNo) || !\is_int((int) $departementNo)) {
            throw new \UnexpectedValueException('Could not parse this department number');
        }

        $url = "https://bano.openstreetmap.fr/data/bano-{$departementNo}.csv";

        $response = $this->client->request('GET', $url);

        if (200 !== $response->getStatusCode()) {
            throw new \Exception('Could not download CSV: '.$response->getStatusCode());
        }

        $file = tmpfile();

        foreach ($this->client->stream($response) as $chunk) {
            fwrite($file, $chunk->getContent());
        }

        fseek($file, 0);

        $csv = Reader::from($file);
        $csv->setDelimiter(',');
        $stmt = new Statement();
        $stmt = $stmt->process($csv, [
            'refId',
            'streetNumber',
            'street',
            'postcode',
            'city',
            '_o',
            'lat',
            'lon',
        ]);

        foreach ($stmt as $record) {
            $this->baseImporter->importAddress(
                $record['refId'],
                substr((string) $record['refId'], 0, 5), // extract insee from reference
                $record['postcode'],
                $record['street'],
                $record['streetNumber'],
                'BANO.'.$departementNo,
                (float) $record['lat'],
                (float) $record['lon'],
                4326
            );
        }

        $this->baseImporter->finalize(sendAddressReportToEmail: $sendAddressReportToEmail);

        $this->addressToReferenceMatcher->checkAddressesMatchingReferences();

        fclose($file);
    }
}
