<?php declare(strict_types=1);
namespace Newland\Toubiz\Sync\Neos\Domain\Model;

/*
 * This file is part of the "toubiz-sync-neos" package.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 */

use Doctrine\ORM\Mapping as ORM;
use Neos\Flow\Annotations as Flow;
use Newland\Toubiz\Api\ObjectAdapter\ProvidesRawJson;
use Newland\Toubiz\Api\ObjectAdapter\Weather\DayAdapterInterface;
use Newland\Toubiz\Api\ObjectAdapter\Weather\HourAdapterInterface;
use Newland\Toubiz\Api\ObjectAdapter\WeatherAdapterInterface;
use Newland\Toubiz\Api\Service\OpenWeatherMap\ObjectAdapter\WeatherAdapter;

/**
 * @Flow\Entity
 * @ORM\Table(indexes={
 *      @ORM\Index(name="newland_toubiz_sync_neos_weather_import_ident", columns={"location"})
 * })
 * @deprecated This model will be removed in the future.
 */
class Weather extends AbstractEntity
{
    /**
     * @ORM\Column(type="object", nullable=true)
     * @var WeatherAdapterInterface | null
     */
    protected $data;

    /**
     * @var string
     */
    protected $location;

    /**
     * @var \DateTimeInterface
     */
    protected $updatedAt;

    public function setData(WeatherAdapterInterface $data): void
    {
        $this->data = $data;
    }

    public function setLocation(string $location): void
    {
        $this->location = $location;
    }

    public function getLocation(): string
    {
        return $this->location;
    }

    public function setUpdatedAt(\DateTimeInterface $updatedAt): void
    {
        $this->updatedAt = $updatedAt;
    }

    public function getUpdatedAt(): \DateTimeInterface
    {
        return $this->updatedAt;
    }

    /**
     * @return DayAdapterInterface[]
     */
    public function getForecast(): array
    {
        if ($this->data === null) {
            return [];
        }

        return $this->data->getForecast();
    }

    public function jsonSerialize(): array
    {
        $serialized = [
            'originalId' => $this->originalId,
            'location' => $this->location,
            'updatedAt' => $this->updatedAt->format('Y-m-d\TH:i:s'),
            'forecast' => array_map([ $this, 'serializeDay' ], $this->getForecast()),
        ];

        if ($this->data instanceof ProvidesRawJson) {
            $serialized['rawJson'] = $this->data->getRawJson();
        }

        return $serialized;
    }

    protected function serializeDay(DayAdapterInterface $day): array
    {
        $serialized = [
            'date' => $day->getDate()->format('Y-m-d\TH:i:s'),
            'minimumTemperature' => $day->getMinimumTemperature(),
            'maximumTemperature' => $day->getMaximumTemperature(),
            'symbol' => $day->getSymbol(),
            'sunshineDuration' => $day->hasSunshineDurationData() ? $day->getSunshineDuration() : null,
            'allHours' => array_map([ $this, 'serializeHour' ], $day->getAllHours()),
            'mainHours' => array_map([ $this, 'serializeHour' ], $day->getMainHours()),
            'mainHoursPadded' => array_map([ $this, 'serializeHour' ], $day->getMainHoursPadded()),
        ];


        if ($day instanceof ProvidesRawJson) {
            $serialized['rawJson'] = $day->getRawJson();
        }

        return $serialized;
    }

    protected function serializeHour(HourAdapterInterface $hour): array
    {
        $serialized = [
            'date' => $hour->getDate()->format('Y-m-d\TH:i:s'),
            'externalId' => $hour->getExternalId(),
            'symbol' => $hour->getSymbol(),
            'minimumTemperature' => $hour->getMinimumTemperature(),
            'maximumTemperature' => $hour->getMaximumTemperature(),
            'time' => $hour->getTime(),
        ];

        if ($hour instanceof ProvidesRawJson) {
            $serialized['rawJson'] = $hour->getRawJson();
        }

        return $serialized;
    }
}
