<?php

namespace DynamicOOOS\Spatie\CalendarLinks;

use DynamicOOOS\Spatie\CalendarLinks\Exceptions\InvalidLink;
use DynamicOOOS\Spatie\CalendarLinks\Generators\Google;
use DynamicOOOS\Spatie\CalendarLinks\Generators\Ics;
use DynamicOOOS\Spatie\CalendarLinks\Generators\WebOutlook;
use DynamicOOOS\Spatie\CalendarLinks\Generators\Yahoo;
/**
 * @property-read string $title
 * @property-read \DateTimeInterface|\DateTime|\DateTimeImmutable $from
 * @property-read \DateTimeInterface|\DateTime|\DateTimeImmutable $to
 * @property-read string $description
 * @property-read string $address
 * @property-read bool $allDay
 */
class Link
{
    /** @var string */
    protected $title;
    /** @var \DateTime */
    protected $from;
    /** @var \DateTime */
    protected $to;
    /** @var string */
    protected $description;
    /** @var bool */
    protected $allDay;
    /** @var string */
    protected $address;
    public function __construct(string $title, \DateTimeInterface $from, \DateTimeInterface $to, bool $allDay = \false)
    {
        $this->title = $title;
        $this->allDay = $allDay;
        if ($to < $from) {
            throw InvalidLink::negativeDateRange($from, $to);
        }
        $this->from = clone $from;
        $this->to = clone $to;
    }
    /**
     * @param string $title
     * @param \DateTimeInterface $from
     * @param \DateTimeInterface $to
     * @param bool $allDay
     *
     * @return static
     * @throws InvalidLink
     */
    public static function create(string $title, \DateTimeInterface $from, \DateTimeInterface $to, bool $allDay = \false)
    {
        return new static($title, $from, $to, $allDay);
    }
    /**
     * @param string $title
     * @param \DateTimeInterface|\DateTime|\DateTimeImmutable $fromDate
     * @param int $numberOfDays
     *
     * @return Link
     * @throws InvalidLink
     */
    public static function createAllDay(string $title, \DateTimeInterface $fromDate, int $numberOfDays = 1) : self
    {
        $from = (clone $fromDate)->modify('midnight');
        $to = (clone $from)->modify("+{$numberOfDays} days");
        return new self($title, $from, $to, \true);
    }
    /**
     * @param string $description
     *
     * @return $this
     */
    public function description(string $description)
    {
        $this->description = $description;
        return $this;
    }
    /**
     * @param string $address
     *
     * @return $this
     */
    public function address(string $address)
    {
        $this->address = $address;
        return $this;
    }
    public function formatWith(Generator $generator) : string
    {
        return $generator->generate($this);
    }
    public function google() : string
    {
        return $this->formatWith(new Google());
    }
    public function ics(array $options = []) : string
    {
        return $this->formatWith(new Ics($options));
    }
    public function yahoo() : string
    {
        return $this->formatWith(new Yahoo());
    }
    public function webOutlook() : string
    {
        return $this->formatWith(new WebOutlook());
    }
    public function __get($property)
    {
        return $this->{$property};
    }
}
