<?php

class ScholarSync_Public
{

    /**
     * The ID of this plugin.
     *
     * @since    1.0.0
     * @access   private
     * @var      string $plugin_name The ID of this plugin.
     */
    private $plugin_name;

    /**
     * The version of this plugin.
     *
     * @since    1.0.0
     * @access   private
     * @var      string $version The current version of this plugin.
     */
    private $version;

    /**
     * Initialize the class and set its properties.
     *
     * @param string $plugin_name The name of the plugin.
     * @param string $version The version of this plugin.
     * @since    1.0.0
     */
    public function __construct($plugin_name, $version)
    {

        $this->plugin_name = $plugin_name;
        $this->version = $version;
    }


    /**
     * Register the stylesheets for the public-facing side of the site.
     *
     * @since    1.0.0
     */
    public function enqueue_styles()
    {

        wp_enqueue_style($this->plugin_name, plugin_dir_url(__FILE__) . 'css/scholar-sync-public.css', array(), $this->version, 'all');
    }

    /**
     * Register the JavaScript for the public-facing side of the site.
     *
     * @since    1.0.0
     */
    public function enqueue_scripts()
    {
        // Shared pagination widget (small, always enqueued).
        wp_enqueue_script(
            'scholar-sync-pagination',
            plugin_dir_url( __FILE__ ) . 'js/scholar-sync-pagination.js',
            array( 'jquery' ),
            $this->version,
            true
        );
        wp_localize_script( 'scholar-sync-pagination', 'scholar_sync_public_object',
            array(
                'site_url'   => SCHOLAR_SYNC_SITE_URL,
                'rest'       => rest_url( 'sclr/v1/' ),
                'rest_nonce' => wp_create_nonce('wp_rest'),
                'user_id'    => get_current_user_id(),
                'plugin_url' => SCHOLAR_SYNC_PLUGIN_URL,
            )
        );

        // Shared article-card helpers — registered here; auto-enqueued as dependency of scholar-sync-group-public.
        wp_register_script(
            'scholar-sync-article-card',
            plugin_dir_url( __FILE__ ) . 'js/scholar-sync-article-card.js',
            array( 'jquery' ),
            $this->version,
            true
        );

        global $post;
        if ( is_singular() && $post instanceof WP_Post ) {
            // Author display JS — only on pages using [scholar-sync-scholar].
            if ( has_shortcode( $post->post_content, 'scholar-sync-scholar' ) ) {
                wp_enqueue_script(
                    'scholar-sync-author-display',
                    plugin_dir_url( __FILE__ ) . 'js/scholar-sync-author-display.js',
                    array( 'jquery', 'scholar-sync-pagination', 'scholar-sync-article-card' ),
                    $this->version,
                    true
                );
            }
            // Group rendering JS — only on pages using [scholar-sync-group].
            if ( has_shortcode( $post->post_content, 'scholar-sync-group' ) ) {
                wp_enqueue_script(
                    'scholar-sync-group-public',
                    plugin_dir_url( __FILE__ ) . 'js/scholar-sync-group-public.js',
                    array( 'jquery', 'scholar-sync-pagination', 'scholar-sync-article-card' ),
                    $this->version,
                    true
                );
            }
        }

    }


    public function manage_shortcode_author($atts)
    {
        $author_id = '';
        if (isset($atts['id'])) {
            $author_id = trim($atts['id']);
        } else if (isset($_GET['author-id'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- public shortcode reads author-id for display only
            $author_id = absint( wp_unslash( $_GET['author-id'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        }

        $header      = !(isset($atts['header'])      && $atts['header']      == '0');
        $search      = !(isset($atts['search'])      && $atts['search']      == '0');
        $cited_by    = !(isset($atts['cited-by'])    && $atts['cited-by']    == '0');
        $co_authors  = !(isset($atts['co-authors'])  && $atts['co-authors']  == '0');
        $co_author_photos = !(isset($atts['co-author-photos']) && $atts['co-author-photos'] == '0');
        $image_shape  = isset($atts['image_shape']) ? sanitize_key($atts['image_shape']) : 'circle';
        $image_shadow = !(isset($atts['shadow']) && $atts['shadow'] == '0');
        $article_image = !(isset($atts['article-image']) && $atts['article-image'] == '0');
        $sort_by = isset($atts['sort_by']) ? sanitize_key($atts['sort_by']) : '';

        require_once SCHOLAR_SYNC_PLUGIN_DIR . '/includes/class-scholar-sync-author-display.php';

        $author = new ScholarSync_Author_Display($author_id, $header, $search, $cited_by, $co_authors, $image_shape, $image_shadow, $article_image, $co_author_photos, $sort_by);
        return $author->display();
    }

    public function manage_shortcode_group( $atts ) {
        $atts = shortcode_atts( array(
            'id'           => 0,
            'columns'      => '',
            'image_shape'  => '',
            'show_text'    => '', // legacy combined toggle; kept for backward compatibility with existing embeds
            'shadow'       => '',
            'cited-by'     => '',
            'co-authors'   => '',
            'co-author-photos' => '',
            'article-image' => '',
            'target_page'  => '',
            'search'       => '1',
            'sort_by'      => '',
            'show_position'     => '',
            'show_institution'  => '',
            'show_tags'         => '',
            'max_tags'          => '',
            'show_publications' => '',
            'show_profile_link' => '',
            'per_page'          => '',
        ), $atts, 'scholar-sync-group' );

        $group_id = (int) $atts['id'];
        if ( ! $group_id ) {
            return '';
        }

        $data = 'data-group-id="' . esc_attr( $group_id ) . '"';
        if ( $atts['columns'] !== '' ) {
            $data .= ' data-columns="' . esc_attr( (int) $atts['columns'] ) . '"';
        }
        if ( $atts['image_shape'] !== '' ) {
            $data .= ' data-image-shape="' . esc_attr( $atts['image_shape'] ) . '"';
        }
        if ( $atts['show_text'] !== '' ) {
            $data .= ' data-show-text="' . esc_attr( $atts['show_text'] ) . '"';
        }
        if ( $atts['shadow'] !== '' ) {
            $data .= ' data-shadow="' . esc_attr( $atts['shadow'] ) . '"';
        }
        if ( $atts['cited-by'] === '0' ) {
            $data .= ' data-cited-by="0"';
        }
        if ( $atts['co-authors'] === '0' ) {
            $data .= ' data-co-authors="0"';
        }
        if ( $atts['co-author-photos'] === '0' ) {
            $data .= ' data-co-author-photos="0"';
        }
        if ( $atts['article-image'] !== '' ) {
            $data .= ' data-article-image="' . esc_attr( $atts['article-image'] ) . '"';
        }
        if ( $atts['target_page'] !== '' ) {
            $data .= ' data-target-page="' . esc_attr( $atts['target_page'] ) . '"';
        }
        if ( $atts['search'] === '0' ) {
            $data .= ' data-search="0"';
        }
        if ( $atts['sort_by'] !== '' ) {
            $data .= ' data-sort-by="' . esc_attr( sanitize_key( $atts['sort_by'] ) ) . '"';
        }
        if ( $atts['show_position'] !== '' ) {
            $data .= ' data-show-position="' . esc_attr( $atts['show_position'] ) . '"';
        }
        if ( $atts['show_institution'] !== '' ) {
            $data .= ' data-show-institution="' . esc_attr( $atts['show_institution'] ) . '"';
        }
        if ( $atts['show_tags'] !== '' ) {
            $data .= ' data-show-tags="' . esc_attr( $atts['show_tags'] ) . '"';
        }
        if ( $atts['max_tags'] !== '' ) {
            $data .= ' data-max-tags="' . esc_attr( (int) $atts['max_tags'] ) . '"';
        }
        if ( $atts['show_publications'] !== '' ) {
            $data .= ' data-show-publications="' . esc_attr( $atts['show_publications'] ) . '"';
        }
        if ( $atts['show_profile_link'] !== '' ) {
            $data .= ' data-show-profile-link="' . esc_attr( $atts['show_profile_link'] ) . '"';
        }
        if ( $atts['per_page'] !== '' ) {
            $data .= ' data-per-page="' . esc_attr( (int) $atts['per_page'] ) . '"';
        }

        // ── Heading + server-rendered first page ──────────────────────
        // The heading sits outside the container so it survives loadGroup()'s
        // $el.html() replacement; the SSR list goes inside so it's a real (if
        // brief, for JS visitors) placeholder that non-JS crawlers/AI agents
        // still see as the final content.
        $heading_html = '';
        $inner_html   = '';
        $json_ld_html = '';

        global $wpdb;
        $group = $wpdb->get_row( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Read bypasses cache safely
            $wpdb->prepare( 'SELECT * FROM %i WHERE group_id = %d', SCHOLAR_SYNC_DB_GROUPS, $group_id ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- %i is the WordPress identifier placeholder (WP 6.2+)
        );

        if ( $group ) {
            $group_settings = array();
            if ( $group->settings ) {
                $decoded = json_decode( $group->settings, true );
                if ( is_array( $decoded ) ) {
                    $group_settings = $decoded;
                }
            }
            // Shortcode attrs override the group's persisted settings — same layering
            // scholar-sync-group-public.js's loadGroup() applies on top of the REST response.
            if ( $atts['columns'] !== '' )           { $group_settings['columns']           = (int) $atts['columns']; }
            if ( $atts['image_shape'] !== '' )       { $group_settings['image_shape']       = sanitize_key( $atts['image_shape'] ); }
            if ( $atts['shadow'] !== '' )             { $group_settings['shadow']            = ( $atts['shadow'] !== '0' ); }
            if ( $atts['show_position'] !== '' )      { $group_settings['show_position']     = ( $atts['show_position'] !== '0' ); }
            if ( $atts['show_institution'] !== '' )   { $group_settings['show_institution']  = ( $atts['show_institution'] !== '0' ); }
            if ( $atts['show_tags'] !== '' )          { $group_settings['show_tags']         = ( $atts['show_tags'] !== '0' ); }
            if ( $atts['max_tags'] !== '' )           { $group_settings['max_tags']          = (int) $atts['max_tags']; }
            if ( $atts['show_publications'] !== '' )  { $group_settings['show_publications'] = ( $atts['show_publications'] !== '0' ); }
            if ( $atts['show_profile_link'] !== '' )  { $group_settings['show_profile_link'] = ( $atts['show_profile_link'] !== '0' ); }
            if ( $atts['per_page'] !== '' )           { $group_settings['per_page']          = (int) $atts['per_page']; }

            $group_name = trim( (string) $group->name );

            if ( 'grid' === $group->view_type ) {
                list( $summary, $inner_html, $json_ld ) = $this->render_group_grid_ssr( $group_id, $group_name, $group_settings, (string) $atts['target_page'] );
            } else {
                list( $summary, $inner_html, $json_ld ) = $this->render_group_feed_ssr( $group_id, $group_name, (string) $atts['sort_by'] );
            }

            if ( $group_name !== '' ) {
                $heading_html  = '<h2 class="scholar-sync-group-heading">' . esc_html( $group_name ) . '</h2>';
                $heading_html .= '<p class="scholar-sync-group-summary">' . esc_html( $summary ) . '</p>';
            }
            if ( $json_ld !== null ) {
                ob_start();
                ScholarSync_SEO::render_json_ld( $json_ld );
                $json_ld_html = ob_get_clean();
            }
        }

        return $heading_html
            . '<div class="scholar-sync-group-shortcode" ' . $data . '>' . $inner_html . '</div>'
            . $json_ld_html;
    }

    /**
     * Server-rendered first page of the Staff Directory grid + a Person ItemList
     * schema, for group.view_type === 'grid'. Mirrors the query shape of
     * ScholarSync_REST_API::get_group_display()'s grid branch.
     *
     * @return array{0:string,1:string,2:array|null} [summary sentence, inner HTML, JSON-LD data].
     */
    private function render_group_grid_ssr( $group_id, $group_name, array $settings, $target_page ) {
        global $wpdb;
        $table_authors       = SCHOLAR_SYNC_DB_AUTHORS;
        $table_group_authors = SCHOLAR_SYNC_DB_GROUP_AUTHORS;

        $total = (int) $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $wpdb->prepare( 'SELECT COUNT(*) FROM %i WHERE group_id = %d', $table_group_authors, $group_id ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- %i is the WordPress identifier placeholder (WP 6.2+)
        );

        $per_page = isset( $settings['per_page'] ) ? (int) $settings['per_page'] : 12;
        $per_page = max( 4, min( 48, $per_page ?: 12 ) );

        $authors = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $wpdb->prepare( // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- %i is the WordPress identifier placeholder (WP 6.2+)
                "SELECT a.author_id, a.name, a.position, a.thumbnail, a.scholar_id, a.orcid_id, a.website, a.directory_link,
                        a.affiliations, a.interests,
                        COALESCE( NULLIF( ga.link_url, '' ), NULLIF( a.directory_link, '' ) ) AS effective_link
                 FROM %i a
                 INNER JOIN %i ga ON ga.author_id = a.author_id
                 WHERE ga.group_id = %d
                 ORDER BY ga.sort_order ASC
                 LIMIT %d",
                $table_authors,
                $table_group_authors,
                $group_id,
                $per_page
            ),
            ARRAY_A
        );

        if ( ! empty( $authors ) ) {
            $author_ids   = wp_list_pluck( $authors, 'author_id' );
            $placeholders = implode( ',', array_fill( 0, count( $author_ids ), '%d' ) );
            $table_articles = SCHOLAR_SYNC_DB_ARTICLES;
            $count_rows = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
                $wpdb->prepare(
                    "SELECT author_id, COUNT(*) AS cnt FROM %i WHERE author_id IN ( {$placeholders} ) AND is_active = 1 GROUP BY author_id", // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- %i is the WordPress identifier placeholder (WP 6.2+); $placeholders is array_fill()-generated %d only
                    array_merge( array( $table_articles ), $author_ids )
                ),
                ARRAY_A
            );
            $counts = array();
            foreach ( $count_rows as $row ) {
                $counts[ (int) $row['author_id'] ] = (int) $row['cnt'];
            }
            foreach ( $authors as &$author_ref ) {
                $author_ref['publication_count'] = $counts[ (int) $author_ref['author_id'] ] ?? 0;
            }
            unset( $author_ref );
        }

        $inner = '<div class="scholar-sync-group-grid-wrap"><div class="scholar-sync-group-grid">';
        foreach ( $authors as $author_row ) {
            $inner .= ScholarSync_SEO::render_group_card_ssr( $author_row, $settings, $target_page );
        }
        $inner .= '</div></div><div class="scholar-sync-group-grid-pagination"></div>';

        $json_ld = null;
        if ( ! empty( $authors ) ) {
            $people  = array_map( array( 'ScholarSync_SEO', 'person_schema' ), $authors );
            $json_ld = ScholarSync_SEO::item_list_document( $people, $group_name !== '' ? $group_name : __( 'Staff Directory', 'scholar-sync' ) );
        }

        $summary = $group_name !== ''
            ? sprintf(
                /* translators: 1: group name, 2: number of researchers */
                _n( '%1$s is a staff directory of %2$s researcher.', '%1$s is a staff directory of %2$s researchers.', $total, 'scholar-sync' ),
                $group_name,
                number_format_i18n( $total )
            )
            : '';

        return array( $summary, $inner, $json_ld );
    }

    /**
     * Server-rendered first page of the Research Feed (articles aggregated across
     * all group members) + a ScholarlyArticle ItemList schema, for
     * group.view_type === 'feed'. Mirrors the default-sort branch of
     * ScholarSync_REST_API::get_group_display()'s feed query.
     *
     * @return array{0:string,1:string,2:array|null} [summary sentence, inner HTML, JSON-LD data].
     */
    private function render_group_feed_ssr( $group_id, $group_name, $sort_by, $limit = 20 ) {
        global $wpdb;
        $table_articles       = SCHOLAR_SYNC_DB_ARTICLES;
        $table_group_authors  = SCHOLAR_SYNC_DB_GROUP_AUTHORS;

        $total = (int) $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $wpdb->prepare(
                'SELECT COUNT(*) FROM %i WHERE author_id IN ( SELECT author_id FROM %i WHERE group_id = %d ) AND is_active = 1', // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- %i is the WordPress identifier placeholder (WP 6.2+)
                $table_articles, $table_group_authors, $group_id
            )
        );

        // ORDER BY is a hardcoded literal in each branch (mirrors REST get_group_display()),
        // never built from a variable, so no value is ever interpolated into the SQL string.
        if ( 'cited_by' === $sort_by ) {
            $articles = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
                $wpdb->prepare( // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- %i is the WordPress identifier placeholder (WP 6.2+)
                    'SELECT article_id, title, link, authors, publication, cited_by_value, year FROM %i WHERE author_id IN ( SELECT author_id FROM %i WHERE group_id = %d ) AND is_active = 1 ORDER BY cited_by_value DESC, year DESC LIMIT %d',
                    $table_articles,
                    $table_group_authors,
                    $group_id,
                    $limit
                ),
                ARRAY_A
            );
        } else {
            $articles = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
                $wpdb->prepare( // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- %i is the WordPress identifier placeholder (WP 6.2+)
                    'SELECT article_id, title, link, authors, publication, cited_by_value, year FROM %i WHERE author_id IN ( SELECT author_id FROM %i WHERE group_id = %d ) AND is_active = 1 ORDER BY year DESC, cited_by_value DESC LIMIT %d',
                    $table_articles,
                    $table_group_authors,
                    $group_id,
                    $limit
                ),
                ARRAY_A
            );
        }
        $articles = is_array( $articles ) ? $articles : array();

        $inner = '<div class="wps-feed-list">';
        if ( ! empty( $articles ) ) {
            $inner .= '<div class="scholar-sync-feed-container">';
            foreach ( $articles as $article ) {
                $inner .= ScholarSync_SEO::render_article_card_ssr( $article );
            }
            $inner .= '</div>';
        }
        $inner .= '</div><div class="wps-feed-pagination"></div>';

        $json_ld = null;
        if ( ! empty( $articles ) ) {
            $items   = array_map( array( 'ScholarSync_SEO', 'scholarly_article_schema' ), $articles );
            $json_ld = ScholarSync_SEO::item_list_document( $items, $group_name !== '' ? $group_name : __( 'Research Feed', 'scholar-sync' ) );
        }

        $summary = $group_name !== ''
            ? sprintf(
                /* translators: 1: group name, 2: number of publications */
                _n( '%1$s is a research feed of %2$s publication.', '%1$s is a research feed of %2$s publications.', $total, 'scholar-sync' ),
                $group_name,
                number_format_i18n( $total )
            )
            : '';

        return array( $summary, $inner, $json_ld );
    }

    /**
     * @param $attributes
     * @return string
     * Render the preview block
     */
    public function render_block($attributes)
    {
        global $wpdb;
        if (isset($attributes['author'])) {
            $author_id = $attributes['author'];
        } else {
            return "";
        }
        $results = $wpdb->get_results( // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- %i is the WordPress identifier placeholder (WP 6.2+), Read bypasses cache safely
            $wpdb->prepare('SELECT * FROM %i WHERE author_id = %d', SCHOLAR_SYNC_DB_ARTICLES, $author_id)
        );

        if ( $wpdb->num_rows > 0 ) {
            $str = '
            <table id="my-table">
                    <thead>
                    <tr>
                        <th>Title23</th>
                        <th>Cited by334</th>
                        <th>Year</th>
                    </tr>
                    </thead>
                    <tbody>
            ';
            foreach ($results as $row) {
                $str .= '<tr>';
                $str .= '<td>';
                $str .= '<div><a href="' . esc_url($row->link) . '" target="_blank">' . esc_html($row->title) . '</a></div>';
                $str .= '<div>' . esc_html($row->authors) . '</div>';
                $str .= '<div>' . esc_html($row->publication) . '</div>';
                $str .= '<td>' . esc_html($row->cited_by_value) . '</td>';
                $str .= '<td>' . esc_html($row->year) . '</td>';
                $str .= '</tr>';
            }
            $str .= '
                </tbody>
            </table>
            
            ';
        } else {
            // no results
            $str = '<div>No articles for author with id: ' . esc_html($author_id) . '</div>';
        }
        return $str;
    }

}
