<?php

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

/**
 * Class Wpil_Table_Domain
 */
class Wpil_Table_Keyword extends WP_List_Table
{
    private $prepared_page = 1;
    private $prepared_per_page = 20;

    function get_columns()
    {
        $cols = array(
            'checkbox' => '<input type="checkbox" id="wpil_check_all_keywords" style="margin:0px;" />',
            'keyword' => 'Keyword',
            'link' => 'Link',
        );

        $options = get_user_meta(get_current_user_id(), 'wpil_keyword_options', true);
        $select_links_active = Wpil_Keyword::keywordLinkSelectActive();

        if($select_links_active && (empty($options) || isset($options['hide_select_links_column']) && $options['hide_select_links_column'] === 'off')){
            $cols['select_links'] = 'Possible Links';
        }

        $cols['links'] = 'Links Added';
        $cols['actions'] = '';

        return $cols;
    }

    function prepare_items($args = array())
    {
        if(!defined('WPIL_LOADING_REPORT')){
            define('WPIL_LOADING_REPORT', true);
        }

        $options = get_user_meta(get_current_user_id(), 'wpil_keyword_options', true);

        if(!empty($args['per_page'])){
            $per_page = (int)$args['per_page'];
        }elseif(!empty($options) && isset($options['per_page'])){
            $per_page = intval($options['per_page']);
        }else{
            $per_page = 20;
        }

        if(empty($per_page)){
            $per_page = 20;
        }

        $page = !empty($args['page']) ? (int)$args['page'] : (isset($_REQUEST['paged']) ? (int)$_REQUEST['paged'] : 1);
        $search = isset($args['search']) ? $args['search'] : (!empty($_GET['s']) ? $_GET['s'] : '');
        $orderby = isset($args['orderby']) ? $args['orderby'] : (isset($_REQUEST['orderby']) ? $_REQUEST['orderby'] : '');
        $order = isset($args['order']) ? $args['order'] : (isset($_REQUEST['order']) ? $_REQUEST['order'] : '');

        if(empty($page) && empty($search) && empty($orderby) && empty($order)){
            Wpil_Telemetry::log_event('report_open_autolinking');
        }

        $columns = $this->get_columns();
        $hidden = [];
        $sortable = $this->get_sortable_columns();
        $this->_column_headers = [$columns, $hidden, $sortable];
        $data = Wpil_Keyword::getData($per_page, $page, $search, $orderby, $order);

        $total_pages = (!empty($data['total'])) ? (int)ceil($data['total'] / $per_page) : 1;
        if($page > $total_pages){
            $page = $total_pages;
            $data = Wpil_Keyword::getData($per_page, $page, $search, $orderby, $order);
        }

        $this->items = $data['keywords'];
        $this->prepared_page = $page;
        $this->prepared_per_page = $per_page;

        $this->set_pagination_args(array(
            'total_items' => $data['total'],
            'per_page' => $per_page,
            'total_pages' => max(1, (int)ceil($data['total'] / $per_page))
        ));
    }

    public function get_total_item_count(){
        return !empty($this->_pagination_args['total_items']) ? (int)$this->_pagination_args['total_items'] : 0;
    }

    public function get_current_keyword_page(){
        return $this->prepared_page;
    }

    public function get_current_per_page(){
        return $this->prepared_per_page;
    }

    public static function get_table_display_data($args = array()){
        $table = new self();
        $table->prepare_items($args);

        ob_start();
        $table->display();
        $table_html = ob_get_clean();

        return array(
            'table_html' => $table_html,
            'total' => $table->get_total_item_count(),
            'page' => $table->get_current_keyword_page(),
            'per_page' => $table->get_current_per_page(),
            'next_batch_ids' => Wpil_Keyword::getDeleteBatchIdsFromKeywords($table->items)
        );
    }

    function column_default($item, $column_name)
    {
        switch($column_name) {
            case 'checkbox':
                $link_count = !empty($item->links) ? count($item->links): 0;
                return '<input type="checkbox" class="wpil-autolink-rule-select-checkbox" data-id="' . $item->id . '" data-link-count="' . $link_count . '" />';
            case 'keyword':
                $terms = Wpil_Term::getAllCategoryTerms();
                $term_selector = '';
                if(!empty($terms)){
                    // get any restricted terms
                    $restricted_cats = explode(',', $item->restricted_cats);
                    // build the tax cache
                    $tax_cache = array();
                    foreach($terms as $term){
                        if(!isset($tax_cache[$term->taxonomy])){
                            $tax_cache[$term->taxonomy] = get_taxonomy($term->taxonomy);
                        }
                    }

                    // build the term options
                    $cat_options = '';
                    $tag_options = '';
                    foreach($terms as $term){
                        if(isset($tax_cache[$term->taxonomy]) && !empty($tax_cache[$term->taxonomy]) && $tax_cache[$term->taxonomy]->hierarchical){
                            $cat_options .= '<li>
                                    <input type="hidden" name="wpil_keywords_restrict_term_' . $term->term_taxonomy_id . '" value="0" />
                                    <input type="checkbox" class="wpil-restrict-keywords-input" name="wpil_keywords_restrict_term_' . $term->term_taxonomy_id . '" ' . (in_array($term->term_taxonomy_id, $restricted_cats)?'checked':'') . ' data-term-id="' . $term->term_taxonomy_id . '">' . esc_html($term->name) . '</li>';
                        }else{
                            $tag_options .= '<li>
                                    <input type="hidden" name="wpil_keywords_restrict_term_' . $term->term_taxonomy_id . '" value="0" />
                                    <input type="checkbox" class="wpil-restrict-keywords-input" name="wpil_keywords_restrict_term_' . $term->term_taxonomy_id . '" ' . (in_array($term->term_taxonomy_id, $restricted_cats)?'checked':'') . ' data-term-id="' . $term->term_taxonomy_id . '">' . esc_html($term->name) . '</li>';
                            }
                    }

                    $term_selector ='
                    <div class="wpil_keywords_restrict_to_cats_container">
                        <input type="hidden" name="wpil_keywords_restrict_to_cats" value="0" />
                        <input type="checkbox" class="wpil_keywords_restrict_to_cats" name="wpil_keywords_restrict_to_cats" ' . (!empty($item->restrict_cats)?'checked':'') . ' value="1" />
                        <label for="wpil_keywords_restrict_to_cats">' . __('Restrict autolinks to specific categories or tags?', 'wpil') . '</label>
                        <span class="wpil-keywords-restrict-cats-show"></span>
                    </div>';

                    $term_selector .= '<ul class="wpil-keywords-restrict-cats" style="display:none;">';
                    $term_selector .= '<li>' . __('Available Categories:', 'wpil') . '</li>';
                    $term_selector .= $cat_options;
                    $term_selector .= '</ul>';
                    $term_selector .= '<br />';

                    $term_selector .= '<ul class="wpil-keywords-restrict-cats" style="display:none;">';
                    $term_selector .= '<li>' . __('Available Tags:', 'wpil') . '</li>';
                    $term_selector .= $tag_options;
                    $term_selector .= '</ul>';
                    $term_selector .= '<br />';
                }

                $date_restricted = (!empty($item->restrict_date) && !empty($item->restricted_date));

                return '<div class="wpil-autolink-rule-keyword">' . esc_html(stripslashes($item->$column_name)) . '<i class="dashicons dashicons-admin-generic"></i></div>
                        <div class="local_settings">
                            <div class="block" data-id="' . $item->id . '">
                                <input type="hidden" name="wpil_keywords_add_same_link" value="0" />
                                <input type="checkbox" name="wpil_keywords_add_same_link" ' . ($item->add_same_link==1?'checked':'') . ' value="1" />
                                <label for="wpil_keywords_add_same_link">' . __('Add link if post already has this link?', 'wpil') . '</label>
                                <br>
                                <input type="hidden" name="wpil_keywords_link_once" value="0" />
                                <input type="checkbox" name="wpil_keywords_link_once" ' . ($item->link_once==1?'checked':'') . ' value="1" />
                                <label for="wpil_keywords_link_once">' . __('Only link once per post', 'wpil') . '</label>
                                <br>
                                <input type="hidden" name="wpil_keywords_restrict_to_live" value="0" />
                                <input type="checkbox" name="wpil_keywords_restrict_to_live" ' . (isset($item->restrict_to_live) && $item->restrict_to_live==1?'checked':'') . ' value="1" />
                                <label for="wpil_keywords_restrict_to_live">' . __('Only create internal links when target is published?', 'wpil') . '</label>
                                <br>
                                <input type="hidden" name="wpil_keywords_force_insert" value="0" />
                                <input type="checkbox" name="wpil_keywords_force_insert" ' . ($item->force_insert==1?'checked':'') . ' value="1" />
                                <label for="wpil_keywords_force_insert">' . __('Override "One Link per Sentence" rule?', 'wpil') . '</label>
                                <div class="wpil_help" style="display: inline-block; float:none; height: 5px;">
                                    <i class="dashicons dashicons-editor-help" style="font-size: 20px; color: #444; margin: 2px 0 8px;"></i>
                                    <div>' . __('By default, Link Whisper only inserts one link per sentence. If a sentence already has a link, Link Whisper won\'t add another one to it. This option allows you to override the rule so autolinks can be inserted in sentences that already have links.', 'wpil') . '</div>
                                </div>
                                <br>
                                <input type="hidden" name="wpil_keywords_limit_inserts" value="0" />
                                <input type="checkbox" name="wpil_keywords_limit_inserts" class="wpil_keywords_limit_inserts_checkbox" ' . (isset($item->limit_inserts) && $item->limit_inserts==1?'checked':'') . ' value="1" />
                                <label for="wpil_keywords_limit_inserts">' . __('Limit how many autolinks are created?', 'wpil') . '</label>
                                <div class="wpil_help" style="display: inline-block; float:none; height: 5px;">
                                    <i class="dashicons dashicons-editor-help" style="font-size: 20px; color: #444; margin: 2px 0 8px;"></i>
                                    <div>' . __('Setting a limit for how many autolinks are created will tell Link Whisper how many times an autolink should be inserted on the site. Once the limit is reached, Link Whisper will stop inserting the rule\'s links. But if a link is deleted, Link Whisper will insert another link somewhere to bring the total back up to the limit.', 'wpil') . '</div>
                                </div>
                                <div class="wpil_keywords_insert_limit_container" style="' . (isset($item->limit_inserts) && $item->limit_inserts==1?'display:block;':''). '">
                                    <input type="number" style="max-width: 60px;" name="wpil_keywords_insert_limit" min="0" value="'. ((isset($item->insert_limit) && !empty($item->insert_limit)) ? $item->insert_limit : 0) .'" step="1"/>
                                </div>
                                <br>
                                <input type="hidden" name="wpil_keywords_select_links" value="0" />
                                <input type="checkbox" name="wpil_keywords_select_links" ' . ($item->select_links==1?'checked':'') . ' value="1" />
                                <label for="wpil_keywords_select_links">Select links before inserting?</label>
                                <br>
                                <input type="hidden" name="wpil_keywords_set_priority" value="0" />
                                <input type="checkbox" name="wpil_keywords_set_priority" class="wpil_keywords_set_priority_checkbox" ' . ($item->set_priority==1?'checked':'') . ' value="1" />
                                <label for="wpil_keywords_set_priority">' . __('Set priority for auto link insertion?', 'wpil') . '</label>
                                <div class="wpil_help" style="display: inline-block; float:none; height: 5px;">
                                    <i class="dashicons dashicons-editor-help" style="font-size: 20px; color: #444; margin: 2px 0 8px;"></i>
                                    <div>' . __('Setting a priority for the auto link will tell Link Whisper which link to insert if it comes across a sentence that has keywords that match multiple auto links. The auto link with the highest priority will be the one inserted in such a case.', 'wpil') . '</div>
                                </div>
                                <div class="wpil_keywords_priority_setting_container" style="' . ($item->set_priority==1?'display:block;':''). '">
                                    <input type="number" style="max-width: 60px;" name="wpil_keywords_priority_setting" min="0" value="'. ((isset($item->priority_setting) && !empty($item->priority_setting)) ? $item->priority_setting : 0) .'" step="1"/>
                                </div>
                                <br>
                                <input type="hidden" name="wpil_keywords_prioritize_longtail" value="0" />
                                <input type="checkbox" name="wpil_keywords_prioritize_longtail"' . (isset($item->prioritize_longtail) && $item->prioritize_longtail==1?'checked':'') . ' value="1" />
                                <label for="wpil_keywords_prioritize_longtail">' . __('Prioritize long-tail autolinks?', 'wpil') . '</label>
                                <div class="wpil_help" style="display: inline-block; float:none; height: 5px;">
                                    <i class="dashicons dashicons-editor-help" style="font-size: 20px; color: #444; margin: 2px 0 8px;"></i>
                                    <div>' . __('Prioritizing long-tail autolinks will tell Link Whisper to prefer inserting long keyword autolinks to short ones. So "The best shoes in the world" would be preferred to "Best Shoes" since it\'s longer.', 'wpil') . '</div>
                                </div>
                                <br>
                                <input type="hidden" name="wpil_keywords_restrict_date" value="0" />
                                <input type="checkbox" id="wpil_keywords_restrict_date_' . $item->id . '" name="wpil_keywords_restrict_date" class="wpil_keywords_restrict_date_checkbox" ' . ($item->restrict_date==1?'checked':'') . ' value="1" />
                                <label for="wpil_keywords_restrict_date_' . $item->id . '">' . __('Only add links to posts published after the given date', 'wpil') . '</label>
                                <div class="wpil_keywords_restricted_date_container" ' . (($date_restricted) ? 'style="display:block;"' : ''). '>
                                    <input type="date" name="wpil_keywords_restricted_date" ' . ((!empty($item->restricted_date)) ? 'value="' . str_replace(' 00:00:00', '', $item->restricted_date) . '"': '') . '/>
                                </div>
                                <br>
                                <input type="hidden" name="wpil_keywords_case_sensitive" value="0" />
                                <input type="checkbox" id="wpil_keywords_case_sensitive_' . $item->id . '" name="wpil_keywords_case_sensitive" class="wpil_keywords_case_sensitive_checkbox" ' . ($item->case_sensitive==1?'checked':'') . ' value="1" />
                                <label for="wpil_keywords_case_sensitive_' . $item->id . '">' . __('Make Keyword case sensitive', 'wpil') . '</label>
                                <br>
                                <input type="hidden" name="wpil_keywords_same_lang" value="0" />
                                <input type="checkbox" id="wpil_keywords_same_lang_' . $item->id . '" name="wpil_keywords_same_lang" class="wpil_keywords_case_same_lang" ' . (isset($item->same_lang) && $item->same_lang==1?'checked':'') . ' value="1" />
                                <label for="wpil_keywords_same_lang_' . $item->id . '">' . __('Restrict autolinks to target page\'s language', 'wpil') . '</label>
                                <br>
                                ' . $term_selector . '
                                <a href="javascript:void(0)" class="button-primary wpil_keyword_local_settings_save" data-id="' . $item->id . '">Save</a>
                            </div>
                            <div class="progress_panel loader">
                                <div class="progress_count"></div>
                            </div>
                        </div>';
            case 'link':
                return esc_html($item->$column_name);
            case 'select_links':
                $possible_links = Wpil_Keyword::getPossibleLinksByKeyword($item->id, 100);
                $total_possible_links = Wpil_Keyword::getPossibleLinkCountByKeyword($item->id);
                $data = array(
                    'keyword_id' => $item->id,
                    'keyword' => $item->keyword,
                    'report_type' => 'autolinks',
                    'dropdown_type' => 'select-links',
                    'nonce' => wp_create_nonce(wp_get_current_user()->ID . 'wpil-collapsible-nonce')
                );
                ob_start();
                include WP_INTERNAL_LINKING_PLUGIN_DIR . '/templates/blocks/collapsible_select_keywords.php';
                return ob_get_clean();
            case 'links':
                $links = $item->$column_name;
                $data = array(
                    'keyword_id' => $item->id,
                    'keyword' => $item->keyword,
                    'report_type' => 'autolinks',
                    'dropdown_type' => 'links',
                    'nonce' => wp_create_nonce(wp_get_current_user()->ID . 'wpil-collapsible-nonce')
                );
                ob_start();
                include WP_INTERNAL_LINKING_PLUGIN_DIR . '/templates/blocks/collapsible_posts.php';
                return ob_get_clean();
            case 'actions':
                return '<a href="javascript:void(0)" class="delete" data-id="' . $item->id . '" title="Autolink ID: ' . $item->id . '">Delete</a>';
            default:
                return print_r($item, true);
        }
    }

    function get_sortable_columns()
    {
        return [
            'keyword' => ['keyword', false],
            'link' => ['link', false],
            'links' => ['links', false],
        ];
    }

    /**
     * Generates the columns for a single row of the table.
     *
     * @since 3.1.0
     *
     * @param object $item The current item.
     */
    protected function single_row_columns( $item ) {
        list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();

        foreach ( $columns as $column_name => $column_display_name ) {
            $classes = "$column_name column-$column_name";
            if ( $primary === $column_name ) {
                $classes .= ' has-row-actions column-primary';
            }

            if ( in_array( $column_name, $hidden, true ) ) {
                $classes .= ' hidden';
            }
 
            if(in_array($column_name, array('select_links', 'links'), true)){
                $classes .= ' wpil-dropdown-column';
            }

            // Comments column uses HTML in the display name with screen reader text.
            // Instead of using esc_attr(), we strip tags to get closer to a user-friendly string.
            $data = 'data-colname="' . wp_strip_all_tags( $column_display_name ) . '"';
 
            $attributes = "class='$classes' $data";
 
            if ( 'cb' === $column_name ) {
                echo '<th scope="row" class="check-column">';
                echo $this->column_cb( $item );
                echo '</th>';
            } elseif ( method_exists( $this, '_column_' . $column_name ) ) {
                echo call_user_func(
                    array( $this, '_column_' . $column_name ),
                    $item,
                    $classes,
                    $data,
                    $primary
                );
            } elseif ( method_exists( $this, 'column_' . $column_name ) ) {
                echo "<td $attributes>";
                echo call_user_func( array( $this, 'column_' . $column_name ), $item );
                echo $this->handle_row_actions( $item, $column_name, $primary );
                echo '</td>';
            } else {
                echo "<td $attributes>";
                echo $this->column_default( $item, $column_name );
                echo $this->handle_row_actions( $item, $column_name, $primary );
                echo '</td>';
            }
        }
    }
}
