<?php

if (!defined('ABSPATH')) {
    exit;
}


if (!class_exists('WooPricelyUtil')) {

    class WooPricelyUtil {

        private static $order_cache = array();

        public static function get_chosen_shipping_method_cost() {
            if (count(WC()->session->chosen_shipping_methods) == 0) {
                return 0;
            }
            $chosen_shipping = WC()->session->chosen_shipping_methods[0];
            if ($chosen_shipping == '') {
                return 0;
            }
            WC()->cart->calculate_shipping();
            foreach (WC()->shipping->get_packages() as $package) {
                foreach ($package['rates'] as $key => $rate) {
                    if ($rate->get_id() == $chosen_shipping) {

                        return $rate->get_cost();
                    }
                }
            }
            return 0;
        }

        public static function get_chosen_shipping_method() {
            if (count(WC()->session->chosen_shipping_methods) == 0) {
                return '';
            }
            $chosen_shipping = WC()->session->chosen_shipping_methods[0];
            if ($chosen_shipping == '') {
                return '';
            }
            WC()->cart->calculate_shipping();
            foreach (WC()->shipping->get_packages() as $package) {
                foreach ($package['rates'] as $key => $rate) {

                    if ($rate->get_id() == $chosen_shipping) {
                        return $rate->get_method_id();
                    }
                }
            }
            return '';
        }

        public static function get_chosen_shipping_rate() {
            if (count(WC()->session->chosen_shipping_methods) == 0) {
                return 0;
            }
            $chosen_shipping = WC()->session->chosen_shipping_methods[0];
            if ($chosen_shipping == '') {
                return 0;
            }
            WC()->cart->calculate_shipping();
            foreach (WC()->shipping->get_packages() as $package) {
                foreach ($package['rates'] as $key => $rate) {

                    if ($rate->get_id() == $chosen_shipping) {
                        return $rate->get_instance_id();
                    }
                }
            }
            return 0;
        }

        public static function get_chosen_shipping_zone() {
            if (count(WC()->session->chosen_shipping_methods) == 0) {
                return 0;
            }
            $chosen_shipping = WC()->session->chosen_shipping_methods[0];
            if ($chosen_shipping == '') {
                return 0;
            }


            foreach (WC()->shipping->get_packages() as $package) {
                foreach ($package['rates'] as $key => $rate) {
                    if ($rate->get_id() == $chosen_shipping) {
                        $zone_id = self::get_shipping_zone_by_shipping_method($rate->get_instance_id());

                        return $zone_id;
                    }
                }
            }
            return 0;
        }

        public static function get_applied_coupons_ids() {
            $coupon_ids = array();

            foreach (WC()->cart->get_applied_coupons() as $coupon_code) {
                $coupon_id = wc_get_coupon_id_by_code($coupon_code);
                if ($coupon_id > 0) {
                    $coupon_ids[] = $coupon_id;
                }
            }
            return $coupon_ids;
        }

        public static function get_customer_amount_spent($amount_type, $customer_id, $from_date = '', $paid_orders = true) {

            global $wpdb;

            try {

                $sql = self::get_order_db_query('SELECT posts.id', $customer_id, $from_date, $paid_orders);
                $order_ids = array();

                foreach ($wpdb->get_results($sql, ARRAY_A) as $order_record) {
                    $order_ids[] = $order_record['id'];
                }

                if ($amount_type == 'LAST' && count($order_ids) > 1) {
                    $order_ids = array();
                    $last_id = $order_ids[count($order_ids) - 1];
                    $order_ids[] = $last_id;
                }

                $amounts = array();
                foreach ($wpdb->get_results("SELECT meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_order_total' AND post_id IN ('" . implode("','", array_map('esc_sql', $order_ids)) . "')", ARRAY_A) as $order_amount) {
                    $amounts[] = $order_amount['meta_value'];
                }
                return self::get_value_by_amount_type($amount_type, $amounts);
            } catch (Exception $ex) {
                return 0;
            }
        }

        public static function get_customer_orders_count($customer_id, $from_date = '', $paid_orders = true) {

            global $wpdb;
            try {

                $sql = self::get_order_db_query('SELECT COUNT(posts.id)', $customer_id, $from_date, $paid_orders);
                return $wpdb->get_var($sql);
            } catch (Exception $ex) {
                return 0;
            }
        }

        public static function get_customer_reviews_count($customer_id, $from_date = '') {

            global $wpdb;
            try {
                $db_date = "";
                if ($from_date != '') {
                    $db_date = " AND (comment_date>='" . esc_sql($from_date) . "')";
                }
                $sql = "SELECT COUNT(comment_ID) FROM {$wpdb->prefix}comments WHERE (user_id = " . $customer_id . ")" . $db_date . " AND (comment_approved=1)";

                return $wpdb->get_var($sql);
            } catch (Exception $ex) {
                return 0;
            }
        }

        public static function get_customer_coupon_used($customer_id, $from_date = '', $paid_orders = true) {

            global $wpdb;
            $sql = self::get_order_db_query('SELECT posts.id', $customer_id, $from_date, $paid_orders);

            $order_ids = array();
            foreach ($wpdb->get_results($sql, ARRAY_A) as $order_record) {
                $order_ids[] = $order_record['id'];
            }
            $used_coupons = array();

            foreach ($order_ids as $order_id) {
                $wc_order = wc_get_order($order_id);

                if (method_exists($wc_order, 'get_used_coupons')) {

                    foreach ($wc_order->get_used_coupons() as $coupon) {
                        $used_coupons[$coupon] = $coupon;
                    }
                }
            }
            $coupon_codes = array();
            if (count($used_coupons) > 0) {
                $coupon_codes = array_keys($used_coupons);
            }

            $coupon_ids = array();

            foreach ($coupon_codes as $coupon_code) {
                $coupon_id = wc_get_coupon_id_by_code($coupon_code);
                if ($coupon_id > 0) {
                    $coupon_ids[] = $coupon_id;
                }
            }


            return $coupon_ids;
        }

        public static function get_date_from_rule_value($rule_value) {

            $result = '';
            if ($rule_value['date_type'] == 'current') {
                $current_type = 'day';
                if ($rule_value['current'] != '') {
                    $current_type = $rule_value['current'];
                }
                $result = self::get_date_from_current($current_type);
            } else if ($rule_value['date_type'] == 'hours' || $rule_value['date_type'] == 'days' || $rule_value['date_type'] == 'weeks' || $rule_value['date_type'] == 'months' || $rule_value['date_type'] == 'years') {
                $result = self::get_date_from_offset($rule_value['date_type'], $rule_value['date_offset']);
            }
            return $result;
        }

        public static function get_current_date($include_time = true) {
            if ($include_time == true) {
                return date("Y-m-d H:i:s", current_time('timestamp'));
            }
            return date("Y-m-d", current_time('timestamp'));
        }

        public static function get_date_from_week_days($compare, $week_days) {



            $current_week = date('W', current_time('timestamp'));
            $current_year = date("Y", current_time('timestamp'));
            $c_date = new DateTime();
            $c_date->setISODate($current_year, $current_week);
            $c_date->setTime(0, 0, 0);
            $date_from_monday = $c_date->format('U');


            $selected_day_range = self::get_selected_week_days($compare, $week_days);

            if (count($selected_day_range) > 0) {
                return array(
                    'from' => date('Y-m-d', ($date_from_monday + (DAY_IN_SECONDS * $selected_day_range[0]))) . ' 00:00:00',
                    'to' => date('Y-m-d', ($date_from_monday + (DAY_IN_SECONDS * $selected_day_range[1]))) . ' 23:59:59',
                );
            } else {
                return '';
            }
        }

        public static function get_date_from_month_days($compare, $month_days) {

            $selected_day_range = self::get_selected_month_days($compare, $month_days);

            if (count($selected_day_range) > 0) {
                $current_month = date('m', current_time('timestamp'));
                $current_year = date("Y", current_time('timestamp'));
                $c_date = new DateTime();


                $date_range = array();

                $c_date->setDate($current_year, $current_month, $selected_day_range[0]);
                $c_date->setTime(0, 0, 0);
                $date_u = $c_date->format('U');
                $date_range['from'] = date('Y-m-d', $date_u) . ' 00:00:00';

                $c_date->setDate($current_year, $current_month, $selected_day_range[1]);
                $c_date->setTime(0, 0, 0);
                $date_u = $c_date->format('U');
                $date_range['to'] = date('Y-m-d', $date_u) . ' 23:59:59';
                return $date_range;
            } else {
                return '';
            }
        }

        public static function get_date_from_year_months($compare, $months) {
            $selected_month_range = self::get_selected_months($compare, $months);

            if (count($selected_month_range) > 0) {


                $current_year = date("Y", current_time('timestamp'));
                $c_date = new DateTime();


                $date_range = array();

                $c_date->setDate($current_year, $selected_month_range[0]['month'], $selected_month_range[0]['day']);
                $c_date->setTime(0, 0, 0);
                $date_u = $c_date->format('U');
                $date_range['from'] = date('Y-m-d', $date_u) . ' 00:00:00';

                $c_date->setDate($current_year, $selected_month_range[1]['month'], $selected_month_range[1]['day']);
                $c_date->setTime(0, 0, 0);
                $date_u = $c_date->format('U');
                $date_range['to'] = date('Y-m-d', $date_u) . ' 23:59:59';
                return $date_range;
            } else {
                return '';
            }
        }

        public static function get_purchase_history($customer_id, $data_type, $from_date = '', $paid_orders = true, $get_cache = true) {
            $order_products = self::get_purchase_history_data($customer_id, $from_date, $paid_orders, $get_cache);

            if ($data_type == 'product_ids') {
                $product_ids = array();
                foreach ($order_products as $order_product) {
                    foreach ($order_product as $product) {
                        $product_ids[$product['id']] = $product['id'];
                    }
                }
                return array_values($product_ids);
            }

            if ($data_type == 'variation_ids') {
                $variation_ids = array();
                foreach ($order_products as $order_product) {
                    foreach ($order_product as $product) {
                        if (isset($product['variation_id'])) {
                            $variation_ids[$product['variation_id']] = $product['variation_id'];
                        }
                    }
                }
                return array_values($variation_ids);
            }

            if ($data_type == 'category_ids') {
                $category_ids = array();
                foreach ($order_products as $order_product) {
                    foreach ($order_product as $product) {
                        foreach ($product['categories'] as $category_id) {
                            $category_ids[$category_id] = $category_id;
                        }
                    }
                }
                return array_values($category_ids);
            }

            if ($data_type == 'tag_ids') {
                $tag_ids = array();
                foreach ($order_products as $order_product) {
                    foreach ($order_product as $product) {
                        foreach ($product['tags'] as $tag_id) {
                            $tag_ids[$tag_id] = $tag_id;
                        }
                    }
                }
                return array_values($tag_ids);
            }

            if ($data_type == 'attribute_ids') {
                $attribute_ids = array();
                foreach ($order_products as $order_product) {
                    foreach ($order_product as $product) {
                        $db_attrs = wc_get_product($product['id'])->get_attributes();
                        foreach ($db_attrs as $db_attr) {
                            foreach ($db_attr->get_options() as $attr_option) {
                                if (is_numeric($attr_option)) {
                                    $attribute_ids[$attr_option] = $attr_option;
                                }
                            }
                        }
                    }
                }

                return array_values($attribute_ids);
            }

            return array();
        }

        public static function get_purchase_history_quantity($customer_id, $data_type, $data_ids, $from_date = '', $paid_orders = true, $get_cache = true) {
            $order_products = self::get_purchase_history_data($customer_id, $from_date, $paid_orders, $get_cache);

            $qty = 0;
            if ($data_type == 'product_ids') {
                foreach ($order_products as $order_product) {
                    $product_ids = array();
                    foreach ($order_product as $product) {
                        if (WooPricely_Validation_Util::validate_value_list($product['id'], $data_ids, 'in_list') == true) {
                            $qty += $product['quantity'];
                        }
                    }
                }
            }

            if ($data_type == 'variation_ids') {
                foreach ($order_products as $order_product) {
                    $product_ids = array();
                    foreach ($order_product as $product) {
                        if (isset($product['variation_id']) == true) {
                            if (WooPricely_Validation_Util::validate_value_list($product['variation_id'], $data_ids, 'in_list') == true) {
                                $qty += $product['quantity'];
                            }
                        }
                    }
                }
            }

            if ($data_type == 'category_ids') {
                foreach ($order_products as $order_product) {
                    foreach ($order_product as $product) {
                        if (WooPricely_Validation_Util::validate_list_list($product['categories'], $data_ids, 'in_list') == true) {
                            $qty += $product['quantity'];
                        }
                    }
                }
            }

            if ($data_type == 'tag_ids') {
                foreach ($order_products as $order_product) {
                    foreach ($order_product as $product) {
                        if (WooPricely_Validation_Util::validate_list_list($product['tags'], $data_ids, 'in_list') == true) {
                            $qty += $product['quantity'];
                        }
                    }
                }
            }


            if ($data_type == 'attribute_ids') {
                foreach ($order_products as $order_product) {
                    foreach ($order_product as $product) {
                        $attribute_ids = array();
                        $db_attrs = wc_get_product($product['id'])->get_attributes();
                        foreach ($db_attrs as $db_attr) {
                            foreach ($db_attr->get_options() as $attr_option) {
                                if (is_numeric($attr_option)) {
                                    $attribute_ids[] = $attr_option;
                                }
                            }
                        }
                        if (WooPricely_Validation_Util::validate_list_list($attribute_ids, $data_ids, 'in_list') == true) {
                            $qty += $product['quantity'];
                        }
                    }
                }
            }

            return $qty;
        }

        public static function get_purchase_history_subtotal($customer_id, $data_type, $data_ids, $from_date = '', $paid_orders = true, $get_cache = true) {
            $order_products = self::get_purchase_history_data($customer_id, $from_date, $paid_orders, $get_cache);

            $subtotal = 0;
            if ($data_type == 'product_ids') {
                foreach ($order_products as $order_product) {
                    $product_ids = array();
                    foreach ($order_product as $product) {
                        if (WooPricely_Validation_Util::validate_value_list($product['id'], $data_ids, 'in_list') == true) {
                            $subtotal += $product['subtotal'];
                        }
                    }
                }
            }

            if ($data_type == 'variation_ids') {
                foreach ($order_products as $order_product) {
                    $product_ids = array();
                    foreach ($order_product as $product) {
                        if (isset($product['variation_id']) == true) {
                            if (WooPricely_Validation_Util::validate_value_list($product['variation_id'], $data_ids, 'in_list') == true) {
                                $subtotal += $product['subtotal'];
                            }
                        }
                    }
                }
            }

            if ($data_type == 'category_ids') {
                foreach ($order_products as $order_product) {
                    foreach ($order_product as $product) {
                        if (WooPricely_Validation_Util::validate_list_list($product['categories'], $data_ids, 'in_list') == true) {
                            $subtotal += $product['subtotal'];
                        }
                    }
                }
            }

            if ($data_type == 'tag_ids') {
                foreach ($order_products as $order_product) {
                    foreach ($order_product as $product) {
                        if (WooPricely_Validation_Util::validate_list_list($product['tags'], $data_ids, 'in_list') == true) {
                            $subtotal += $product['subtotal'];
                        }
                    }
                }
            }

            if ($data_type == 'attribute_ids') {
                foreach ($order_products as $order_product) {
                    foreach ($order_product as $product) {
                        $attribute_ids = array();
                        $db_attrs = wc_get_product($product['id'])->get_attributes();
                        foreach ($db_attrs as $db_attr) {
                            foreach ($db_attr->get_options() as $attr_option) {
                                if (is_numeric($attr_option)) {
                                    $attribute_ids[] = $attr_option;
                                }
                            }
                        }
                        if (WooPricely_Validation_Util::validate_list_list($attribute_ids, $data_ids, 'in_list') == true) {
                            $subtotal += $product['subtotal'];
                        }
                    }
                }
            }

            return $subtotal;
        }

        private static function get_purchase_history_data($customer_id, $from_date = '', $paid_orders = true, $get_cache = true) {

            $cache_id = $customer_id . '_' . $from_date . '_' . $paid_orders;

            if ($get_cache == true && isset(self::$order_cache[$cache_id])) {
                return self::$order_cache[$cache_id];
            }
            try {

                $orders_args = array(
                    'customer_id' => $customer_id,
                );

                if ($from_date != '') {
                    if ($paid_orders == true) {
                        $orders_args['date_paid'] = '>=' . $from_date;
                    } else {
                        $orders_args['date_created'] = '>=' . $from_date;
                    }
                }


                $order_products = array();

                $paid_statuses = wc_get_is_paid_statuses();

                foreach (wc_get_orders($orders_args) as $order) {
                    $order_id = $order->get_id();

                    if ($paid_orders == true) {
                        $order_is_paid = false;
                        $order_status = $order->get_status(false);

                        foreach ($paid_statuses as $status) {
                            if ($status == $order_status) {
                                $order_is_paid = true;
                            }
                        }
                        if ($order_is_paid != true) {
                            continue;
                        }
                    }


                    foreach ($order->get_items('line_item') as $order_item) {
                        $variation_id = $order_item->get_variation_id();

                        $product = array();
                        $product['id'] = $order_item->get_product_id();
                        if ($variation_id > 0) {
                            $product['variation_id'] = $variation_id;
                            $product['key'] = WooPricely::get_product_identifier_key($product['id'], $variation_id);
                        } else {
                            $product['key'] = WooPricely::get_product_identifier_key($product['id']);
                        }
                        $product['quantity'] = $order_item->get_quantity();
                        $product['subtotal'] = $order_item->get_subtotal();

                        $prod = wc_get_product($product['id']);

                        if ($prod) {
                            $product['categories'] = wp_get_post_terms($product['id'], 'product_cat', array('fields' => 'ids'));
                            $product['tags'] = wp_get_post_terms($product['id'], 'product_tag', array('fields' => 'ids'));
//                            $product['categories'] = $prod->get_category_ids();
//                            $product['tags'] = $prod->get_tag_ids();
                        } else {
                            $product['categories'] = array();
                            $product['tags'] = array();
                        }

                        $order_products[$order_id][] = $product;
                    }
                }
                self::$order_cache[$cache_id] = $order_products;
                return $order_products;
            } catch (Exception $ex) {
                return array();
            }
        }

        private static function get_order_db_query($sql, $customer_id, $from_date = '', $paid_only_status = false) {
            global $wpdb;
            $statuses = "'" . implode("','", array_map('esc_sql', array_keys(wc_get_order_statuses()))) . "'";
            if ($paid_only_status == true) {
                $statuses = "'wc-" . implode("','wc-", array_map('esc_sql', wc_get_is_paid_statuses())) . "'";
            }
            $db_date = "";
            if ($from_date != '') {
                $db_date = "AND (post_date>='" . esc_sql($from_date) . "')";
            }
            return $sql . " FROM $wpdb->posts as posts " .
                    "LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id " .
                    "WHERE meta.meta_key = '_customer_user' " .
                    "AND posts.post_type = 'shop_order'	" .
                    "AND meta_value = '" . esc_sql($customer_id) . "' " .
                    $db_date .
                    "AND posts.post_status IN ( " . $statuses . " ) " .
                    "ORDER BY posts.post_date DESC";
        }

        private static function get_shipping_zone_by_shipping_method($instance_id) {
            global $wpdb;
            try {
                $sql = "SELECT zone_id FROM {$wpdb->prefix}woocommerce_shipping_zone_methods "
                        . "WHERE (instance_id=%d) LIMIT 1";
                $sql = $wpdb->prepare($sql, $instance_id);
                return $wpdb->get_var($sql);
            } catch (Exception $ex) {
                return 0;
            }
        }

        private static function get_date_from_current($date_mode = 'day') {

            switch ($date_mode) {
                case 'week':
                    $current_week = date('W', current_time('timestamp'));
                    $current_year = date("Y", current_time('timestamp'));
                    $c_date = new DateTime();
                    $c_date->setISODate($current_year, $current_week);
                    return $c_date->format('Y-m-d') . " 00:00:00";
                case 'month':
                    $current_month = date('m', current_time('timestamp'));
                    $current_year = date("Y", current_time('timestamp'));
                    $c_date = new DateTime();
                    $c_date->setDate($current_year, $current_month, 1);
                    return $c_date->format('Y-m-d') . " 00:00:00";
                case 'year':
                    $current_year = date("Y", current_time('timestamp'));
                    $c_date = new DateTime();
                    $c_date->setDate($current_year, 1, 1);
                    return $c_date->format('Y-m-d') . " 00:00:00";
                default :
                    $current_year = date("Y", current_time('timestamp'));
                    $current_month = date("m", current_time('timestamp'));
                    $current_day = date("d", current_time('timestamp'));
                    $c_date = new DateTime();
                    $c_date->setDate($current_year, $current_month, $current_day);
                    return $c_date->format('Y-m-d') . " 00:00:00";
            }
        }

        private static function get_date_from_offset($offset_mode = 'hours', $offset = 1) {


            $current_time = current_time('timestamp');



            switch ($offset_mode) {
                case 'years':
                    return date("Y-m-d", $current_time - (YEAR_IN_SECONDS * $offset)) . " 00:00:00";
                case 'months':
                    return date("Y-m-d", $current_time - (MONTH_IN_SECONDS * $offset)) . " 00:00:00";
                case 'weeks':
                    return date("Y-m-d", $current_time - (WEEK_IN_SECONDS * $offset)) . " 00:00:00";
                case 'days':
                    return date("Y-m-d", $current_time - (DAY_IN_SECONDS * $offset)) . " 00:00:00";
                default:
                    return date("Y-m-d H:i", $current_time - (HOUR_IN_SECONDS * $offset)) . ":00";
            }
        }

        private static function get_value_by_amount_type($amount_type, $values) {
            $amount = 0;
            switch ($amount_type) {
                case 'AVG':
                    $cnt = 0;
                    $avg_amount = 0;
                    foreach ($values as $value) {
                        $avg_amount += ((float) $value);
                        $cnt++;
                    }

                    if ($avg_amount > 0) {
                        $amount = $avg_amount / $cnt;
                    }
                    break;
                case 'MAX':
                    foreach ($values as $value) {
                        if ($value > $amount) {
                            $amount = ((float) $value);
                        }
                    }
                    break;
                case 'MIN':
                    foreach ($values as $value) {
                        if ($value < $amount || $amount == 0) {
                            $amount = ((float) $value);
                        }
                    }
                    break;
                case 'SUM':
                    foreach ($values as $value) {
                        $amount += ((float) $value);
                    }
                    break;
                case 'LAST':
                    foreach ($values as $value) {
                        $amount += ((float) $value);
                    }
                    break;
            }
            return $amount;
        }

        private static function get_selected_week_days($compare, $week_days) {



            if ($compare != 'in_list') {
                $selected_week_days = array();
                for ($i = 0; $i < 7; $i++) {
                    if (!in_array($i, $week_days)) {
                        $selected_week_days[] = $i;
                    }
                }
            } else {
                $selected_week_days = $week_days;
            }


            $weeks_range = array();

            $range = array();
            for ($i = 0; $i < 7; $i++) {

                if (in_array($i, $selected_week_days) && count($range) == 0) {
                    $range[0] = $i;
                    $range[1] = $i;
                } else if (in_array($i, $selected_week_days) && count($range) > 0) {
                    $range[1] = $i;
                } else if (count($range) > 0) {
                    $weeks_range[] = $range;
                    $range = array();
                }
            }
            if (count($range) > 0) {
                $weeks_range[] = $range;
            }



            $jd = cal_to_jd(CAL_GREGORIAN, date("m", current_time('timestamp')), date("d", current_time('timestamp')), date("Y", current_time('timestamp')));
            $week_day = self::map_week_day(jddayofweek($jd, 0));

            foreach ($weeks_range as $week_day_range) {
                if ($week_day >= $week_day_range[0] && $week_day <= $week_day_range[1]) {

                    return $week_day_range;
                }
            }

            return array();
        }

        private static function get_selected_months($compare, $months) {
            if ($compare != 'in_list') {
                $selected_months = array();
                for ($i = 1; $i <= 12; $i++) {
                    if (!in_array($i, $months)) {
                        $selected_months[] = $i;
                    }
                }
            } else {
                $selected_months = $months;
            }

            $months_range = array();


            $range = array();
            for ($i = 1; $i <= 31; $i++) {

                if (in_array($i, $selected_months) && count($range) == 0) {
                    $range[0] = $i;
                    $range[1] = $i;
                } else if (in_array($i, $selected_months) && count($range) > 0) {
                    $range[1] = $i;
                } else if (count($range) > 0) {
                    $months_range[] = $range;
                    $range = array();
                }
            }
            if (count($range) > 0) {
                $months_range[] = $range;
            }


            $month = date("m", current_time('timestamp'));


            foreach ($months_range as $month_range) {
                if ($month >= $month_range[0] && $month <= $month_range[1]) {

                    $sl_month_range = array();
                    $sl_month_range[0]['month'] = $month_range[0];
                    $sl_month_range[0]['day'] = 1;
                    $sl_month_range[1]['month'] = $month_range[1];
                    $sl_month_range[1]['day'] = self::get_month_max_days($month_range[1]);

                    return $sl_month_range;
                }
            }

            return array();
        }

        private static function get_selected_month_days($compare, $month_days) {
            if ($compare != 'in_list') {
                $selected_month_days = array();
                for ($i = 1; $i <= 31; $i++) {
                    if (!in_array($i, $month_days)) {
                        $selected_month_days[] = $i;
                    }
                }
            } else {
                $selected_month_days = $month_days;
            }

            $days_range = array();

            $range = array();
            for ($i = 1; $i <= 31; $i++) {

                if (in_array($i, $selected_month_days) && count($range) == 0) {
                    $range[0] = $i;
                    $range[1] = $i;
                } else if (in_array($i, $selected_month_days) && count($range) > 0) {
                    $range[1] = $i;
                } else if (count($range) > 0) {
                    $days_range[] = $range;
                    $range = array();
                }
            }
            if (count($range) > 0) {
                $days_range[] = $range;
            }


            $month_day = date("d", current_time('timestamp'));
            $current_month = date("m", current_time('timestamp'));

            foreach ($days_range as $month_day_range) {
                if ($month_day >= $month_day_range[0] && $month_day <= $month_day_range[1]) {
                    $max_day = self::get_month_max_days($current_month);
                    if ($month_day_range[0] > $max_day) {
                        $month_day_range[0] = $max_day;
                    }
                    if ($month_day_range[1] > $max_day) {
                        $month_day_range[1] = $max_day;
                    }
                    return $month_day_range;
                }
            }

            return array();
        }

        private static function get_month_max_days($month) {
            switch ($month) {
                case 2:
                    $is_leap_year = (date('L', current_time('timestamp')) === 1);
                    if ($is_leap_year == true) {
                        return 29;
                    }
                    return 28;
                case 4:
                case 6:
                case 9:
                case 11:
                    return 30;
                default :
                    return 31;
            }
        }

        private static function map_week_day($jd_day) {
            $days = array(
                0 => 6,
                1 => 0,
                2 => 1,
                3 => 2,
                4 => 3,
                5 => 4,
                6 => 5,
            );
            return $days[$jd_day];
        }

    }

}