<?php

namespace common\modules\event\models\copy;

use common\models\Event;
use common\modules\event\manager\EventManager;
use common\modules\event\models\timetable\TimeTableMonth;
use common\modules\event\models\timetable\TimeTableMonthDay;
use customerapi\models\available\EventInterval;
use DateTime;
use Exception;
use Yii;
use yii\base\Model;

/**
 * @property string $sourceDateString
 * @property string $targetDateString
 * @property integer $timestampSource
 * @property integer $timestampTarget
 * @property EventInterval $sourceInterval
 * @property EventInterval $targetInterval
 * @property TimeTableMonth $sourceTimeTable
 * @property TimeTableMonth $targetTimeTable
 */
class CopyWeekForm extends Model
{


    public /** @noinspection PhpUnused */
        $sourceDateString;
    public $timestampSource;

    public /** @noinspection PhpUnused */
        $targetDateString;
    public $timestampTarget;

    public $sourceInterval;
    public $targetInterval;

    public $sourceTimeTable;
    public $targetTimeTable;

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['sourceDateString',], 'date', 'format' => Yii::$app->formatter->dateFormat, 'timestampAttribute' => 'timestampSource', 'timeZone' => 'UTC'],
            [['targetDateString',], 'date', 'format' => Yii::$app->formatter->dateFormat, 'timestampAttribute' => 'timestampTarget', 'timeZone' => 'UTC'],
            [['targetDateString',], 'validateTargetWeekHasNoEvents'],
        ];
    }

    /**
     * @throws Exception
     */
    public function save(){

        $sourceDate =  new DateTime();
        $sourceDate->setTimestamp($this->timestampSource);
        $sourceDate->modify('this week');

        $targetDate =  new DateTime();
        $targetDate->setTimestamp($this->timestampTarget);
        $targetDate->modify('this week');

        $this->sourceInterval = EventInterval::createInterval($sourceDate,7,7);
        $this->targetInterval = EventInterval::createInterval($targetDate,7,7);

        // load the time table objects for source and target interval
        $eventManager = new EventManager();
        $this->sourceTimeTable = $eventManager->loadTimeTable($this->sourceInterval);
        $this->targetTimeTable = $eventManager->loadTimeTable($this->targetInterval);

        $sourceWeek = $this->sourceTimeTable->weeks[0];
        $targetWeek = $this->targetTimeTable->weeks[0];

        // Iterate over all the week days: monday, tuesday, ...
        foreach (EventInterval::weekdays as $weekday ){
            // this is very ugly
            // it returns eg.: $sourceWeek->monday , $sourceWeek->tuesday...
            /** @var TimeTableMonthDay $sourceDay */
            $sourceDay = $sourceWeek->$weekday;
            /** @var TimeTableMonthDay $targetDay */
            $targetDay = $targetWeek->$weekday;

            $sourceEvents = $sourceDay->events;

            /** @var Event $sourceEvent */
            foreach ($sourceEvents as $sourceEvent ){
                $event = new Event();
                $event->start  = $sourceEvent->start;
                $event->id_room = $sourceEvent->id_room;
                $event->id_event_type = $sourceEvent->id_event_type;
                $event->id_trainer = $sourceEvent->id_trainer;
                $event->seat_count = $sourceEvent->seat_count;
                $event->active = $sourceEvent->active;
                $event->deleted_at = $sourceEvent->deleted_at;

                $start = $this->createDateTime(new DateTime('@'.$targetDay->date),new DateTime('@'.$event->start));
                $event->start = $start->getTimestamp();

                // end date is start date + duration
                $eventDuration = $sourceEvent->end - $sourceEvent->start;
                $event->end   = $start->getTimestamp() + $eventDuration;

                $event->save(false);

            }

        }

    }

    /**
     * Create a DateTime object from 2 input DateTimes.
     * The first input will be used to set the date part.
     * The second input will be used to set the time part.
     *
     * @param DateTime $date the date part of the new date will set to the values of this object
     * @param DateTime $time the time part of the new date will set to the values of this object
     * @return DateTime
     * @throws Exception
     */
    private function createDateTime($date,$time){
        $result = new DateTime();
        $result->setDate($date->format('Y'),$date->format('m'),$date->format('d'));
        $result->setTime($time->format('H'),$time->format('i'));
        return $result;
    }
}
