<?php

namespace PWH_DCFH\App\Admin\Controllers;

use DateTime;
use DateTimeZone;
use Exception;

if (!defined('ABSPATH')) exit;
if (!class_exists('PWH_DCFH_Admin_Notice')) {
    class PWH_DCFH_Syn_ICS_URL
    {
        public $url;

        public $domain;

        /**
         * Class Constructor
         */
        public function __construct($url)
        {
            $this->url = $url;

        }

        private function get_domain()
        {
            $url = $this->url;

            return wp_parse_url($url, PHP_URL_HOST);

        }

        /**
         * Get Data
         * @throws Exception
         * @return array
         */
        public function data()
        {
            $domain = $this->get_domain();
            $events = $this->parse();
            $data = [];
            if ('calendar.google.com' === strtolower($domain)) {
                $timezone = isset($events[1]['X-WR-TIMEZONE']) ? trim($events[1]['X-WR-TIMEZONE']) : null;
                unset($events[1]);
                foreach ($events as $event) {
                    if (isset($event['DTSTART;VALUE=DATE']) || isset($event['DTSTART'])) {
                        $event_name = isset($event['SUMMARY']) ? $event['SUMMARY'] : '-';
                        // Start Date
                        $dtstart = isset($event['DTSTART;VALUE=DATE']) ? $event['DTSTART;VALUE=DATE'] : $event['DTSTART'];
                        $dt_obj1 = new DateTime ($dtstart);
                        $dt_obj1->setTimeZone(new DateTimezone ($timezone));
                        $start_datetime = $dt_obj1->format('Y-m-d h:ia');
                        $start_date = $dt_obj1->format('Y-m-d');
                        $start_time = $dt_obj1->format('h:ia');
                        $dayname = strtolower($dt_obj1->format('l'));
                        // End Date
                        $dtend = isset($event['DTEND;VALUE=DATE']) ? $event['DTEND;VALUE=DATE'] : $event['DTEND'];
                        $dt_obj2 = new DateTime ($dtend);
                        $dt_obj2->setTimeZone(new DateTimezone ($timezone));
                        $end_datetime = $dt_obj2->format('Y-m-d h:ia');
                        $end_date = $dt_obj2->format('Y-m-d');
                        $end_time = $dt_obj2->format('h:ia');
                        // Data
                        $data['events'][] = [
                            'event_name' => $event_name,
                            'start_datetime' => $start_datetime,
                            'end_datetime' => $end_datetime,
                            'start_date' => $start_date,
                            'end_date' => $end_date,
                            'start_time' => $start_time,
                            'end_time' => $end_time,
                        ];
                        $data['dates_str'] = isset($data['dates_str']) ? $data['dates_str'].$start_date.','.$end_date.',' : $start_date.','.$end_date.',';
                        if (!empty($data['dates_str'])) {
                            $data['dates_str'] = implode(',', array_unique(explode(",", $data['dates_str'])));
                        }
                        $data['times_str'] = isset($data['times_str']) ? $data['times_str'].$start_time.','.$end_time.',' : $start_time.','.$end_time.',';
                        if (!empty($data['times_str'])) {
                            $data['times_str'] = implode(',', array_unique(explode(",", $data['times_str'])));
                        }
                        $data['unavailable_times_'.$dayname] = isset($data['unavailable_times_'.$dayname]) ? $data['unavailable_times_'.$dayname].$end_time.',' : $end_time.',';
                    }

                }
            }
            if ('outlook.live.com' === strtolower($domain)) {
                $timezone = array_map(function ($events) {
                    return isset($events['TZID']) ? $events['TZID'] : '';
                }, $events);
                if (!empty($timezone)) {
                    $timezone = array_values((array)array_filter($timezone, 'strlen'));
                    if (isset($timezone[0])) {
                        $timezone = trim($timezone[0]);
                    }
                }
                if (!empty($timezone) && is_string($timezone)) {
                    foreach ($events as $event) {
                        if (isset($event["DTSTART;TZID=".$timezone]) && isset($event["DTEND;TZID=".$timezone])) {
                            $event_name = isset($event['SUMMARY']) ? $event['SUMMARY'] : '-';
                            // Start Date
                            $dtstart = $event["DTSTART;TZID=$timezone"];
                            $dt_obj1 = new DateTime ($dtstart);
                            $dayname = strtolower($dt_obj1->format('l'));
                            $start_datetime = $dt_obj1->format('Y-m-d h:ia');
                            $start_date = $dt_obj1->format('Y-m-d');
                            $start_time = $dt_obj1->format('h:ia');
                            // End Date
                            $dtend = $event["DTEND;TZID=$timezone"];
                            $dt_obj2 = new DateTime ($dtend);
                            $end_datetime = $dt_obj2->format('Y-m-d h:ia');
                            $end_date = $dt_obj2->format('Y-m-d');
                            $end_time = $dt_obj2->format('h:ia');
                            // DATA
                            $data['events'][] = [
                                'event_name' => $event_name,
                                'dayname' => $dayname,
                                'start_datetime' => $start_datetime,
                                'end_datetime' => $end_datetime,
                                'start_date' => $start_date,
                                'end_date' => $end_date,
                                'start_time' => $start_time,
                                'end_time' => $end_time,
                            ];
                            $data['dates_str'] = isset($data['dates_str']) ? $data['dates_str'].$start_date.','.$end_date.',' : $start_date.','.$end_date.',';
                            if (!empty($data['dates_str'])) {
                                $data['dates_str'] = implode(',', array_unique(explode(",", $data['dates_str'])));
                            }
                            $data['times_str'] = isset($data['times_str']) ? $data['times_str'].$start_time.','.$end_time.',' : $start_time.','.$end_time.',';
                            if (!empty($data['times_str'])) {
                                $data['times_str'] = implode(',', array_unique(explode(",", $data['times_str'])));
                            }
                            $data['unavailable_times_'.$dayname] = isset($data['unavailable_times_'.$dayname]) ? $data['unavailable_times_'.$dayname].$end_time.',' : $end_time.',';

                        }
                    }
                }

            }

            return $data;
        }

        /**
         * Parse ICS URL
         * @return array
         */
        private function parse()
        {
            $ics_dates = [];
            $response = wp_remote_get($this->url, ['timeout' => 15, 'sslverify' => false]);
            if (!is_wp_error($response) || 200 === wp_remote_retrieve_response_code($response)) {
                $response = wp_remote_retrieve_body($response);
                /* Explode the ICs Data to get datas as array according to string ‘BEGIN:’ */
                $data = explode("BEGIN:", $response);
                /* Iterating the icsData value to make all the start end dates as sub array */
                foreach ($data as $key => $value) {
                    $metas[$key] = explode("\n", $value);
                }
                /* Itearting the Ics Meta Value */
                if (!empty($metas)) {
                    foreach ($metas as $key => $value) {
                        foreach ($value as $sub_key => $sub_value) {
                            /* to get ics events in proper order */
                            $ics_dates = $this->get_dates($key, $sub_key, $sub_value, $ics_dates);
                        }

                    }
                }
            }

            return $ics_dates;
        }

        /**
         * Get ICS Dates
         *
         * @param $key
         * @param $sub_key
         * @param $sub_value
         * @param $ics_dates
         *
         * @return array
         */
        private function get_dates($key, $sub_key, $sub_value, $ics_dates)
        {
            if ($key !== 0 && $sub_key === 0) {
                $ics_dates[$key]["BEGIN"] = $sub_value;
            } else {
                $sub_value_arr = explode(":", $sub_value, 2);
                if (isset($sub_value_arr[1])) {
                    $ics_dates[$key][$sub_value_arr[0]] = $sub_value_arr[1];
                }
            }

            return $ics_dates;
        }
    }
}
