<?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 AddressReferenceLU
{
    private const RELEASE = 'https://data.public.lu/fr/datasets/r/5cadc5b8-6a7d-4283-87bc-f9e58dd771f7';

    public function __construct(private readonly HttpClientInterface $client, private readonly AddressReferenceBaseImporter $addressBaseImporter, private readonly PostalCodeBaseImporter $postalCodeBaseImporter, private readonly AddressToReferenceMatcher $addressToReferenceMatcher) {}

    public function import(?string $sendAddressReportToEmail = null): void
    {
        $downloadUrl = self::RELEASE;

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

        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(';');
        $csv->setHeaderOffset(0);

        $this->process_postal_code($csv);

        $this->process_address($csv, $sendAddressReportToEmail);

        $this->addressToReferenceMatcher->checkAddressesMatchingReferences();

        fclose($file);
    }

    private function process_address(Reader $csv, ?string $sendAddressReportToEmail = null): void
    {
        $stmt = new Statement();
        $stmt = $stmt->process($csv);
        foreach ($stmt as $record) {
            $this->addressBaseImporter->importAddress(
                $record['id_geoportail'],
                $record['code_postal'],
                $record['code_postal'],
                $record['rue'],
                $record['numero'],
                'bd-addresses.lux',
                (float) $record['lat_wgs84'],
                (float) $record['lon_wgs84'],
                4326
            );
        }

        $this->addressBaseImporter->finalize(sendAddressReportToEmail: $sendAddressReportToEmail);
    }

    private function process_postal_code(Reader $csv): void
    {
        $stmt = new Statement();
        $stmt = $stmt->process($csv);
        $arr_postal_codes = [];
        foreach ($stmt as $record) {
            if (false === \array_key_exists($record['code_postal'], $arr_postal_codes)) {
                $this->postalCodeBaseImporter->importCode(
                    'LU',
                    trim((string) $record['localite']),
                    trim((string) $record['code_postal']),
                    trim((string) $record['code_postal']),
                    'bd-addresses.lux',
                    (float) $record['lat_wgs84'],
                    (float) $record['lon_wgs84'],
                    4326
                );
                $arr_postal_codes[$record['code_postal']] = 1;
            }
        }
    }
}
