<?php
defined('_WPBOOKINGPRO_EXEC') or die;
if(!class_exists("WpBookingPro_PackageModel")) {
    /**
     * Class WpBookingPro_PackageModel
     */
    class WpBookingPro_PackageModel extends WoobookingModelForm
    {
        /**
         * @var string
         */
        public $table_name = "package";
        /**
         * @var string
         */
        public $context = "package";

        /**
         * @param array $data
         * @return array|bool|object
         */
        public function save($data = array())
        {
            $is_new = !$data['id'];
            if ($package = parent::save($data)) {
                if ($is_new) {
                    if ($post_id = wp_insert_post(array(
                        'post_title' => $package->name,
                        'post_type' => 'product',
                        'post_status' => 'publish',
                        'post_content' => 'package',
                        'post_excerpt' => 'package'
                    ))) {
                        wp_set_object_terms($post_id, 'Races', 'product_cat');
                        wp_set_object_terms($post_id, 'simple', 'product_type');
                        update_post_meta($post_id, '_visibility', 'visible');
                        update_post_meta($post_id, '_stock_status', 'instock');
                        update_post_meta($post_id, 'total_sales', '0');
                        update_post_meta($post_id, '_downloadable', 'yes');
                        update_post_meta($post_id, '_virtual', 'yes');
                        update_post_meta($post_id, '_regular_price', "1");
                        update_post_meta($post_id, '_sale_price', "1");
                        update_post_meta($post_id, '_purchase_note', "");
                        update_post_meta($post_id, '_featured', "no");
                        update_post_meta($post_id, '_weight', "");
                        update_post_meta($post_id, '_length', "");
                        update_post_meta($post_id, '_width', "");
                        update_post_meta($post_id, '_height', "");
                        update_post_meta($post_id, '_sku', "package_" . $package->id);
                        update_post_meta($post_id, '_product_attributes', array());
                        update_post_meta($post_id, '_sale_price_dates_from', "");
                        update_post_meta($post_id, '_sale_price_dates_to', "");
                        update_post_meta($post_id, '_price', $package->price);
                        update_post_meta($post_id, '_sold_individually', "");
                        update_post_meta($post_id, '_manage_stock', "no");
                        update_post_meta($post_id, '_backorders', "no");
                        update_post_meta($post_id, '_stock', "10000");
                        $package->open_source_link_id = $post_id;
                        $package = parent::save((array)$package);
                    } else {
                        $this->delete($package->id);
                        return false;
                    }
                } elseif ($package->open_source_link_id && $product = wc_get_product($package->open_source_link_id)) {
                    $product->set_name($package->name);
                    update_post_meta($package->open_source_link_id, '_price', $package->price);
                }
            }
            return $package;
        }

        /**
         * @param int $id
         * @return mixed
         */
        public function getItem($id = 0)
        {
            $item = parent::getItem($id); // TODO: Change the autogenerated stub
            if ($item) {
                $db = Factory::getDBO();
                $query = $db->getQuery(true)
                    ->select("tag.name")
                    ->from(WoobookingTable::getWBTable('package_tag') . ' AS package_tag')
                    ->leftJoin(WoobookingTable::getWBTable('tag') . ' AS tag ON tag.id=package_tag.tag_id')
                    ->where('package_tag.package_id=' . (int)$item->id);
                $item->tags = $db->setQuery($query)->loadColumn();
                $query->clear()
                    ->select("rate.*")
                    ->from(WoobookingTable::getWBTable('rate') . ' AS rate')
                    ->where('rate.object_id=' . (int)$item->id)
                    ->where('rate.type=' . $query->quote(WpBookingPro_RateHelperAdmin::getNamePackage()));
                $item->rates = $db->setQuery($query)->loadObjectList();
                $query->clear()
                    ->select("gallery.*")
                    ->from(WoobookingTable::getWBTable('gallery') . ' AS gallery')
                    ->where('gallery.object_id=' . (int)$item->id)
                    ->where('gallery.type=' . $query->quote('package'));
                $item->gallery = $db->setQuery($query)->loadObjectList();
                $query->clear()
                    ->select('package_event.event_id')
                    ->from(WoobookingTable::getWBTable('package_event') . ' AS package_event')
                    ->where('package_id=' . (int)$item->id);
                $item->list_event_id = $db->setQuery($query)->loadColumn();
            }
            return $item;
        }

        /**
         * @param $package_id
         * @param $booking_date
         * @return array
         * @throws Exception
         */
        public function get_rang_time_avail($package_id, $booking_date)
        {
            $booking_date = Factory::getDate($booking_date);
            $model_package = $this->getModel('package');
            $db = Factory::getDBO();
            $query = $db->getQuery(true);
            $package = $model_package->getItem($package_id);
            $product = wc_get_product($package->woo_product_id);
            if ($product->status != "publish") {
                return array();
            }
            $rates = $package->rates;
            $rates = explode(';', $rates);
            if ($package->close == 1) {
                $close_date = Factory::getDate($package->close_date);
                if ($booking_date > $close_date) {
                    return [];
                }
            }
            $list_rate = [];
            foreach ($rates as $rate) {
                list($start, $end) = explode(',', $rate);
                $start = Factory::getDate($start);
                $end = Factory::getDate($end);
                //check in range
                $in_range = ($booking_date >= $start) && ($booking_date <= $end);
                //check recurring
                $list_recurring = [];
                if ($package->recurring == 1) {
                    $recurring_repeat = $package->recurring_repeat;
                    $recurring_until = Factory::getDate($package->recurring_until);
                    $list_recurring = self::get_date_recurring($start, $recurring_until, $recurring_repeat);
                }
                if ($in_range && count($list_recurring) && self::check_date_in_range_date($booking_date, $list_recurring)) {
                    $item_rate = [$start->format('h:i'), $end->format('h:i')];
                    $list_rate[] = $item_rate;
                } elseif ($in_range) {
                    $item_rate = [$start->format('h:i'), $end->format('h:i')];
                    $list_rate[] = $item_rate;
                }
            }
            return $list_rate;
        }

        /**
         * @param $date
         * @param $dates
         * @return bool
         */
        protected function check_date_in_range_date($date, $dates)
        {
            $date_strtotime = strtotime($date);
            foreach ($dates AS $date) {
                $timestamp = strtotime($date);
                if ($timestamp == $date_strtotime) {
                    return true;
                }
            }
            return false;
        }

        /**
         * @param $package_date
         * @param $package_end_date
         * @param $package_repetition_type
         * @return array
         */
        protected function get_date_recurring($package_date, $package_end_date, $package_repetition_type)
        {
            $date_calculation = "";
            $package_repetition_type = strtolower($package_repetition_type);
            switch ($package_repetition_type) {
                case "daily":
                    $date_calculation = " +1 day";
                    break;
                case "weekly":
                    $date_calculation = " +1 week";
                    break;
                case "monthly":
                    $date_calculation = " +1 month";
                    break;
                default:
                    $date_calculation = "none";
            }
            $dateArray[] = $package_date->format('Y-m-d');
            $day = $package_date;
            $to = $package_end_date;
            while ($day <= $to) {
                $day = $day->modify($date_calculation);
                $dateArray[] = $day->format('Y-m-d');
            }
            //here make above array as key in $a array
            return $dateArray;
        }

        /**
         * @return array
         */
        public function getHeader()
        {
            return array();
        }
    }
}