<?php
defined('ABSPATH') || exit;
add_filter('cron_schedules', 'cron_filter_payments_schedules');
function cron_filter_payments_schedules($schedules)
{
    $schedules['ten_minutes'] = array(
        'interval' => 60 * 1,
        'display'  => esc_html__('Every Ten Minutes'),
    );
    return $schedules;
}
if (!wp_next_scheduled('transactions_cron_hook')) wp_schedule_event(time(), 'ten_minutes', 'transactions_cron_hook');
if (!class_exists('yascode_vip')) :
    class yascode_vip
    {
        private static $wpdb;
        private static $plans_table;
        private static $discounts_table;
        private static $subscribers_table;
        private static $payments_table;
        //init before run
        private static $instance;
        public static function get_instance()
        {
            if (!self::$instance) {
                self::$instance = new self();
            }
            return self::$instance;
        }

        public function __construct()
        {
            global $wpdb;
            self::$wpdb = $wpdb;
            self::$plans_table = self::$wpdb->prefix . 'yascode_vip_plans';
            self::$discounts_table = self::$wpdb->prefix . 'yascode_vip_discounts';
            self::$subscribers_table = self::$wpdb->prefix . 'yascode_vip_subscribers';
            self::$payments_table = self::$wpdb->prefix . 'yascode_vip_payments';
            add_action('after_setup_theme', array($this, 'create_subscription_tables'));
            add_action('admin_menu', array($this, 'create_subscriptions_page'));
            add_action('admin_head', array($this, 'subscriptions_head'));
            add_action('wp_head', array($this, 'check_subscription_plans'));
            add_action('transactions_cron_hook', array($this, 'check_payments'));

            if (is_admin() && current_user_can('administrator')) {
                add_action('show_user_profile', array($this, 'add_user_meta_subscription'));
                add_action('edit_user_profile', array($this, 'add_user_meta_subscription'));
                add_action('personal_options_update', array($this, 'add_user_meta_subscription_update'));
                add_action('edit_user_profile_update', array($this, 'add_user_meta_subscription_update'));
            }
            // ajax
            add_action('wp_ajax_yascode_use_subscription_discount_code', array($this, 'yascode_use_subscription_discount_code'));
        }

        public function check_payments()
        {
            $currentTime = (time() - 10 * 60);
            $date = date('Y-m-d H:i:s', $currentTime);
            $transactions = self::$wpdb->get_results("select * from " . self::$payments_table . " where created_at < '" . $date . "' AND status='pending'");
            if (!empty($transactions)) {
                $gateways = yascode_gateway::get_subscription_gateways();
                foreach ($transactions as $transaction) {
                    $gateway_id = (!empty($transaction->gateway_id)) ? $transaction->gateway_id : null;
                    if (!empty($gateway_id)) {
                        $trans_id = (!empty($transaction->transaction)) ? $transaction->transaction : '';
                        $authority = (!empty($transaction->authority)) ? $transaction->authority : '';
                        $price = (!empty($transaction->price)) ? $transaction->price : '';
                        $user_id = (!empty($transaction->user_id)) ? $transaction->user_id : 0;
                        $days = (!empty($transaction->days)) ? $transaction->days : 0;
                        if (!empty($gateways) && is_array($gateways)) {
                            foreach ($gateways as $gateway) {
                                if (!empty($gateway['id']) && $gateway['id'] == $gateway_id) {
                                    if (file_exists(THEME_TEMPLATE_URL_PATH . '/app/classes/subscription/gateways/' . $gateway_id . '-gateway.class.php')) {
                                        $gateway_api = (!empty($gateway['api'])) ? $gateway['api'] : '';
                                        if (!empty($gateway_api)) {
                                            require_once(THEME_TEMPLATE_URL_PATH . '/app/classes/subscription/gateways/' . $gateway_id . '-gateway.class.php');
                                            $verify = $gateway_id::verify_request($gateway_api, $price, $authority, $trans_id);
                                            if ($verify['success'] == true) {
                                                yascode_vip::add_subscriber($user_id, $days);
                                                yascode_vip::update_payment_status($trans_id, 'success');
                                            } else yascode_vip::update_payment_status($trans_id, 'failed');
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return;
        }

        public function cron_filter_payments_schedules($schedules)
        {
            $schedules['ten_minutes'] = array(
                'interval' => 60 * 1,
                'display'  => esc_html__('Every Ten Minutes'),
            );
            return $schedules;
        }


        public function check_subscription_plans()
        {
            if (isset($_POST['buy_subscription_plan']) && isset($_POST['security_nonce']) && wp_verify_nonce($_POST['security_nonce'], 'buy_subscription_security')) {
                $access = yc_get_option('subscription_access');
                if ($access != 'on') return;
                else {
                    $plan_id = (!empty($_POST['plan_id'])) ? $_POST['plan_id'] : 0;
                    $discount_code = (!empty($_POST['discount_code'])) ? $_POST['discount_code'] : null;
                    $gateway_id = (!empty($_POST['gateway_id'])) ? $_POST['gateway_id'] : null;
                    yascode_gateway::create_payment($plan_id, $gateway_id, $discount_code);
                }
            }
        }

        public static function create_payment_row($user_id, $gateway, $transaction, $authority, $price, $days, $discount = null, $percentage = 0, $status = 'pending')
        {
            $result = self::$wpdb->insert(self::$payments_table, array(
                'user_id' => $user_id,
                'gateway_id' => $gateway,
                'transaction' => $transaction,
                'authority' => $authority,
                'price' => $price,
                'days' => $days,
                'discount' => $discount,
                'percentage' => $percentage,
                'status' => $status,
                'created_at' => date('Y-m-d H:i:s')
            ));
            return $result;
        }

        public static function update_payment_status($transaction, $status)
        {
            $result = self::$wpdb->update(self::$payments_table, array(
                'status' => $status
            ), array('transaction' => $transaction));
            return $result;
        }

        public static function get_payment_info_by_transaction($transaction)
        {
            $result = array();
            $query = "select * from " . self::$payments_table . " where transaction = '" . $transaction . "' order by created_at DESC LIMIT 1";
            $result = self::$wpdb->get_row($query);
            return $result;
        }

        public function yascode_use_subscription_discount_code()
        {
            $msg = '';
            $result = array('success' => false);
            $nonce = $_POST['_wpnonce'];
            if (isset($nonce) && wp_verify_nonce($nonce, 'ajax_nonce')) {
                $code = (!empty($_POST['code'])) ? $_POST['code'] : '';
                $plan_id = (!empty($_POST['plan'])) ? $_POST['plan'] : '';
                $discount_info = self::get_discount_info_by_name($code);
                if (!empty($discount_info)) {
                    $percent = (!empty($discount_info->percentage)) ? $discount_info->percentage : 0;
                    $expire = (!empty($discount_info->expiration_date)) ? strtotime($discount_info->expiration_date) : null;
                    $plans = (!empty($discount_info->plan)) ? explode(',', $discount_info->plan) : null;
                    if ((!empty($expire) && $expire > time()) || (empty($expire))) {
                        if ((!empty($plans) && in_array($plan_id, $plans)) || (empty($plans))) {
                            $result['success'] = true;
                            $result['code'] = $code;
                            $plan_price = self::get_plan_price($plan_id, $code);
                            $result['new_price']['real_price'] = (!empty($plan_price['real_price'])) ? number_format($plan_price['real_price']) . ' تومان' : '';
                            $result['new_price']['discounted'] = (!empty($plan_price['discounted'])) ? number_format($plan_price['discounted']) . ' تومان' : '';
                            $result['new_price']['price'] = (is_numeric($plan_price['price']) && $plan_price['price'] >= 0) ? $plan_price['price'] : '';
                            if (is_numeric($result['new_price']['price']) && $result['new_price']['price'] == 0) $result['new_price']['price'] = 'رایگان';
                            elseif ($result['new_price']['price'] > 0) $result['new_price']['price'] = number_format($result['new_price']['price']) . ' تومان';
                            $msg = 'کد تخفیف ' . $percent . ' درصدی با موفقیت اعمال شد';
                        } else $msg = 'این کد تخفیف مختص پلن دیگری می باشد';
                    } else $msg = 'این کد تخفیف منقضی شده است';
                } else $msg = 'کد تخفیف وارد شده اشتباه می باشد !';
            } else $msg = 'خطایی رخ داد مجددا امتحان نمایید';
            $result['msg'] = $msg;
            wp_send_json($result);
            wp_die();
        }

        public static function get_plan_price($plan_id, $code = '')
        {
            $result = array();
            $plan_info = yascode_vip::get_plan_info($plan_id);
            if (!empty($plan_info)) {
                $price = 0;
                $discounted = 0;
                $real_price = (!empty($plan_info->price) && is_numeric($plan_info->price)) ? $plan_info->price : 0;
                $discount_price = (!empty($plan_info->discount_price) && is_numeric($plan_info->discount_price)) ? $plan_info->discount_price : 0;
                if (!empty($discount_price) && !empty($real_price) && $discount_price < $real_price) $price = $discount_price;
                else $price = $real_price;
                if (!empty($real_price) && !empty($discount_price) && $discount_price < $real_price) $discounted = $discounted + ceil($real_price - $discount_price);
                if (!empty($price)) {
                    $discount_info = (!empty($code)) ? self::get_discount_info_by_name($code) : '';
                    if (!empty($discount_info)) {
                        $percent = (!empty($discount_info->percentage)) ? $discount_info->percentage : 0;
                        $expire = (!empty($discount_info->expiration_date)) ? strtotime($discount_info->expiration_date) : null;
                        $plans = (!empty($discount_info->plan)) ? explode(',', $discount_info->plan) : null;
                        if ((!empty($expire) && $expire > time()) || (empty($expire))) {
                            if ((!empty($plans) && in_array($plan_id, $plans)) || (empty($plans))) {
                                $discounted_code = ($price * $percent) / 100;
                                $discounted = ceil($discounted + $discounted_code);
                                $price = ceil($price - $discounted_code);
                                $result['code'] = $code;
                                $result['percent'] = $percent;
                            }
                        }
                    }
                    $result['price'] = $price;
                    $result['real_price'] = $real_price;
                    $result['discount_price'] = $discount_price;
                    $result['discounted'] = $discounted;
                }
            }
            return $result;
        }

        public static function is_active()
        {
            $result = false;
            $vip_status = yc_get_option('subscription_access');
            $vip_status = (!empty($vip_status)) ? $vip_status : '';
            if ($vip_status == 'on') $result = true;
            else if ($vip_status == 'off') $result = false;
            else $result = true;
            return $result;
        }

        public static function limit_user_access_vip($post_type, $type)
        {
            # post_type = series | movies
            # type = dub | sub | play
            $result = false;
            $limits = yc_get_option('limit_vip_options');
            $vip_active = self::is_active();
            $limits = (!empty($limits) && is_array($limits)) ? $limits : array();
            if (!$vip_active || empty($limits)) $result = true;
            else if (array_key_exists('login_users', $limits) && !is_user_logged_in()) $result = false;
            else {
                $option = $type . '_' . $post_type;
                if (!array_key_exists($option, $limits)) $result = true;
                else if (is_user_logged_in()) {
                    $user_id = get_current_user_id();
                    if (self::is_user_vip($user_id)) $result = true;
                }
            }
            return $result;
        }

        public static function get_user_transactions($user_id, int $per_page = 5, int $paged = 1)
        {
            $result = array();
            $offset = ($paged - 1) * $per_page;
            $query = "select * from " . self::$payments_table . " where user_id='" . $user_id . "' order by created_at DESC LIMIT " . $per_page . " OFFSET " . $offset;
            $result['items'] = self::$wpdb->get_results($query);
            $query_count = "select COUNT(*) from " . self::$payments_table . " where user_id='" . $user_id . "'";
            $result['count'] = (int) self::$wpdb->get_var($query_count);
            $result['count'] = (empty($result['count']) ? 0 : $result['count']);
            $result['total_pages'] = ceil($result['count'] / $per_page);
            return $result;
        }

        public static function get_all_payments($per_page = 15, $paged = 1, $status = '', $order = '', $search = '')
        {
            $result = array();
            $offset = ($paged - 1) * $per_page;
            $where_str = '';
            $wheres = array();
            if (!empty($search)) {
                $user_id = 0;
                if (username_exists($search)) $user_data = get_user_by('login', $search);
                elseif (is_email($search)) $user_data = get_user_by('email', $search);
                if (!empty($user_data)) $user_id = $user_data->ID;
                if (!empty($user_id)) $wheres[] = " user_id='" . $user_id . "'";
                else $wheres[] = " transaction LIKE '%" . $search . "%'";
            }
            if (!empty($status)) {
                if ($status != 'failed') $wheres[] = " status='" . $status . "'";
                else $wheres[] = " status NOT IN ('success', 'pending')";
            }
            if (!empty($order)) {
                $current_date = date('Y-m-d');
                if ($order == 'today') $wheres[] = " created_at LIKE '%" . $current_date . "%'";
                elseif ($order == 'yesterday') {
                    $yesterday_date = date("Y-m-d", strtotime("-1 day", strtotime(current_time('mysql'))));
                    $wheres[] = " DATE(created_at) LIKE '%" . $yesterday_date . "%'";
                } else if ($order == 'week') {
                    $week_date = date('Y-m-d', strtotime($current_date . '-7 day'));
                    $wheres[] = " created_at >= '" . $week_date . 'T00:00:00.000' . "' AND created_at <= '" . $current_date . 'T00:00:00.000' . "'";
                } else if ($order == 'month') {
                    $month_date = date('Y-m-01');
                    $wheres[] = " created_at >= '" . $month_date . 'T00:00:00.000' . "' AND created_at <= '" . $current_date . 'T00:00:00.000' . "'";
                } else if ($order == 'year') {
                    $year_date = date('Y-01-01');
                    $wheres[] = " created_at >= '" . $year_date . 'T00:00:00.000' . "' AND created_at <= '" . $current_date . 'T00:00:00.000' . "'";
                }
            }
            if (!empty($wheres)) $where_str = ' where ' . implode(' AND', $wheres);
            $sep = 'where';
            if (!empty($where_str)) $sep = 'and';
            $query = "select * from " . self::$payments_table . " $where_str order by created_at DESC LIMIT $per_page OFFSET $offset";
            $count_query = "select COUNT(*) from " . self::$payments_table . " $where_str";
            $count_all = "select COUNT(*) from " . self::$payments_table;
            $count_success = "select COUNT(*) from " . self::$payments_table . " where status='success'";
            $count_failed = "select COUNT(*) from " . self::$payments_table . " where status NOT IN ('success', 'pending')";
            $count_pending = "select COUNT(*) from " . self::$payments_table . " where status='pending'";
            $count_success_total = "select COUNT(*) from " . self::$payments_table . " $where_str $sep status='success'";
            $count_success_come = "select SUM(price) from " . self::$payments_table . " $where_str $sep status='success'";
            $result['items'] = self::$wpdb->get_results($query);
            $result['count'] = self::$wpdb->get_var($count_query);
            $result['count_all'] = self::$wpdb->get_var($count_all);
            $result['count_success'] = self::$wpdb->get_var($count_success);
            $result['count_failed'] = self::$wpdb->get_var($count_failed);
            $result['count_pending'] = self::$wpdb->get_var($count_pending);
            $result['count_total_success'] = self::$wpdb->get_var($count_success_total);
            $result['count_total_come'] = self::$wpdb->get_var($count_success_come);
            $result['total_pages'] = (!empty($result['count'])) ? ceil($result['count'] / $per_page) : 0;
            return $result;
        }


        public static function get_plan_days($plan_id)
        {
            $result = 0;
            $plan_info = yascode_vip::get_plan_info($plan_id);
            if (!empty($plan_info)) $result = (!empty($plan_info->time)) ? $plan_info->time : 0;
            return $result;
        }

        public static function get_payment_status_info($status)
        {
            $result = array();
            if ($status == 'pending') {
                $result['name'] = 'در انتظار';
                $result['class'] = 'pending';
            } else if ($status == 'success') {
                $result['name'] = 'موفق';
                $result['class'] = 'success';
            } else {
                $result['name'] = 'ناموفق';
                $result['class'] = 'failed';
            }
            return $result;
        }

        public static function get_user_vip_status($user_id)
        {
            global $wpdb;
            $result = array(
                'status' => 0,
                'expire' => -1,
                'days_left' => 0,
                'expire_percent' => 0
            );
            $sql = "select * from " . self::$subscribers_table . " where user_id='" . $user_id . "'";
            $fetch = $wpdb->get_row($sql);
            if (!empty($fetch)) {
                $days = 0;
                $percent = 0;
                $current_time = time();
                $expire_date = (!empty($fetch->expiration_date)) ? $fetch->expiration_date : '';
                $status = (!empty($fetch->status)) ? $fetch->status : 0;
                if ($status == 1 && !empty($expire_date)) {
                    $seconds_expire = strtotime($expire_date);
                    $var = floor(($seconds_expire - $current_time) / 86400) + 1;
                    $days = ($var <= 0) ? 0 : $var;
                    $updated_at = (!empty($fetch->updated_at)) ? strtotime($fetch->updated_at) : '';
                    $current_time = time();
                    $per_com = (($current_time - $updated_at) / ($seconds_expire - $updated_at)) * 100;
                    $percent = ceil(max(100 - $per_com, 0));
                    if ($seconds_expire <= $current_time) {
                        $status = 0;
                        $expire_date = -1;
                        $days = 0;
                        $percent = 0;
                        self::$wpdb->update(self::$subscribers_table, array('status' => 0), array('user_id' => $user_id));
                    }
                }
                $result = array(
                    'status' => $status,
                    'expire' => $expire_date,
                    'days_left' => $days,
                    'expire_percent' => $percent
                );
            }
            return $result;
        }

        public static function is_user_vip($user_id)
        {
            $result = false;
            $vip_status = self::get_user_vip_status($user_id);
            $result = $vip_status['status'];
            return $result;
        }

        public function add_user_meta_subscription($user)
        {
            $subscriber = self::get_user_vip_status($user->ID); ?>
            <h2 style="font-family: 'irsans'">تنظیمات پوسته <?php echo FA_THEME_NAME; ?></h2>
            <table class="form-table">
                <tr>
                    <th><label for="user_subscriber">وضعیت اشتراک</label></th>
                    <td>
                        <label for="user_subscriber_on" style="background-color: #bdbdbd; padding: 6px 7px; border-radius: 3px; margin: 0 0 0 10px;">
                            <input name="user_subscriber" type="radio" id="user_subscriber_on" value="true" <?php echo ($subscriber['status'] == 1) ? 'checked' : ''; ?>> فعال
                        </label>
                        <label for="user_subscriber_off" style="background-color: #bdbdbd; padding: 6px 7px; border-radius: 3px; margin: 0 0 0 10px;">
                            <input name="user_subscriber" type="radio" id="user_subscriber_off" value="false" <?php echo ($subscriber['status'] == 0) ? 'checked' : ''; ?>>
                            غیرفعال
                        </label>
                    </td>
                </tr>
                <tr>
                    <th><label for="vip_expire_user">اعتبار اشتراک </label></th>
                    <td>
                        <div class="picker datepicker">
                            <input type="text" name="vip_expire_user" id="vip_expire_user" autocomplete="off" class="datepicker" value="<?php echo (!empty($subscriber['expire']) && $subscriber['expire'] != -1) ? jdate('Y/m/d', strtotime($subscriber['expire'])) : ''; ?>">
                            <span class="datepicker"></span>
                        </div>
                    </td>
                </tr>
                <tr>
                    <th><label for="vip_expire_user">تاریخ پایان اشتراک</label></th>
                    <td>
                        <?php if ($subscriber['status'] == 1) { ?>
                            <span style=" background-color: #4CAF50; color: #ffffff; padding: 6px; border-radius: 3px; letter-spacing: 2px; ">
                                <?php $expire_date = (!empty($subscriber['expire']) && $subscriber['expire'] != -1) ? jdate('Y/m/d', strtotime($subscriber['expire'])) : 'نامحدود';
                                echo $expire_date; ?>
                            </span>
                        <?php } else { ?>
                            <span style=" background-color: #e91e1e; color: #ffffff; padding: 6px; border-radius: 3px; ">غیرفعال</span>
                        <?php } ?>
                    </td>
                </tr>
            </table>
            <hr>
<?php }

        public function add_user_meta_subscription_update($user_id)
        {
            $expire_vip = (!empty($_POST['vip_expire_user'])) ? $_POST['vip_expire_user'] : '';
            if (!empty($expire_vip)) $expire_vip = yascode_jalali_to_gregorian($expire_vip);
            $status = (!empty($_POST['user_subscriber']) && $_POST['user_subscriber'] == 'true') ? 1 : 0;
            self::set_user_subscriber($user_id, $status, $expire_vip);
        }

        public static function set_user_subscriber($user_id, $status = false, $expire = null)
        {
            $fetch = self::$wpdb->get_row("select * from " . self::$subscribers_table . " where user_id='" . $user_id . "' order by created_at DESC LIMIT 1");
            $ID = (!empty($fetch->ID)) ? $fetch->ID : null;
            if (!empty($ID)) {
                self::$wpdb->update(self::$subscribers_table, array(
                    'user_id' => $user_id,
                    'expiration_date' => (!empty($expire)) ? $expire : null,
                    'status' => $status,
                    'updated_at' => date('Y-m-d H:i:s'),
                ), array('ID' => $ID));
            } else {
                self::$wpdb->insert(self::$subscribers_table, array(
                    'user_id' => $user_id,
                    'expiration_date' => (!empty($expire)) ? $expire : null,
                    'status' => $status,
                    'updated_at' => date('Y-m-d H:i:s'),
                    'created_at' => date('Y-m-d H:i:s')
                ));
            }
        }

        public static function add_subscriber($user_id, $days)
        {
            $fetch = self::$wpdb->get_row("select * from " . self::$subscribers_table . " where user_id='" . $user_id . "' order by created_at DESC LIMIT 1");
            $ID = (!empty($fetch->ID)) ? $fetch->ID : null;
            if (!empty($ID)) {
                $current_time = time();
                $expiration_date = (empty($fetch->expiration_date) ? 0 : strtotime($fetch->expiration_date));
                $seconds_to_expire =  $expiration_date - $current_time;
                $this_days = floor($seconds_to_expire / 86400);
                $days_left = ($this_days < 0 ? 0 : $this_days);
                $final_days = $days_left + $days;
                $expiration = date('Y-m-d H:m:s', strtotime('+' . $final_days . ' days'));
                self::$wpdb->update(self::$subscribers_table, array(
                    'user_id' => $user_id,
                    'expiration_date' => $expiration,
                    'status' => true,
                    'updated_at' => date('Y-m-d H:i:s'),
                ), array('ID' => $ID));
            } else {
                $expiration = date('Y-m-d H:m:s', strtotime('+' . $days . ' days'));
                self::$wpdb->insert(self::$subscribers_table, array(
                    'user_id' => $user_id,
                    'expiration_date' => $expiration,
                    'status' => true,
                    'updated_at' => date('Y-m-d H:i:s'),
                    'created_at' => date('Y-m-d H:i:s')
                ));
            }
        }

        public function subscriptions_head()
        {
            $page = (!empty($_GET['page'])) ? $_GET['page'] : '';
            if ($page == 'subscriptions') {
                if (isset($_POST['submit_edit_plan'])) {
                    $sub_page = (!empty($_GET['plan'])) ? $_GET['plan'] : '';
                    $msg = '';
                    $status = 'nok';
                    $plan_id = (!empty($_POST['plan_id']) && is_numeric($_POST['plan_id'])) ? $_POST['plan_id'] : 0;
                    $plan_name = (!empty($_POST['plan_name'])) ? sanitize_text_field($_POST['plan_name']) : '';
                    $plan_time = (!empty($_POST['plan_time']) && is_numeric($_POST['plan_time'])) ? $_POST['plan_time'] : 0;
                    $plan_price = (!empty($_POST['plan_price']) && is_numeric($_POST['plan_price']) && $_POST['plan_price'] >= 1000) ? $_POST['plan_price'] : 0;
                    $plan_discount_price = (!empty($_POST['plan_discount_price']) && is_numeric($_POST['plan_discount_price']) && $_POST['plan_discount_price'] >= 1000) ? $_POST['plan_discount_price'] : null;
                    if (empty($plan_name)) $msg = 'نام پلن الزامی می باشد';
                    if (empty($plan_time)) $msg = 'تعداد روز عددی و الزامی می باشد';
                    if (empty($plan_price)) $msg = 'قیمت پلن الزامی و بیشتر از 1000 می باشد';
                    if (!empty($plan_discount_price) && $plan_discount_price > $plan_price) $msg = 'قیمت تخفیف خورده عددی و نمیتواند بیشتر از قیمت اصلی باشد همچنین بیشتر از 1000 می باشد';
                    if (empty($msg)) {
                        if (!empty($plan_id)) {
                            $updated = self::$wpdb->update(self::$plans_table, array(
                                'name' => $plan_name,
                                'time' => $plan_time,
                                'price' => $plan_price,
                                'discount_price' => $plan_discount_price,
                            ), array('ID' => $plan_id));
                            if ($updated) {
                                $msg = 'پلن با موفقیت بروز شد !';
                                $status = 'ok';
                            } else $msg = 'خطایی پیش آمد';
                        } else {
                            $created = self::$wpdb->insert(self::$plans_table, array(
                                'name' => $plan_name,
                                'time' => $plan_time,
                                'price' => $plan_price,
                                'discount_price' => $plan_discount_price,
                                'created_at' => date('Y-m-d H:i:s')
                            ));
                            if ($created) {
                                $msg = 'پلن جدید با موفقیت ایجاد شد !';
                                $status = 'ok';
                            } else $msg = 'خطایی پیش آمد';
                        }
                    }
                    if ($status == 'ok') wp_redirect(add_query_arg(array('page' => 'subscriptions', 'status' => $status, 'msg' => $msg), admin_url('admin.php')));
                    else wp_redirect(add_query_arg(array('page' => 'subscriptions', 'plan' => $sub_page, 'status' => $status, 'msg' => $msg), admin_url('admin.php')));
                } else if (isset($_POST['select_plans_action'])) {
                    $action = (!empty($_POST['action_item'])) ? $_POST['action_item'] : '';
                    $plans = (!empty($_POST['select_plans']) && is_array($_POST['select_plans'])) ? $_POST['select_plans'] : array();
                    if (!empty($plans)) {
                        foreach ($plans as $plan_id) {
                            if (!empty($action)) {
                                if ($action == 'remove') self::remove_plan($plan_id);
                            }
                        }
                        $msg = '';
                        if ($action == 'remove') $msg = 'پلن های انتخابی حذف شد';
                        if (!empty($msg)) wp_redirect(add_query_arg(array('page' => 'subscriptions', 'status' => 'ok', 'msg' => $msg), admin_url('admin.php')));
                    }
                }
            } else if ($page == 'discounts') {
                if (isset($_POST['submit_edit_discount'])) {
                    $sub_page = (!empty($_GET['discount'])) ? $_GET['discount'] : '';
                    $msg = '';
                    $status = 'nok';
                    $discount_id = (!empty($_POST['discount_id']) && is_numeric($_POST['discount_id'])) ? $_POST['discount_id'] : 0;
                    $discount_title = (!empty($_POST['discount_title'])) ? sanitize_text_field($_POST['discount_title']) : '';
                    $discount_percent = (!empty($_POST['discount_percent']) && is_numeric($_POST['discount_percent'])) ? $_POST['discount_percent'] : 0;
                    $discount_expire = (!empty($_POST['discount_expire'])) ? $_POST['discount_expire'] : null;
                    $discount_plans = (!empty($_POST['discount_plans'])) ? $_POST['discount_plans'] : null;
                    if (!empty($discount_expire)) $discount_expire = yascode_jalali_to_gregorian($discount_expire);
                    if (empty($discount_title)) $msg = 'کد تخفیف الزامی می باشد';
                    if (empty($discount_percent) || !is_numeric($discount_percent) || $discount_percent > 100 || $discount_percent < 1) $msg = 'درصد تخفیف الزامی و بین 1 تا 100 می باشد';
                    if (empty($msg)) {
                        if (!empty($discount_id)) {
                            $updated = self::$wpdb->update(self::$discounts_table, array(
                                'title' => $discount_title,
                                'percentage' => $discount_percent,
                                'expiration_date' => $discount_expire,
                                'plan' => $discount_plans
                            ), array('ID' => $discount_id));
                            if ($updated) {
                                $msg = 'کد تخفیف با موفقیت بروز شد !';
                                $status = 'ok';
                            } else $msg = 'خطایی پیش آمد';
                        } else {
                            $created = self::$wpdb->insert(self::$discounts_table, array(
                                'title' => $discount_title,
                                'percentage' => $discount_percent,
                                'expiration_date' => $discount_expire,
                                'plan' => $discount_plans,
                                'created_at' => date('Y-m-d H:i:s')
                            ));
                            if ($created) {
                                $msg = 'کد تخفیف جدید با موفقیت ایجاد شد !';
                                $status = 'ok';
                            } else $msg = 'خطایی پیش آمد';
                        }
                    }
                    if ($status == 'ok') wp_redirect(add_query_arg(array('page' => 'discounts', 'status' => $status, 'msg' => $msg), admin_url('admin.php')));
                    else wp_redirect(add_query_arg(array('page' => 'discounts', 'discount' => $sub_page, 'status' => $status, 'msg' => $msg), admin_url('admin.php')));
                }
            } else if ($page == 'subscribers') {
                if (!empty($_GET['action']) && !empty($_GET['select_subs'])) {
                    $action = $_GET['action'];
                    $subscribers = $_GET['select_subs'];
                    foreach ($subscribers as $subscriber) self::subscriber_change_status($subscriber, $action);
                    if ($action == 'remove') $msg = 'مشترکین انتخابی حذف شد';
                    elseif ($action == 'deactive') $msg = 'مشترکین انتخابی منقضی شدند';
                    elseif ($action == 'active') $msg = 'مشترکین انتخابی فعال شدند';
                    if (!empty($msg)) wp_redirect(add_query_arg(array('page' => 'subscribers', 'status' => 'ok', 'msg' => $msg), admin_url('admin.php')));
                }
            } else if ($page == 'transactions') {
                if (!empty($_POST['action']) && !empty($_POST['select_transactions'])) {
                    $action = $_POST['action'];
                    $transes = $_POST['select_transactions'];
                    foreach ($transes as $trans_id) {
                        if ($action == "remove") self::remove_transaction($trans_id);
                        elseif ($action == "successful") self::transaction_change_status($trans_id, "success");
                        elseif ($action == "unsuccessful") self::transaction_change_status($trans_id, "failed");
                    }
                    if ($action == 'remove') $msg = 'تراکنش های انتخابی حذف شد';
                    elseif ($action == 'successful') $msg = 'تراکنش های انتخابی موفق شدند';
                    elseif ($action == 'unsuccessful') $msg = 'تراکنش های انتخابی ناموفق شدند';
                    if (!empty($msg)) wp_redirect(add_query_arg(array('page' => 'transactions', 'stats' => 'ok', 'msg' => $msg), admin_url('admin.php')));
                }
            }
        }

        public static function transaction_change_status($trans_id, $action)
        {
            if (is_numeric($trans_id) && !empty($action)) self::$wpdb->update(self::$payments_table, array('status' => $action), array('ID' => $trans_id));
            return true;
        }

        public static function subscriber_change_status($subscriber, $action)
        {
            if ($action == 'remove') self::remove_subscriber($subscriber);
            else {
                $status = '';
                if ($action == 'deactive') $status = '0';
                else if ($action == 'active') $status = '1';
                if (is_numeric($status) && $status >= 0) self::$wpdb->update(self::$subscribers_table, array('status' => $status), array('ID' => $subscriber));
            }
            return true;
        }

        public static function get_subscribers($per_page = 15, $paged = 1, $status = '', $search = '')
        {
            $result = array();
            $offset = ($paged - 1) * $per_page;
            $where_str = '';
            $wheres = array();
            if (!empty($search)) {
                $user_id = 0;
                if (username_exists($search)) $user_data = get_user_by('login', $search);
                elseif (is_email($search)) $user_data = get_user_by('email', $search);
                if (!empty($user_data)) $user_id = $user_data->ID;
                $wheres[] = " user_id='" . $user_id . "'";
            }
            if (!empty($status)) {
                if ($status == 'active') $wheres[] = " status='1'";
                else if ($status == 'expired') $wheres[] = " status='0'";
            }
            if (!empty($wheres)) $where_str = ' where ' . implode(' AND', $wheres);
            $query = "select * from " . self::$subscribers_table . " $where_str order by created_at DESC LIMIT $per_page OFFSET $offset";
            $count_query = "select COUNT(*) from " . self::$subscribers_table . " $where_str";
            $count_all = "select COUNT(*) from " . self::$subscribers_table;
            $count_active = "select COUNT(*) from " . self::$subscribers_table . " where status='1'";
            $count_expired = "select COUNT(*) from " . self::$subscribers_table . " where status='0'";
            $result['items'] = self::$wpdb->get_results($query);
            $result['count'] = self::$wpdb->get_var($count_query);
            $result['count_all'] = self::$wpdb->get_var($count_all);
            $result['count_active'] = self::$wpdb->get_var($count_active);
            $result['count_expired'] = self::$wpdb->get_var($count_expired);
            $result['total_pages'] = (!empty($result['count'])) ? ceil($result['count'] / $per_page) : 0;
            return $result;
        }

        public static function remove_subscriber($subscriber_id)
        {
            $result = array();
            $deleted = self::$wpdb->delete(self::$subscribers_table, array('ID' => $subscriber_id));
            if ($deleted) {
                $result['status'] = 'ok';
                $result['text'] = 'مشترک انتخابی حذف شد';
            } else {
                $result['status'] = 'nok';
                $result['text'] = 'مشترکی جهت حذف یافت نشد';
            }
            return $result;
        }

        public static function remove_transaction($trans_id)
        {
            $result = array();
            $deleted = self::$wpdb->delete(self::$payments_table, array('ID' => $trans_id));
            if ($deleted) {
                $result['status'] = 'ok';
                $result['text'] = 'تراکنش انتخابی حذف شد';
            } else {
                $result['status'] = 'nok';
                $result['text'] = 'تراکنشی جهت حذف یافت نشد';
            }
            return $result;
        }

        public static function get_discounts($per_page = 15, $paged = 1)
        {
            $result = array();
            $offset = ($paged - 1) * $per_page;
            $query = "select * from " . self::$discounts_table . " order by created_at DESC LIMIT $per_page OFFSET $offset";
            $count_query = "select COUNT(*) from " . self::$discounts_table;
            $result['items'] = self::$wpdb->get_results($query);
            $result['count'] = self::$wpdb->get_var($count_query);
            $result['total_pages'] = (!empty($result['count'])) ? ceil($result['count'] / $per_page) : 0;
            return $result;
        }

        public static function remove_discount($discount_id)
        {
            $result = array();
            $deleted = self::$wpdb->delete(self::$discounts_table, array('ID' => $discount_id));
            if ($deleted) {
                $result['status'] = 'ok';
                $result['text'] = 'کد تخفیف انتخابی حذف شد';
            } else {
                $result['status'] = 'nok';
                $result['text'] = 'کد تخفیفی جهت حذف یافت نشد';
            }
            return $result;
        }

        public static function get_discount_info($discount_id)
        {
            $result = array();
            $query = "select * from " . self::$discounts_table . " where ID = '" . $discount_id . "' LIMIT 1";
            $result = self::$wpdb->get_row($query);
            return $result;
        }

        public static function get_discount_info_by_name($code)
        {
            $result = array();
            $query = "select * from " . self::$discounts_table . " where title = '" . $code . "' order by created_at DESC LIMIT 1";
            $result = self::$wpdb->get_row($query);
            return $result;
        }

        public static function get_plans($per_page = 'all', $paged = 1)
        {
            $result = array();
            $limit = '';
            if (is_numeric($per_page)) {
                $offset = ($paged - 1) * $per_page;
                $limit = "LIMIT $per_page OFFSET $offset";
            }
            $query = "select * from " . self::$plans_table . " order by created_at DESC $limit";
            $count_query = "select COUNT(*) from " . self::$plans_table;
            $result['items'] = self::$wpdb->get_results($query);
            $result['count'] = self::$wpdb->get_var($count_query);
            if (is_numeric($per_page)) $result['total_pages'] = (!empty($result['count'])) ? ceil($result['count'] / $per_page) : 0;
            return $result;
        }

        public static function get_plan_info($plan_id)
        {
            $result = array();
            $query = "select * from " . self::$plans_table . " where ID = '" . $plan_id . "' LIMIT 1";
            $result = self::$wpdb->get_row($query);
            return $result;
        }

        public static function remove_plan($plan_id)
        {
            $result = array();
            $deleted = self::$wpdb->delete(self::$plans_table, array('ID' => $plan_id));
            if ($deleted) {
                $result['status'] = 'ok';
                $result['text'] = 'پلن انتخابی حذف شد';
            } else {
                $result['status'] = 'nok';
                $result['text'] = 'پلنی جهت حذف یافت نشد';
            }
            return $result;
        }

        public function create_subscriptions_page()
        {
            add_menu_page(
                "اشتراک ویژه",
                "اشتراک ویژه",
                'administrator',
                'subscriptions',
                array($this, 'subscription_page_init'),
                'dashicons-groups',
                10
            );
            add_submenu_page(
                'subscriptions',
                "کدهای تخفیف",
                "کدهای تخفیف",
                'administrator',
                'discounts',
                array($this, 'subscription_discount_init'),
                1
            );
            add_submenu_page(
                'subscriptions',
                "لیست مشترکین",
                "لیست مشترکین",
                'administrator',
                'subscribers',
                array($this, 'subscription_subscriber_init'),
                2
            );
            add_submenu_page(
                'subscriptions',
                "تراکنش ها",
                "تراکنش ها",
                'administrator',
                'transactions',
                array($this, 'subscription_transaction_init'),
                3
            );
        }

        public function subscription_subscriber_init()
        {
            $this->vip_get_template('subscribers');
        }

        public function subscription_transaction_init()
        {
            $this->vip_get_template('transactions');
        }

        public function subscription_page_init()
        {
            $sub_page = (!empty($_GET['plan'])) ? $_GET['plan'] : '';
            if (is_numeric($sub_page) || $sub_page == 'new') $this->vip_get_template('plan-edit');
            else $this->vip_get_template('plans');
        }

        private function vip_get_template($page)
        {
            include THEME_TEMPLATE_URL_PATH . '/templates/admin/subscriptions/' . $page . '.php';
        }

        public function subscription_discount_init()
        {
            $sub_page = (!empty($_GET['discount'])) ? $_GET['discount'] : '';
            if (is_numeric($sub_page) || $sub_page == 'new') $this->vip_get_template('discount-edit');
            else $this->vip_get_template('discounts');
        }

        public function create_subscription_tables()
        {
            if (self::$wpdb->get_var("SHOW TABLES LIKE '" . self::$plans_table . "'") != self::$plans_table) {
                $sql = "CREATE TABLE IF NOT EXISTS `" . self::$plans_table . "` (
                `ID` bigint(20) NOT NULL AUTO_INCREMENT,
                `name` varchar(200) NOT NULL,
                `time` smallint UNSIGNED NOT NULL DEFAULT 0,
                `price` int(20) NOT NULL,
                `discount_price` int(20) DEFAULT NULL,
                `special` BOOLEAN DEFAULT 0,
                `icon` varchar(60) DEFAULT NULL,
                `created_at` datetime NOT NULL,
                    PRIMARY KEY (`ID`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";
                require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
                dbDelta($sql);
            }

            if (self::$wpdb->get_var("SHOW TABLES LIKE '" . self::$discounts_table . "'") != self::$discounts_table) {
                $sql = "CREATE TABLE IF NOT EXISTS `" . self::$discounts_table . "` (
                `ID` bigint(20) NOT NULL AUTO_INCREMENT,
                `title` varchar(200) NOT NULL,
                `percentage` tinyint(2) NOT NULL DEFAULT '0',
                `expiration_date` datetime DEFAULT NULL,
                `plan` text DEFAULT NULL,
                `created_at` datetime NOT NULL,
                    PRIMARY KEY (`ID`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";
                require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
                dbDelta($sql);
            }

            if (self::$wpdb->get_var("SHOW TABLES LIKE '" . self::$subscribers_table . "'") != self::$subscribers_table) {
                $sql = "CREATE TABLE IF NOT EXISTS `" . self::$subscribers_table . "` (
                `ID` bigint(20) NOT NULL AUTO_INCREMENT,
                `user_id` bigint(20) NOT NULL,
                `expiration_date` datetime DEFAULT NULL,
                `status` BOOLEAN DEFAULT 0,
                `updated_at` datetime NOT NULL,
                `created_at` datetime NOT NULL,
                    PRIMARY KEY (`ID`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";
                require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
                dbDelta($sql);
            }

            if (self::$wpdb->get_var("SHOW TABLES LIKE '" . self::$payments_table . "'") != self::$payments_table) {
                $sql = "CREATE TABLE IF NOT EXISTS `" . self::$payments_table . "` (
                `ID` bigint(20) NOT NULL AUTO_INCREMENT,
                `user_id` bigint(20) NOT NULL,
                `gateway_id` text DEFAULT NULL,
                `transaction` text DEFAULT NULL,
                `authority` text DEFAULT NULL,
                `price` varchar(150) NOT NULL DEFAULT 0,
                `status` varchar(20) DEFAULT NULL,
                `days` bigint(20) unsigned NOT NULL,
                `discount` varchar(200) DEFAULT NULL,
                `percentage` tinyint(2) NOT NULL DEFAULT 0,
                `created_at` datetime NOT NULL,
                    PRIMARY KEY (`ID`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";
                require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
                dbDelta($sql);
            }
        }
    }
    yascode_vip::get_instance();
endif;
