<?php
namespace PostSnippets;

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

/**
 * Post Snippets All Snippets Table.
 *
 * Class to view list of all Snippets extending WP_List_Table class.
 *
 */
if (class_exists('PostSnippets')) {

    if (!class_exists('WP_List_Table')) {
        require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
    }

    class PSallSnippets extends \WP_List_Table
    {

        /**
         * Generates the table navigation above or bellow the table 
         * 
         * @param string $which 
         * @return void
         */


        function display_tablenav($which)
        {
            ?>
            <div class="tablenav <?php echo esc_attr($which); ?>">

                <div class="alignleft actions bulkactions">
                    <?php $this->bulk_actions($which); ?>
                </div>
                <?php
                $this->extra_tablenav($which);
                $this->pagination($which);
                ?>
                <br class="clear" />
            </div>
            <?php

        }



        function column_snippet_title($item)
        {  //function name is array key of the column

            $snippet_status = ($item['snippet_status'] == esc_attr__('Active', 'post-snippets') ? esc_attr__('Deactivate', 'post-snippets') : esc_attr__('Activate', 'post-snippets'));

            $action_nonce = wp_create_nonce('ps-snippets-hover-trigger_' . $item['ID']);

            $page = Edit::get_snippet_page($item['snippet_php']);

            $actions = array(
                'edit' => sprintf('<a href="?page=%s&action=%s&snippet=%s&_wpnonce=%s">%s</a>', esc_attr($page), 'edit', $item['ID'], $action_nonce, esc_attr__('Edit', 'post-snippets')),
                'delete' => sprintf('<button class="link_style_button red" type=%s name=%s value=%s>%s</button>', esc_attr('submit'), 'delete', $item['ID'], esc_attr__('Delete', 'post-snippets')),
                'status' => sprintf('<button class="link_style_button" type=%s name=%s value=%s>%s</button>', esc_attr('submit'), sanitize_title($snippet_status), $item['ID'], $snippet_status),
                'duplicate' => sprintf('<button class="link_style_button" type=%s name=%s value=%s>%s</button>', esc_attr('submit'), 'duplicate', $item['ID'], esc_attr__('Duplicate', 'post-snippets')),
            );

            return sprintf('%1$s %2$s', $item['snippet_title'], $this->row_actions($actions));
        }


        function get_bulk_actions()
        {   //Bulk Action Dropdown
            $actions = array(
                'enable' => 'Enable',
                'disable' => 'Disable'
            );
            return $actions;
        }

        function column_cb($item)
        {     //Checkbox column
            return sprintf(
                '<input type="checkbox" name="snippets[]" value="%s" class="post-snippet-table-individual-checkbox"/>',
                $item['ID']
            );
        }

        /**This will add vals to table class */
        function __construct()
        {
            parent::__construct(array(
                'singular' => 'psp_all_snippet', //Singular label
                'plural' => 'psp_all_snippets', //plural label, also this well be one of the table css class
                //    'ajax'   => false //We won't support Ajax for this table
            ));
        }


        /**
         * Add extra markup in the toolbars before or after the list
         * @param string $which, helps you decide if you add the markup after (bottom) or before (top) the list
         */
        function extra_tablenav($which)
        {

            if ($which == "top") {
                //The code that goes before the table is here
                ?>

                <div class="alignleft actions">
                    <label class="screen-reader-text"
                        for="filter_by_status"><?php esc_html_e('Filter by status', 'post-snippets') ?></label>
                    <select name="status" id="filter_by_status" class="postform">
                        <option value="-1"> <?php esc_html_e('Select Status', 'post-snippets') ?></option>
                        <option value="1" <?php echo esc_attr((1 == ($_REQUEST['status'] ?? '')) ? " selected" : ''); ?>>
                            <?php esc_html_e('Active', 'post-snippets') ?></option>
                        <option value="0" <?php echo esc_attr((0 == ($_REQUEST['status'] ?? '')) ? " selected" : ''); ?>>
                            <?php esc_html_e('Inactive', 'post-snippets') ?></option>
                    </select>
                    <input type="submit" name="status_filter_action" id="doaction" class="button action"
                        value="<?php esc_html_e('Filter', 'post-snippets') ?>">

                </div>




                </div>

                <?php
            }
        }


        /**
         * Prepare the items for the table to process
         *
         * @return Void
         */
        public function prepare_items()
        {

            $this->trigger_hover_action();
            $this->process_bulk_action();
            $this->process_bulk_upload();
            $this->process_bulk_download();

            global $wpdb;

            $table_name = $wpdb->prefix . \PostSnippets::TABLE_NAME;
            $group_table_name = $wpdb->prefix . \PostSnippets::GROUP_TABLE_NAME;

            // $snippets_query = $this->process_bulk_filter($table_name);

            // $snippets = $wpdb->get_results($wpdb->prepare($snippets_query, NULL), ARRAY_A );

            $snippets = $this->process_bulk_filter($table_name);

            if (!empty($snippets) && $snippets != NULL) {

                $data = $snippets;

                foreach ($data as $key => $value) { /**Changing group name and status and date*/

                    $data[$key]['snippet_status'] = ($data[$key]['snippet_status'] == 1 ? esc_attr__('Active', 'post-snippets') : esc_attr__('InActive', 'post-snippets'));
                    $date = $data[$key]['snippet_date'];
                    $createDate = new \DateTime($date);
                    $data[$key]['snippet_date'] = $createDate->format('d-m-Y');

                    unset($data[$key]['snippet_content']);    /**No need for Snippet Content */
                    unset($data[$key]['snippet_vars']);    /**No need for Snippet Vars on List Table */

                    $data[$key]['snippet_desc'] = esc_html(stripslashes($data[$key]['snippet_desc']));
                }

                usort($data, array(&$this, 'sort_data'));   //sort_data is a function, use database related function

                $perPage = $this->get_items_per_page('psp_snippets_per_page', 10);
                $currentPage = $this->get_pagenum();
                $totalItems = count($data);

                $this->set_pagination_args(array(
                    'total_items' => $totalItems,
                    'per_page' => $perPage
                ));

                $data = array_slice($data, (($currentPage - 1) * $perPage), $perPage);

                $this->items = $data;

            }

            $columns = $this->get_columns();
            $hidden = $this->get_hidden_columns();
            $sortable = $this->get_sortable_columns();

            $this->_column_headers = array($columns, $hidden, $sortable);

        }

        /**
         * Override the parent columns method. Defines the columns to use in your listing table
         *
         * @return Array
         */
        public function get_columns()
        {
            $columns = array(
                'cb' => '<input type="checkbox" />',
                // 'id'          => 'ID',
                'snippet_title' => esc_attr__('Title', 'post-snippets'),
                'snippet_desc' => esc_attr__('Description', 'post-snippets'),
                'snippet_status' => esc_attr__('Status', 'post-snippets'),
                'snippet_date' => esc_attr__('Date', 'post-snippets'),

            );

            return $columns;
        }

        /**
         * Define which columns are hidden
         *
         * @return Array
         */
        public function get_hidden_columns()
        {
            return array();
        }

        /**
         * Define the sortable columns
         *
         * @return Array
         */
        public function get_sortable_columns()
        {
            return array('snippet_title' => array('snippet_title', false));
        }

        /**
         * Define what data to show on each column of the table
         *
         * @param  Array $item        Data
         * @param  String $column_name - Current column name
         *
         * @return Mixed
         */
        public function column_default($item, $column_name)
        {
            switch ($column_name) {
                case 'ID':
                case 'snippet_title':
                case 'snippet_desc':
                case 'snippet_status':
                case 'snippet_group':
                case 'snippet_date':
                    $content = $this->col_content_short_length($item[$column_name]);
                    return $content;

                default:
                    return print_r($item, true);
            }
        }

        /**
         * @param $col : column content
         *
         * @return content Short Content
         */
        public function col_content_short_length($col)
        {
            $content = str_replace(array("\r\n", "\r", "\n"), "[BR]", htmlspecialchars($col));
            $content = mb_strimwidth($content, 0, 100, " ...");
            return $content;
        }

        /**
         * Allows you to sort the data by the variables set in the $_GET
         *
         * @return Mixed
         */
        private function sort_data($a, $b)
        {
            // Set defaults
            $orderby = 'snippet_title';
            $order = 'asc';

            // If orderby is set, use this as the sort column
            if (!empty($_GET['orderby'])) {
                $orderby = $_GET['orderby'];
            }

            // If order is set use this as the order
            if (!empty($_GET['order'])) {
                $order = $_GET['order'];
            }


            $result = strcmp($a[$orderby], $b[$orderby]);

            if ($order === 'asc') {
                return $result;
            }

            return -$result;
        }


        /**
         * Trigger Actions from the Hovering Actions section
         *
         * @return NULL
         */
        private function trigger_hover_action()
        {

            if (isset($_REQUEST['delete'])) {

                check_admin_referer('pspro_all_snippets', 'pspro_all_snippets_nonce');

                $snippet_id = intval($_REQUEST['delete']);

                if ($this->delete_snippet($snippet_id)) {
                    printf('<div class="notice notice-success is-dismissible"><p>%s..</p></div>', esc_html__('Snippet Deleted', 'post-snippets'));
                } else {
                    printf('<div class="notice notice-error is-dismissible"><p>%s..</p></div>', esc_html__('There has been an Error', 'post-snippets'));
                }

            } elseif (isset($_REQUEST['deactivate'])) {    /**if it needs to be deactivate */

                check_admin_referer('pspro_all_snippets', 'pspro_all_snippets_nonce');

                $snippet_id = intval($_REQUEST['deactivate']);

                if ($this->change_snippet_status($snippet_id, 0)) {
                    printf('<div class="notice notice-success is-dismissible"><p>%s..</p></div>', esc_html__('Snippet Deactivated', 'post-snippets'));
                } else {
                    printf('<div class="notice notice-error is-dismissible"><p>%s..</p></div>', esc_html__('There has been an Error', 'post-snippets'));
                }
            } elseif (isset($_REQUEST['activate'])) {    /**if it needs to be activated */

                check_admin_referer('pspro_all_snippets', 'pspro_all_snippets_nonce');

                $snippet_id = intval($_REQUEST['activate']);

                if ($this->change_snippet_status($snippet_id, 1)) {
                    printf('<div class="notice notice-success is-dismissible"><p>%s..</p></div>', esc_html__('Snippet Activated', 'post-snippets'));
                } else {
                    printf('<div class="notice notice-error is-dismissible"><p>%s..</p></div>', esc_html__('There has been an Error', 'post-snippets'));
                }
            } elseif (isset($_REQUEST['duplicate'])) {      /**If duplicate is clicked */

                check_admin_referer('pspro_all_snippets', 'pspro_all_snippets_nonce');

                $snippet_id = intval($_REQUEST['duplicate']);

                if ($this->duplicate_snippet($snippet_id)) {
                    printf('<div class="notice notice-success is-dismissible"><p>%s..</p></div>', esc_html__('Snippet Duplicated', 'post-snippets'));
                } else {
                    printf('<div class="notice notice-error is-dismissible"><p>%s..</p></div>', esc_html__('There has been an Error', 'post-snippets'));
                }
            }
        }

        /**
         * Delete Snippet from the Hovering Actions section
         *
         * @return NULL
         */
        private function delete_snippet($snippet_id)
        {

            global $wpdb;
            $table_name = $wpdb->prefix . \PostSnippets::TABLE_NAME;

            $snippet_groups = maybe_unserialize($wpdb->get_var($wpdb->prepare("SELECT snippet_group FROM $table_name WHERE ID = %d", $snippet_id)));

            if ($wpdb->delete($table_name, array('ID' => $snippet_id), array('%d'))) {

                if (!empty($snippet_groups)) {  /**It should have atleast one group, the default group, but just in case */

                    Edit::change_group_count($snippet_groups, 'decrement');

                }
                return true;
            }

        }



        /**
         * Change Snippet Status from the Hovering Actions section
         * 
         * @param  Array|Int    $snippet_ids     Snippets ID Array or Int
         * @param  Int          $action         Whether to activate(1) or deactivate(0)
         *
         * @return Boolean
         */
        private function change_snippet_status($snippet_ids, $action)
        {

            global $wpdb;
            $table_name = $wpdb->prefix . \PostSnippets::TABLE_NAME;

            if (!is_array($snippet_ids)) {

                $snippet_ids = array($snippet_ids);

            }

            foreach ($snippet_ids as $key => $snippet_id) {

                $snippet_status = $wpdb->get_var($wpdb->prepare("SELECT snippet_status FROM $table_name WHERE ID = %d", $snippet_id));       /**Getting It's Status */

                if ($action == 1 && $snippet_status != 1) {    /**If its Already Active, Skip */

                    $status_updated = $this->update_snippet_status($snippet_id, $action, $table_name, $wpdb);
                } elseif ($action == 0 && $snippet_status != 0) {    /**If its Already InActive, Skip */

                    $status_updated = $this->update_snippet_status($snippet_id, $action, $table_name, $wpdb);
                } else {
                    $status_updated = true;
                }
            }

            if ($status_updated) {
                return true;
            }
        }


        /**
         * Change Snippet Status from the Hovering Actions section
         * 
         * @param  Int    $snippet_id     Snippets ID
         * @param  Int    $action         Whether to activate(1) or deactivate(0)
         *
         * @return Int|Bool
         */
        private function update_snippet_status($snippet_id, $action, $table_name, $wpdb)
        {

            $status_updated = $wpdb->update(
                $table_name,
                array(              /**Data to be updated */
                    'snippet_status' => $action,
                ),
                array(                      /**Where Coulum = ? */
                    'ID' => $snippet_id,
                ),
                array(                      /**Data Format, %d or %s */
                    '%d'
                ),
                array(                      /**Where Format, %d or %s */
                    '%d'
                )
            );

            return $status_updated;

        }


        /**
         * Duplicate Snippet from the Hovering Actions section
         *
         * @return NULL
         */
        public static function duplicate_snippet($snippet_id)
        {

            global $wpdb;
            $table_name = $wpdb->prefix . \PostSnippets::TABLE_NAME;

            $current_time = (current_time('mysql'));

            $snippet_title = $wpdb->get_var($wpdb->prepare("SELECT snippet_title FROM $table_name WHERE ID = %d", $snippet_id));
            $snippet_title = Edit::number_duplicate_snippet_title($snippet_title);
            $snippet_title = trim($snippet_title);

            $data = $wpdb->query($wpdb->prepare("INSERT INTO $table_name
                    (snippet_group,
                     snippet_title,
                     snippet_content,
                     snippet_date,
                     snippet_vars,
                     snippet_desc,
                     snippet_status,
                     snippet_shortcode,
                     snippet_php,
                     snippet_wptexturize) 
                     SELECT 
                     snippet_group,
                     '$snippet_title',
                     snippet_content,
                     '$current_time',
                     snippet_vars,
                     snippet_desc,
                     snippet_status,
                     snippet_shortcode,
                     snippet_php,
                     snippet_wptexturize
                     FROM $table_name WHERE ID = %d", $snippet_id));


            if ($data) {

                $snippet_groups = maybe_unserialize($wpdb->get_var($wpdb->prepare("SELECT snippet_group FROM $table_name WHERE ID = %d", $wpdb->insert_id)));

                Edit::change_group_count($snippet_groups, 'increment');

                return true;
            }

        }

        /**
         * Process Bulk Action
         *
         * @return NULL
         */
        private function process_bulk_action()
        {

            $action = $this->current_action();

            if ($action && !empty($_REQUEST['snippets']) && is_array($_REQUEST['snippets'])) {

                check_admin_referer('pspro_all_snippets', 'pspro_all_snippets_nonce');

                if ($action == 'enable') {

                    if ($this->change_snippet_status($_REQUEST['snippets'], 1)) {      //$_REQUEST is taken here directly cuz it will be an array             
                        printf('<div class="notice notice-success is-dismissible"><p>%s..</p></div>', esc_html__('Snippets Activated', 'post-snippets'));
                    } else {
                        printf('<div class="notice notice-error is-dismissible"><p>%s..</p></div>', esc_html__('There has been an Error', 'post-snippets'));
                    }

                } elseif ($action == 'disable') {

                    if ($this->change_snippet_status($_REQUEST['snippets'], 0)) {
                        printf('<div class="notice notice-success is-dismissible"><p>%s..</p></div>', esc_html__('Snippets Deactivated', 'post-snippets'));
                    } else {
                        printf('<div class="notice notice-error is-dismissible"><p>%s..</p></div>', esc_html__('There has been an Error', 'post-snippets'));
                    }

                }

            }

        }

        /**
         * Process Bulk Filter
         * 
         *
         * @return NULL
         */
        private function process_bulk_filter($table_name)
        {

            global $wpdb;

            if (isset($_REQUEST['status_filter_action'])) {

                check_admin_referer('pspro_all_snippets', 'pspro_all_snippets_nonce');

                $group_filter = intval($_REQUEST['group'] ?? 0);
                $status_filter = intval($_REQUEST['status'] ?? 0);

                $wildB = '%\"';
                $wildE = '\"%';
                $find = $group_filter;
                $like = $wildB . $wpdb->esc_like($find) . $wildE;

                if ($group_filter > 0 && $status_filter >= 0) {      //if Both group and Status are selected

                    // return (sprintf( "SELECT * FROM $table_name WHERE snippet_group LIKE '%s' AND snippet_status = $status_filter", $like ) );
                    return $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE snippet_group LIKE '%s' AND snippet_status = $status_filter", $like), ARRAY_A);

                } elseif ($status_filter >= 0) {

                    // return ( ( "SELECT * FROM $table_name WHERE snippet_status = $status_filter") );
                    return $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE snippet_status = %d", $status_filter), ARRAY_A);

                } elseif ($group_filter > 0) {
                    // return (sprintf( "SELECT * FROM $table_name WHERE snippet_group LIKE '%s'", $like ) );
                    return $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE snippet_group LIKE '%s'", $like), ARRAY_A);
                } else {
                    // return "SELECT * FROM $table_name";                
                    return $wpdb->get_results($wpdb->prepare("SELECT * FROM %1s", $table_name), ARRAY_A);
                }
            } else {
                // return "SELECT * FROM $table_name";     //Get all Snippets
                return $wpdb->get_results($wpdb->prepare("SELECT * FROM %1s", $table_name), ARRAY_A);     //Get all Snippets
            }
        }



        /**
         * Process Bulk Download
         * 
         *
         * @return NULL
         */
        private function process_bulk_download()
        {

            if (isset($_REQUEST['psp_download_selected']) && isset($_REQUEST['snippets']) && is_array($_REQUEST['snippets']) && !empty($_REQUEST['snippets'])) {

                check_admin_referer('pspro_all_snippets', 'pspro_all_snippets_nonce');

                $snippets_ids = $_REQUEST['snippets'];

                $snippets_ids = implode(',', $snippets_ids);

                $snippets_ids = "($snippets_ids)";

                $ie = new ImportExport();

                $download_succeed = $ie->exportSnippets($snippets_ids);

                if ($download_succeed) {
                    printf('<div class="notice notice-success is-dismissible"><p>%s..</p></div>', esc_html__('Snippets Downloaded', 'post-snippets'));
                } else {
                    printf('<div class="notice notice-error is-dismissible"><p>%s..</p></div>', esc_html__('There has been an Error', 'post-snippets'));
                }
            }
        }


        /**
         * Process Bulk Upload
         * 
         *
         * @return NULL
         */
        private function process_bulk_upload()
        {

            if (isset($_REQUEST['psp_upload_selected']) && isset($_REQUEST['snippets']) && is_array($_REQUEST['snippets']) && !empty($_REQUEST['snippets'])) {

                check_admin_referer('pspro_all_snippets', 'pspro_all_snippets_nonce');

            }
        }

        public static function get_all_snippets_gutenberg()
        {

            global $wpdb;

            $table_name = $wpdb->prefix . \PostSnippets::TABLE_NAME;

            $all_snippets = $wpdb->get_results($wpdb->prepare("SELECT ID, snippet_title, snippet_vars FROM $table_name WHERE snippet_status = %d AND snippet_php != %d AND snippet_php != %d", 1, 2, 3), ARRAY_A);

            if (!empty($all_snippets)) {

                $snippet_list = array();
                foreach ($all_snippets as $snippet) {
                    if (array_key_exists("ID", $snippet) && array_key_exists("snippet_title", $snippet)) {
                        $snippet_list[$snippet["ID"]] =
                            array(
                                'snippet_title' => $snippet["snippet_title"],
                                'snippet_vars' => Shortcode::filterVars($snippet["snippet_vars"])
                            );
                    }
                }

                return rest_ensure_response($snippet_list);
            }

            return rest_ensure_response(array());

        }

        public static function render_block_content($attributes)
        {

            if (empty($attributes)) {
                return;
            }

            global $wpdb;
            $table_name = $wpdb->prefix . \PostSnippets::TABLE_NAME;
            $atts = array();
            $snippet = '';

            //Backward Compatibility, getting Snippet ID From Name
            if (!isset($attributes["snippetID"]) && isset($attributes["snippet"])) {

                $particular_snippets = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE snippet_title = %s AND snippet_status = 1", $attributes["snippet"]), ARRAY_A);

                if (!empty($particular_snippets)) {

                    $snippet = array();
                    foreach ($particular_snippets as $particular_snippet) {   /**Multiple Snippets of Similar Name (Case Sensitive) */

                        if (strcmp($particular_snippet['snippet_title'], $attributes["snippet"]) == 0 && !empty($particular_snippet)) {
                            $snippet = $particular_snippet;
                            if (isset($attributes['vars']) && !empty($attributes['vars'])) {
                                //for backward compatibility for variables
                                $atts_value = explode("=", $attributes['vars']);
                                if (isset($atts_value[0]) && isset($atts_value[1])) {
                                    $atts[$atts_value[0]] = $atts_value[1];
                                }
                            }
                            break;
                        }
                    }
                }
            } elseif (isset($attributes["snippetID"]) && is_numeric($attributes["snippetID"])) {

                $snippet_id = intval($attributes["snippetID"]);

                $snippet = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE ID = %d AND snippet_status = 1", $snippet_id), ARRAY_A);

                if (!empty($snippet)) {
                    $snippet = $snippet[0];
                }

                $atts = $attributes["snippetVars"];

                if (!empty($atts) || is_array($atts)) {     /**Removing Empty Arrays, so that they get default Vals(snippet_vars) */
                    foreach ($atts as $key => $att) {
                        if (empty($att)) {
                            unset($atts[$key]);
                        }
                    }
                }

            } else {
                return;
            }

            return Shortcode::evaluateSnippet($snippet, $atts);

        }

        public static function get_all_snippets_rest()
        {

            global $wpdb;

            $table_name = $wpdb->prefix . \PostSnippets::TABLE_NAME;

            $all_snippets = $wpdb->get_results($wpdb->prepare("SELECT * FROM %1s", $table_name), ARRAY_A);

            if (!empty($all_snippets)) {

                foreach ($all_snippets as $snippet) {

                    $all_snippets_backward[] = array(

                        'title' => $snippet['snippet_title'],
                        'vars' => $snippet['snippet_vars'],
                        'description' => $snippet['snippet_desc'],
                        'shortcode' => $snippet['snippet_shortcode'],
                        'php' => $snippet['snippet_php'],
                        'wptexturize' => $snippet['snippet_wptexturize'],
                        'snippet' => $snippet['snippet_content'],
                        'ID' => $snippet['ID'],
                        'status' => $snippet['snippet_status'],
                        'group' => $snippet['snippet_group'],
                        'date' => $snippet['snippet_date'],

                    );

                }

                return rest_ensure_response($all_snippets_backward);

            }

            return rest_ensure_response(array('success' => false, 'message' => __('Snippet Not Found.', 'post-snippets')));

        }


        public static function get_particular_snippets_rest($snippet_title)
        {

            if (!empty($snippet_title)) {

                global $wpdb;

                $table_name = $wpdb->prefix . \PostSnippets::TABLE_NAME;

                $wild = '%';
                $find = $snippet_title;
                $snippet_title_like = $wild . $wpdb->esc_like($find) . $wild;

                $particular_snippets_all = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE snippet_title LIKE %s", $snippet_title_like), ARRAY_A);

                foreach ($particular_snippets_all as $particular_snippets) {

                    if (strcmp($particular_snippets['snippet_title'], $snippet_title) == 0 && !empty($particular_snippets)) {

                        $particular_snippet['title'] = $particular_snippets['snippet_title'];
                        $particular_snippet['vars'] = $particular_snippets['snippet_vars'];
                        $particular_snippet['description'] = $particular_snippets['snippet_desc'];
                        $particular_snippet['shortcode'] = $particular_snippets['snippet_shortcode'];
                        $particular_snippet['php'] = $particular_snippets['snippet_php'];
                        $particular_snippet['wptexturize'] = $particular_snippets['snippet_wptexturize'];
                        $particular_snippet['snippet'] = $particular_snippets['snippet_content'];
                        $particular_snippet['ID'] = $particular_snippets['ID'];
                        $particular_snippet['status'] = $particular_snippets['snippet_status'];
                        $particular_snippet['group'] = $particular_snippets['snippet_group'];
                        $particular_snippet['date'] = $particular_snippets['snippet_date'];

                        return rest_ensure_response($particular_snippet);

                    }
                }

                return rest_ensure_response(array('success' => false, 'message' => __('Snippet Not Found.', 'post-snippets')));
            } else {

                return rest_ensure_response(array('success' => false, 'message' => __('Snippet Title Required.', 'post-snippets')));

            }

        }



        public static function delete_snippets_rest($snippet_titles)
        {

            if (!empty($snippet_titles)) {

                global $wpdb;
                $table_name = $wpdb->prefix . \PostSnippets::TABLE_NAME;

                $snippet_titles = explode(",", $snippet_titles);

                $snippet_deleted = false;

                foreach ($snippet_titles as $snippet_title) {

                    $wild = '%';
                    $find = $snippet_title;
                    $snippet_title_like = $wild . $wpdb->esc_like($find) . $wild;

                    $particular_snippets = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE snippet_title LIKE %s", $snippet_title_like), ARRAY_A);

                    foreach ($particular_snippets as $particular_snippet) {

                        if (strcmp($particular_snippet['snippet_title'], $snippet_title) == 0 && !empty($particular_snippet)) {

                            $snippet_groups = maybe_unserialize($particular_snippet['snippet_group']);

                            $snippet_deleted = $wpdb->delete($table_name, array('ID' => $particular_snippet['ID']), array('%d'));

                            if ($snippet_deleted) {

                                if (!empty($snippet_groups)) {  /**It should have atleast one group, the default group, but just in case */

                                    Edit::change_group_count($snippet_groups, 'decrement');

                                }
                            }
                        }
                    }

                }

                if ($snippet_deleted) {
                    return rest_ensure_response(array('success' => true, 'message' => __('Snippet Successfully Deleted.', 'post-snippets')));
                } else {
                    return rest_ensure_response(array('success' => false, 'message' => __('Snippet Not Found.', 'post-snippets')));
                }
            } else {
                return rest_ensure_response(array('success' => false, 'message' => __('Snippet Title Required', 'post-snippets')));
            }

        }


        public static function create_snippet_rest($request)
        {

            global $wpdb;
            $table_name = $wpdb->prefix . \PostSnippets::TABLE_NAME;


            $upgrouped_id = $wpdb->get_var($wpdb->prepare("SELECT ID FROM " . $wpdb->prefix . \PostSnippets::GROUP_TABLE_NAME . " WHERE group_slug = %s", __('ungrouped', 'post-snippets')));
            $group_list = array($upgrouped_id);


            $snippet_title = $request['title'];
            $pattern = '/[\s]/i';   /**remove any WhiteSpaces */
            $replacement = '';
            $snippet_title = preg_replace($pattern, $replacement, $snippet_title);
            $snippet_title = sanitize_text_field($snippet_title);

            $current_snippets_titles = $wpdb->get_results($wpdb->prepare("SELECT snippet_title from %1s", $table_name), ARRAY_A);
            $current_snippets_titles = array_column($current_snippets_titles, "snippet_title");
            if (in_array($snippet_title, $current_snippets_titles)) {
                //duplicate according to settings
                return rest_ensure_response(array('success' => false, 'message' => __('Duplicate Titles are currently not allowed.', 'post-snippets')));

                $snippet_added = true;
            }

            $snippet_added = $wpdb->insert(
                $table_name,
                array(
                    'snippet_group' => maybe_serialize($group_list),
                    'snippet_title' => $snippet_title,
                    'snippet_content' => addslashes($request['snippet_code']),
                    'snippet_date' => current_time('mysql'),
                    'snippet_vars' => $request['vars'],    /**already filtered in rest parameters */
                    'snippet_desc' => sanitize_textarea_field($request['description']),
                    'snippet_status' => 1,
                    'snippet_shortcode' => $request['shortcode'],
                    'snippet_php' => $request['php'],
                    'snippet_wptexturize' => $request['wptexturize'],
                )
            );

            if ($snippet_added) {

                return rest_ensure_response(array('success' => true, 'message' => __('Snippet Successfully Added.', 'post-snippets')));

            } else {
                return rest_ensure_response(array('success' => false, 'message' => __('Could not Add Snippet.', 'post-snippets')));
            }



        }


        public static function update_snippet_rest($request)
        {

            global $wpdb;
            $table_name = $wpdb->prefix . \PostSnippets::TABLE_NAME;

            $wild = '%';
            $find = $request['title'];
            $snippet_title_like = $wild . $wpdb->esc_like($find) . $wild;

            $particular_snippets = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE snippet_title LIKE %s", $snippet_title_like), ARRAY_A);

            if (empty($particular_snippets)) {
                return rest_ensure_response(array('success' => false, 'message' => __('Snippet Not Found.', 'post-snippets')));
            }

            foreach ($particular_snippets as $particular_snippet) {

                if (strcmp($particular_snippet['snippet_title'], $request['title']) == 0 && !empty($particular_snippet)) {
                    $snippet_found = $particular_snippet;
                } else {
                    return rest_ensure_response(array('success' => false, 'message' => __('Snippet Not Found.', 'post-snippets')));
                }

            }

            $snippet_updated = $wpdb->update(
                $table_name,
                array(
                    // 'snippet_group'         => maybe_serialize( $group_list ),
                    // 'snippet_title'         => $snippet_title,
                    // 'snippet_status'        => $request['snippet_status']      ?? 0,     //Disable by default
                    'snippet_content' => addslashes($request['snippet_code']),
                    'snippet_date' => current_time('mysql'),
                    'snippet_vars' => $request['vars'],
                    'snippet_desc' => sanitize_textarea_field($request['description']),
                    'snippet_shortcode' => $request['shortcode'] ?? 0,
                    'snippet_php' => $request['php'] ?? 0,
                    'snippet_wptexturize' => $request['wptexturize'] ?? 0,
                ),
                array(                      /**Where Coulum = ? */
                    'ID' => $snippet_found['ID'],
                ),
                array(                      /**Data Format, %d or %s */
                    /*'%s', '%s', '%d',*/ '%s',
                    '%s',
                    '%s',
                    '%s',
                    '%d',
                    '%d',
                    '%d'
                ),
                array(                      /**Where Format, %d or %s */
                    '%d'
                )
            );


            if ($snippet_updated) {

                return rest_ensure_response(array('success' => true, 'message' => __('Snippet Successfully Updated.', 'post-snippets')));

            } else {
                return rest_ensure_response(array('success' => false, 'message' => __('Could not Update Snippet.', 'post-snippets')));
            }
        }

        public static function get_snippet_php($php)
        {

            if (empty($php)) {
                return 0;
            }

            if (in_array($php, array(0, 1, 2, 3))) {
                return $php;
            }

            return 0;

        }



        public static function run_snippets($snippets)
        {

            if (empty($snippets)) {
                return;
            }

            $script_pattern = "/\<script[\w\s]*\>/i";
            $style_pattern = "/\<style[\w\s]*\>/i";

            foreach ($snippets as $snippet) {

                if ($snippet['snippet_php'] == 2 && !empty($snippet['snippet_content'])) {
                    $snippet_content = stripslashes($snippet['snippet_content']);

                    $tag_exists = preg_match($script_pattern, $snippet_content);

                    if (!$tag_exists) {

                        ?>

                        <script><?php echo $snippet_content; ?></script>

                        <?php
                    } else {
                        // If script tag already exists, sanitize the entire content
                        echo wp_kses($snippet_content, array(
                            'script' => array(
                                'type' => array(),
                                'src' => array(),
                                'async' => array(),
                                'defer' => array(),
                            ),
                        ));
                    }
                } elseif ($snippet['snippet_php'] == 3 && !empty($snippet['snippet_content'])) {
                    $snippet_content = stripslashes($snippet['snippet_content']);
                    // Sanitize CSS content to prevent XSS
                    $snippet_content = wp_kses($snippet_content, array(
                        'style' => array(
                            'type' => array(),
                            'media' => array(),
                        ),
                    ));
                    $tag_exists = preg_match($style_pattern, $snippet_content);

                    if (!$tag_exists) {

                        ?>

                        <style>
                            <?php echo $snippet_content; ?>
                        </style>

                        <?php
                    } else {
                        // If style tag already exists, output sanitized content
                        echo wp_kses($snippet_content, array(
                            'style' => array(
                                'type' => array(),
                                'media' => array(),
                            ),
                        ));
                    }
                }

            }


        }

        public static function run_admin_js_css()
        {

            if (wp_doing_ajax() || isset($_REQUEST['_fs_blog_admin'])) {
                return true;
            }

            global $wpdb;
            $table_name = $wpdb->prefix . \PostSnippets::TABLE_NAME;

            if (is_admin()) {

                $wild = '%';
                $find = 'admin';
                $snippet_var_like = $wild . $wpdb->esc_like($find) . $wild;

                $snippets = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE (snippet_php = %d OR snippet_php = %d) AND snippet_vars LIKE %s AND snippet_status = 1", 2, 3, $snippet_var_like), ARRAY_A);

            }

            if (empty($snippets) || empty(array_filter($snippets))) {
                return;
            }

            self::run_snippets($snippets);


        }

        public static function run_frontend_header_js()
        {

            global $wpdb;
            $table_name = $wpdb->prefix . \PostSnippets::TABLE_NAME;

            $wild = '%';
            $find = 'frontend';
            $snippet_var_like = $wild . $wpdb->esc_like($find) . $wild;
            $location_not_like = 'footer';
            $snippet_var_not_like = $wild . $wpdb->esc_like($location_not_like) . $wild;

            $snippets = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE (snippet_php = %d) AND snippet_status = 1 AND snippet_vars LIKE %s AND snippet_vars NOT LIKE %s", 2, $snippet_var_like, $snippet_var_not_like), ARRAY_A);

            $updated_snippets = self::filter_snippets_for_page($snippets, $location_not_like);

            // echo "<pre>";
            // print_r($updated_snippets);
            // echo "</pre>";

            // die("Debugging");

            self::run_snippets($updated_snippets);

        }

        public static function run_frontend_footer_js_css()
        {

            global $wpdb;
            $table_name = $wpdb->prefix . \PostSnippets::TABLE_NAME;

            $wild = '%';
            $find = 'frontend';
            $snippet_var_like = $wild . $wpdb->esc_like($find) . $wild;
            $location_not_like = 'header';
            $snippet_var_not_like = $wild . $wpdb->esc_like($location_not_like) . $wild;

            $snippets = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE (snippet_php = %d OR snippet_php = %d) AND snippet_status = 1 AND snippet_vars LIKE %s AND snippet_vars NOT LIKE %s", 2, 3, $snippet_var_like, $snippet_var_not_like), ARRAY_A);

            $updated_snippets = self::filter_snippets_for_page($snippets, $location_not_like);

            // echo "<pre>";
            // print_r($updated_snippets);
            // echo "</pre>";

            // die("Debugging");

            self::run_snippets($updated_snippets);


        }


        public static function filter_snippets_for_page($snippets, $location = 'header')
        {

            if (empty($snippets)) {
                return;
            }

            $updated_snippets = array();

            foreach ($snippets as $snippet) {

                $snippets_vars = Shortcode::filterVars($snippet["snippet_vars"]);
                $snippets_vars_keys = array_keys($snippets_vars);

                if (in_array($location, $snippets_vars_keys) || !in_array('frontend', $snippets_vars_keys)) {
                    continue;
                }

                if (in_array('all_website', $snippets_vars_keys)) {
                    $updated_snippets[] = $snippet;
                }

                if (is_front_page() || is_home()) {

                    if (in_array('homepage', $snippets_vars_keys)) {
                        $updated_snippets[] = $snippet;
                    }
                }

                if (is_page()) {
                    if (in_array('all_pages', $snippets_vars_keys)) {
                        $updated_snippets[] = $snippet;
                    }
                }

                if (is_single()) {
                    if (in_array('all_posts', $snippets_vars_keys)) {
                        $updated_snippets[] = $snippet;
                    }
                }

                if (in_array('specific_page', $snippets_vars_keys)) {

                    $specific_page = $snippets_vars['specific_page'] ?? '';

                    if (!empty($specific_page) && is_numeric($specific_page) && (is_page($specific_page) || is_single($specific_page))) {

                        $updated_snippets[] = $snippet;

                    }
                }

            }

            return $updated_snippets;
        }
    }
}