<?php

use Neos\Flow\Persistence\Doctrine\PersistenceManager;
use Neos\Flow\Tests\FunctionalTestCase;
use Newland\Toubiz\Api\ObjectAdapter\Concern\ArticleConstants;
use Newland\Toubiz\Api\Service\OpenWeatherMap\ApiService;
use Newland\Toubiz\Api\Service\ServiceFactory;
use Newland\Toubiz\Sync\Neos\Domain\Model\Article;
use Newland\Toubiz\Sync\Neos\Domain\Model\Weather;
use Newland\Toubiz\Sync\Neos\Service\WeatherService;
use PHPUnit\Framework\MockObject\MockObject;

class WeatherServiceTest extends FunctionalTestCase
{
    protected static $testablePersistenceEnabled = true;

    /** @var WeatherService */
    private $subject;

    /** @var Article */
    private $dummyArticle;

    /** @var MockObject<ApiService> */
    protected $mockedService;

    public function setUp(): void
    {
        parent::setUp();
        $this->subject = new WeatherService();
        $this->dummyArticle = new Article();

        $this->mockedService = $this->createMock(ApiService::class);
        foreach (WeatherService::CONFIGURATION_MAP as $serviceName) {
            ServiceFactory::mock($serviceName, $this->mockedService);
        }
    }

    public function tearDown(): void
    {
        parent::tearDown();
        ServiceFactory::resetMocks();
    }

    public function testSearchingForNonCityArticle(): void
    {
        $this->mockedService
            ->expects($this->never())
            ->method('fetchForecast');

        $this->expectException(InvalidArgumentException::class);
        $this->dummyArticle->setMainType(ArticleConstants::TYPE_TOUR);
        $this->subject->findByCityArticle($this->dummyArticle);
    }

    public function testFetchingAnExistingCityWithoutGeoLocation(): void
    {
        $this->mockedService
            ->expects($this->once())
            ->method('fetchForecast');

        $this->dummyArticle->setMainType(ArticleConstants::TYPE_CITY);
        $this->dummyArticle->setName('Aach');
        $weather = $this->subject->findByCityArticle($this->dummyArticle);
        $this->assertNull($weather);
    }

    public function testFetchingAnExistingCityWithGeoLocation(): void
    {
        $this->mockedService
            ->expects($this->once())
            ->method('fetchForecast');

        $this->dummyArticle->setMainType(ArticleConstants::TYPE_CITY);
        $this->dummyArticle->setName('Aach');
        $this->dummyArticle->setLatitude(47.843221);
        $this->dummyArticle->setLongitude(8.852687);
        $this->subject->findByCityArticle($this->dummyArticle);
    }
}
