<?php

declare(strict_types=1);

namespace Seka\Terminy\Actions;

use DateTimeZone;
use Eluceo\iCal\Domain\Entity\Event;
use Eluceo\iCal\Domain\Entity\Calendar;
use Eluceo\iCal\Presentation\Component;
use Eluceo\iCal\Domain\Entity\TimeZone;
use Seka\Terminy\Models\Udalost\Udalost;
use Eluceo\iCal\Domain\ValueObject\TimeSpan;
use Eluceo\iCal\Domain\ValueObject\DateTime;
use Eluceo\iCal\Domain\ValueObject\Location;
use Eluceo\iCal\Domain\ValueObject\Timestamp;
use Eluceo\iCal\Presentation\Factory\CalendarFactory;
use Eluceo\iCal\Domain\ValueObject\GeographicPosition;

/**
 * Class iCalendarFactory
 *
 * @package Seka\Terminy\Actions
 */
class iCalendarFactory
{
    /**
     * @param \Seka\Terminy\Models\Udalost\Udalost $udalost
     *
     * @return \Eluceo\iCal\Presentation\Component
     * @throws \Exception
     */
    public static function make(Udalost $udalost): Component
    {
        /** @var \Seka\Terminy\Models\MiestoKonania\MiestoKonania $miestoKonania */
        $miestoKonania = $udalost->miestoKonania;

        $location = new Location($miestoKonania->adresa);

        if ($miestoKonania->obsahujeGeografickuPolohu()) {
            $location = $location->withGeographicPosition(
                new GeographicPosition($miestoKonania->latitude, $miestoKonania->longitude)
            );
        }

        $event = (new Event())
            ->setSummary($udalost->nazov . ' [' . $udalost->druh->label . ']')
            ->setDescription(strip_tags($udalost->popis ?? ''))
            ->setLocation($location)
            ->setOccurrence(
                new TimeSpan(
                    new DateTime($udalost->datum_od->toDateTimeImmutable(), true),
                    new DateTime($udalost->datum_do->toDateTimeImmutable(), true)
                )
            )
            ->touch(new Timestamp($udalost->updated_at->toDateTimeImmutable()));

        $calendar = new Calendar([$event]);
        $calendar->setProductIdentifier(config('app.name'));
        $calendar = $calendar->addTimeZone(TimeZone::createFromPhpDateTimeZone(
            new DateTimeZone(config('app.timezone')),
            $udalost->datum_od->toDateTimeImmutable(),
            $udalost->datum_do->toDateTimeImmutable()
        ));
        $componentFactory = new CalendarFactory();

        return $componentFactory->createCalendar($calendar);
    }
}
