<?php
if ( ! defined( 'ABSPATH' ) ) exit;
// phpcs:disable WordPress.Security.NonceVerification -- read-only list table; capability check handled by admin menu registration
// phpcs:disable WordPress.Security.ValidatedSanitizedInput -- GET/POST params cast to int or sanitized with absint/sanitize_key
require_once (ABSPATH . 'wp-admin/includes/class-wp-list-table.php');

class ScholarSync_ArticlesListTableClass extends WP_List_Table {

    const PER_PAGE = 10;
    private $author_id;
    private $author_name   = '';
    private $co_author_map = array();
    private $search_term   = '';

    public function get_search_term() {
        return $this->search_term;
    }

    public function __construct() {
        parent::__construct( array(
            'singular' => 'article',
            'plural'   => 'articles',
            'ajax'     => false,
        ) );
    }

    public function prepare_items() {
        $this->author_id = isset( $_GET['author-id'] ) ? absint( wp_unslash( $_GET['author-id'] ) ) : 0;
        if (empty($this->author_id)) {
            wp_die( esc_html__( 'Error - author id is missing', 'scholar-sync' ) );
        }

        global $wpdb;
        $this->author_name = (string) $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $wpdb->prepare( 'SELECT name FROM %i WHERE author_id = %d', SCHOLAR_SYNC_DB_AUTHORS, (int) $this->author_id ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- %i is the WordPress identifier placeholder (WP 6.2+)
        );
        $co_rows = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $wpdb->prepare( 'SELECT co_author_id, short_name, full_name FROM %i', SCHOLAR_SYNC_DB_CO_AUTHORS ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- %i is the WordPress identifier placeholder (WP 6.2+); no user input
        );
        foreach ( $co_rows as $row ) {
            $id = (int) $row->co_author_id;
            $this->co_author_map[ strtolower( trim( $row->short_name ) ) ] = $id;
            $this->co_author_map[ strtolower( trim( $row->full_name ) )  ] = $id;
        }

        $order_by    = isset( $_GET['orderby'] ) ? sanitize_text_field( wp_unslash( $_GET['orderby'] ) ) : '';
        $order       = isset( $_GET['order'] )   ? sanitize_text_field( wp_unslash( $_GET['order'] ) )   : '';
        // $_REQUEST (not just $_POST) so the search term also survives when carried
        // forward as a GET param — e.g. through the delete-article redirect below.
        $this->search_term = isset( $_REQUEST['s'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ) : '';
        $records = $this->get_table_data($this->author_id, $order_by, $order,  $this->search_term);

        $this->set_pagination_args(array(
            'total_items' => count($records),
            'per_page' => self::PER_PAGE,
        ));
        $this->items = array_slice($records, ($this->get_pagenum() - 1) * self::PER_PAGE, self::PER_PAGE);

        $columns = $this->get_columns();
        $hidden_columns = $this->get_hidden_columns();
        $sortable_columns = $this->get_sortable_columns();
        $this->_column_headers = array($columns, $hidden_columns, $sortable_columns);

    }

    public function get_table_data($author_id, $order_by = '', $order = '', $search_term = '') {
        global $wpdb;

        $allowed_orderby = array('title', 'year', 'cited_by_value');
        $allowed_order   = array('ASC', 'DESC');
        $safe_orderby = in_array($order_by, $allowed_orderby, true) ? $order_by : '';
        $safe_order   = in_array(strtoupper($order), $allowed_order, true) ? strtoupper($order) : 'ASC';
        $data = array();
        $table_name = SCHOLAR_SYNC_DB_ARTICLES;

        // ORDER BY is built only from allowlisted values: the column is passed as a %i
        // identifier placeholder and the direction is a hardcoded ASC/DESC literal, so no
        // value is ever interpolated into the SQL string.
        if ( ! empty( $search_term ) ) {
            $like = '%' . $wpdb->esc_like( $search_term ) . '%';
            if ( $safe_orderby === '' ) {
                $results = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
                    $wpdb->prepare( "SELECT * FROM %i WHERE author_id = %d AND is_active = 1 AND CONCAT_WS(' ', title, authors) LIKE %s", $table_name, $author_id, $like )
                );
            } elseif ( $safe_order === 'ASC' ) {
                $results = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
                    $wpdb->prepare( "SELECT * FROM %i WHERE author_id = %d AND is_active = 1 AND CONCAT_WS(' ', title, authors) LIKE %s ORDER BY %i ASC", $table_name, $author_id, $like, $safe_orderby )
                );
            } else {
                $results = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
                    $wpdb->prepare( "SELECT * FROM %i WHERE author_id = %d AND is_active = 1 AND CONCAT_WS(' ', title, authors) LIKE %s ORDER BY %i DESC", $table_name, $author_id, $like, $safe_orderby )
                );
            }
        } else {
            if ( $safe_orderby === '' ) {
                $results = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
                    $wpdb->prepare( "SELECT * FROM %i WHERE author_id = %d AND is_active = 1", $table_name, $author_id )
                );
            } elseif ( $safe_order === 'ASC' ) {
                $results = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
                    $wpdb->prepare( "SELECT * FROM %i WHERE author_id = %d AND is_active = 1 ORDER BY %i ASC", $table_name, $author_id, $safe_orderby )
                );
            } else {
                $results = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
                    $wpdb->prepare( "SELECT * FROM %i WHERE author_id = %d AND is_active = 1 ORDER BY %i DESC", $table_name, $author_id, $safe_orderby )
                );
            }
        }

        foreach ($results as $result) {
            $data[] = array(
                "article_id" => $result->article_id,
                "title" => $result->title,
                "link" => $result->link,
                "authors" => $result->authors,
                "cite" => $result->cited_by_value,
                "year" => $result->year,
                "publication" => $result->publication,
                "image_url" => $result->image_url
            );
        }

        return $data;
    }

    public function get_hidden_columns() {
        // option to hide columns
        return array();
    }

    public function get_sortable_columns() {
        return array(
            "title" => array("title", false),
            "year"  => array("year", false),
            "cite"  => array("cited_by_value", false)
        );
    }

    public function get_bulk_actions() {
        return array(
//            'edit' => 'Edit X',
            'delete-article' => 'Delete'
        );
    }


    public function display() {
        parent::display();
    }

    public function get_columns() {
        return array(
            'cb' => '<input type="checkbox" />',
            'title' => 'Title',
            'authors' => 'Authors',
            'year' => 'Year',
            'cite' => 'Citations',
            'publication' => 'Publication'
        );
    }

    public function column_default( $item, $column_name ) {
        switch ($column_name) {
            case "article_id":
            case "title":
//                return sprintf('<a target="_blank" href="%s">%s</a>', $item['link'], $item['title']);
            case "year":
            case "cite":
            case "publication":
                return $item[$column_name];
            case "authors":
                return $this->render_authors_cell( $item['authors'] );
            default:
                return "not found";
        }
    }

    private function render_authors_cell( $authors_str ) {
        if ( empty( $authors_str ) ) { return ''; }

        $parts = array();
        foreach ( explode( ',', $authors_str ) as $token ) {
            $trimmed = trim( $token );
            if ( $trimmed === '' ) {
                $parts[] = '';
                continue;
            }
            $lower = strtolower( $trimmed );

            if ( $this->author_name && strcasecmp( $trimmed, $this->author_name ) === 0 ) {
                $parts[] = '<strong>' . esc_html( $trimmed ) . '</strong>';
                continue;
            }

            if ( isset( $this->co_author_map[ $lower ] ) ) {
                $co_url  = add_query_arg( array(
                    'page'         => 'scholar-sync-co-authors-slug',
                    'action'       => 'edit',
                    'co-author-id' => $this->co_author_map[ $lower ],
                ), admin_url( 'admin.php' ) );
                $parts[] = '<a href="' . esc_url( $co_url ) . '">' . esc_html( $trimmed ) . '</a>';
                continue;
            }

            $parts[] = esc_html( $trimmed );
        }

        return implode( ', ', $parts );
    }


    public function column_cb($item) {
        return sprintf('<input type="checkbox" name="post[]" value="%s" />', esc_attr($item['article_id']));
    }

    public function column_title($item) {
        $actions = array(
            'edit' => sprintf('<a href="?page=%s&article-action=add-article&tab=1&author-id=%s&article-id=%s&title=%s&link=%s&authors=%s&publication=%s&cite=%s&year=%s">Edit</a>',
                'scholar-sync-authors-slug', esc_attr($this->author_id), esc_attr($item['article_id']), esc_attr($item['title']), esc_url($item['link'])
                , esc_attr($item['authors']), esc_attr($item['publication']), esc_attr($item['cite']), esc_attr($item['year'])),
            'delete' => sprintf('<a href="%s" style="color:#b32d2e;">Delete</a>',
                esc_url(wp_nonce_url(
                    add_query_arg( array( 'page' => 'scholar-sync-actions-slug', 'action' => 'delete-article', 'author-id' => $this->author_id, 'article-id' => $item['article_id'], 's' => $this->search_term ), admin_url('admin.php') ),
                    'scholar_sync_delete_article'
                ))),
            'duplicate' => sprintf('<a href="?page=%s&article-action=add-article&tab=1&author-id=%s&title=%s&link=%s&authors=%s&publication=%s&cite=%s&year=%s&article-image=%s">Duplicate</a>',
                'scholar-sync-authors-slug', esc_attr($this->author_id), esc_attr($item['title']), esc_url($item['link'])
                , esc_attr($item['authors']), esc_attr($item['publication']), esc_attr($item['cite']), esc_attr($item['year'])
                , esc_attr(rawurlencode((string) ($item['image_url'] ?? '')))),
        );
        return sprintf('%1$s %2$s', esc_html($item['title']), $this->row_actions($actions));
    }
}
