<?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\DataFixtures\ORM;

use Chill\MainBundle\Doctrine\Model\Point;
use Chill\MainBundle\Entity\AddressReference;
use Chill\MainBundle\Entity\PostalCode;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;

/**
 * Load reference addresses into database.
 */
class LoadAddressReferences extends Fixture implements OrderedFixtureInterface
{
    protected $faker;

    public function __construct()
    {
        $this->faker = \Faker\Factory::create('fr_FR');
    }

    public function getOrder(): int
    {
        return 51;
    }

    public function load(ObjectManager $manager): void
    {
        echo "loading some reference address... \n";

        for ($i = 0; 10 > $i; ++$i) {
            $ar = $this->getRandomAddressReference();
            $manager->persist($ar);
        }

        $manager->flush();
    }

    /**
     * Create a random reference address.
     */
    private function getRandomAddressReference(): AddressReference
    {
        $ar = new AddressReference();

        $ar->setRefId($this->faker->numerify('ref-id-######'));
        $ar->setStreet($this->faker->streetName);
        $ar->setStreetNumber((string) random_int(0, 199));
        $ar->setPoint($this->getRandomPoint());
        $ar->setPostcode($this->getReference(
            LoadPostalCodes::$refs[array_rand(LoadPostalCodes::$refs)],
            PostalCode::class
        ));

        $ar->setMunicipalityCode($ar->getPostcode()->getCode());

        return $ar;
    }

    /**
     * Create a random point.
     */
    private function getRandomPoint(): Point
    {
        $lonBrussels = 4.35243;
        $latBrussels = 50.84676;
        $lon = $lonBrussels + 0.01 * random_int(-5, 5);
        $lat = $latBrussels + 0.01 * random_int(-5, 5);

        return Point::fromLonLat($lon, $lat);
    }
}
