<?php

class Calendar
{
    public $ical;
    private $categories = [];

    public static function setup()
    {
        $pageName = 'Kalender';
        $page_exists = get_page_by_path($pageName, OBJECT, 'page');

        // Wenn die Seite nicht existiert, erstelle sie
        if (!$page_exists) {
            $page_id = wp_insert_post(array(
                'post_title' => $pageName,
                'post_content' => '{{calendar}}',
                'post_status' => 'publish',
                'post_type' => 'page',
            ));

            update_option('bdp_calendar_source_url', 'https://wiki.sachsen.pfadfinden.de/rest/calendar-services/1.0/calendar/export/subcalendar/private/ff69f5a689391ac0d7f78a70189cfde7c48cb923.ics');
        }
    }


    public static function printCalendar($content) : string {
        // Der zu ersetzende String
        $original_string = '{{calendar}}';
		if (str_contains($content,$original_string)) {
			$calendar = new Calendar();

			// Der Ersatzstring
			$replacement_string = $calendar->show();

			// Ersetze den Originalstring durch den Ersatzstring im Seiteninhalt
			$content = str_replace( $original_string, $replacement_string, $content );
		}
        return $content;
    }

    /**
     * Constructor
     */
    public function __construct()
    {

        $categories =  get_option('bdp_calendar_categories', null);
        if (null !== $categories) {
            $categories = json_decode($categories, true);
        } else {
            $categories = [
                'yellow' => 'Meute',
                'blue'  => 'Sippe',
                'red' => 'Runde',
                'green' => 'StaFü',
                'fuchsia' => '',
                'orange' => ''
            ];
        }

        foreach ($categories as $color => $keyname) {
            $this->categories[$keyname] = $color;
        }


        $calendarUrl = get_option('bdp_calendar_source_url', 'https://wiki.sachsen.pfadfinden.de/rest/calendar-services/1.0/calendar/export/subcalendar/private/ff69f5a689391ac0d7f78a70189cfde7c48cb923.ics');

        $this->ical = new \ICal('', array(
            'defaultSpan' => 2,     // Default value
            'defaultTimeZone' => '',
            'defaultWeekStart' => 'MO',  // Default value
            'disableCharacterReplacement' => false, // Default value
            'filterDaysAfter' => null,  // Default value
            'filterDaysBefore' => null,  // Default value
            'httpUserAgent' => null,  // Default value
            'skipRecurrence' => false, // Default value
        ));
        $this->ical->initUrl($calendarUrl);
        $this->ical->events();
        $this->naviHref = htmlentities($_SERVER['PHP_SELF']);
    }

    /********************* PROPERTY ********************/
    private $dayLabels = array("Mon", "Die", "Mit", "Don", "Fre", "Sam", "Son");

    private $monthLabels = ['', 'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'];

    private $currentYear = 0;

    private $currentMonth = 0;

    private $currentDay = 0;

    private $currentDate = null;

    private $daysInMonth = 0;

    private $naviHref = null;

    /********************* PUBLIC **********************/

    /**
     * print out the calendar
     */
    public function show()
    {
        $year = null;

        $month = null;

        if (null == $year && isset($_GET['year'])) {

            $year = $_GET['year'];

        } else if (null == $year) {

            $year = date("Y", time());

        }

        if (null == $month && isset($_GET['month'])) {

            $month = $_GET['month'];

        } else if (null == $month) {

            $month = date("m", time());

        }

        $this->currentYear = $year;

        $this->currentMonth = $month;

        $this->daysInMonth = $this->_daysInMonth($month, $year);

        $content = '    <div id="calendarContainer"><div id="calendar">' .
            '<div class="box">' .
            $this->_createNavi() .
            '</div>' .
            '<div class="box-content">' .

            '<table style=" border-collapse: collapse; border-spacing: 0;   table-layout: fixed;width: 100%;">
                <tr>' . $this->_createLabels() . '</tr>';


        $weeksInMonth = $this->_weeksInMonth($month, $year);
        // Create weeks in a month
        for ($i = 0; $i < $weeksInMonth; $i++) {

            //Create days in a week
            for ($j = 1; $j <= 7; $j++) {
                if ($j % 7 == 1) {
                    $content .= '</tr><tr class="bdp_cal_day">';
                }
                $content .= $this->_showDay($i * 7 + $j);
            }
        }

        $content .= '</table></div>';

        return $content;
    }

    private function getCssClass($category)
    {
        $cssClass = 'bdp_cal_event_' . ($this->categories[$category] ?? 'grey');
        return $cssClass;
    }


    private function getEvent($date)
    {
        $eventString = '<ul>';
        #echo '<pre>';
        foreach ($this->ical->filterByDate($date) as $curEvent) {
            $time = $curEvent->getEventTime() ?? 'Ganztags';

            #print_r($curEvent);
            $eventString .= '<li class="' . $this->getCssClass($curEvent->category) . '">' .
                $time . ':<br />' .
                $curEvent->summary . '</li>';
        }
        return $eventString;
    }

    /********************* PRIVATE **********************/
    /**
     * create the li element for ul
     */
    private function _showDay($cellNumber)
    {

        if ($this->currentDay == 0) {

            $firstDayOfTheWeek = date('N', strtotime($this->currentYear . '-' . $this->currentMonth . '-01'));

            if (intval($cellNumber) == intval($firstDayOfTheWeek)) {

                $this->currentDay = 1;

            }
        }

        if (($this->currentDay != 0) && ($this->currentDay <= $this->daysInMonth)) {
            $date =
                str_pad($this->currentDay, 2, '0', STR_PAD_LEFT) . '.' .
                str_pad($this->currentMonth, 2, '0', STR_PAD_LEFT) . '.' .
                $this->currentYear;

            $this->currentDate = date('Y-m-d', strtotime($this->currentYear . '-' . $this->currentMonth . '-' . ($this->currentDay)));

            $cellContent = '<span class="bdp_cal_day">' . $this->currentDay . '</span>' . $this->getEvent($date);

            $this->currentDay++;

        } else {

            $this->currentDate = null;

            $cellContent = null;
        }


        return '<td style="padding-top: 5px; border-color: #a0a0a0; height: 120px; border-style: solid; border-width:1px; vertical-align: top;">' . $cellContent . '</td>';
    }

    /**
     * create navigation
     */
    private function _createNavi()
    {

        $nextMonth = $this->currentMonth == 12 ? 1 : intval($this->currentMonth) + 1;

        $nextYear = $this->currentMonth == 12 ? intval($this->currentYear) + 1 : $this->currentYear;

        $preMonth = $this->currentMonth == 1 ? 12 : intval($this->currentMonth) - 1;

        $preYear = $this->currentMonth == 1 ? intval($this->currentYear) - 1 : $this->currentYear;

        return
            '<div class="header">' .
            '<a class="prev" href="javascript:void(0);" onclick="loadCalendar(' . $preMonth . ',' . $preYear . ');"><< Vorheriger Monat</a>' .
            '<span class="title">' . $this->monthLabels[(int)date('m', strtotime($this->currentYear . '-' . $this->currentMonth . '-1'))] . ' ' . date('Y', strtotime($this->currentYear . '-' . $this->currentMonth . '-1')) . '</span>' .
            '<a class="next" href="javascript:void(0);" onclick="loadCalendar(' . $nextMonth . ',' . $nextYear . ');">Nächster Monat >></a>' .
            '</div>';
    }

    /**
     * create calendar week labels
     */
    private function _createLabels()
    {

        $content = '';

        foreach ($this->dayLabels as $index => $label) {

            $content .= '<td style="max-width: 14.287%;">' . $label . '</td>';

        }

        return $content;
    }


    /**
     * calculate number of weeks in a particular month
     */
    private function _weeksInMonth($month = null, $year = null)
    {

        if (null == ($year)) {
            $year = date("Y", time());
        }

        if (null == ($month)) {
            $month = date("m", time());
        }

        // find number of days in this month
        $daysInMonths = $this->_daysInMonth($month, $year);

        $numOfweeks = ($daysInMonths % 7 == 0 ? 0 : 1) + intval($daysInMonths / 7);

        $monthEndingDay = date('N', strtotime($year . '-' . $month . '-' . $daysInMonths));

        $monthStartDay = date('N', strtotime($year . '-' . $month . '-01'));

        if ($monthEndingDay < $monthStartDay) {

            $numOfweeks++;

        }

        return $numOfweeks;
    }

    /**
     * calculate number of days in a particular month
     */
    private function _daysInMonth($month = null, $year = null)
    {

        if (null == ($year))
            $year = date("Y", time());

        if (null == ($month))
            $month = date("m", time());

        return date('t', strtotime($year . '-' . $month . '-01'));
    }

}
