/* global jQuery */
/* Shared article-card helpers – loaded before scholar-sync-group-public.js and scholar-sync-groups.js */
(function ($) {
    'use strict';

    /* ── Short-name helper ─────────────────────────────────── */
    /* Algorithm: first-char of first word + last word, e.g. "John von Neumann" → "J Neumann" */
    window.scholarSyncGenerateShortName = function (fullName) {
        if (!fullName) { return ''; }
        var parts = fullName.trim().split(/\s+/);
        if (parts.length === 0 || parts[0] === '') { return ''; }

        // Strip honorific prefixes, case-insensitively, repeatedly, as long as a word remains.
        // Kept in sync by hand with admin/scholar_sync_functions.php and
        // admin/js/scholar-sync-admin.js.
        var PREFIXES = ['dr', 'prof', 'professor', 'mr', 'mrs', 'ms', 'mx', 'miss'];
        while (parts.length > 1) {
            var candidate = parts[0].replace(/\.$/, '').toLowerCase();
            if (PREFIXES.indexOf(candidate) === -1) { break; }
            parts.shift();
        }

        return parts[0].charAt(0).toUpperCase() + ' ' + parts[parts.length - 1];
    };

    /* ── Article card HTML builder ─────────────────────────── */
    /*
     * @param {Object} article      – article row object from REST API
     * @param {number} index        – 0-based index within the current page (stored as data-article-index)
     * @param {Object} authorPhotos – map of short-name → { image_url, name } built server-side
     * @param {string} pluginUrl    – SCHOLAR_SYNC_PLUGIN_URL (trailing slash included)
     * @returns {string} HTML string for one card
     */
    window.scholarSyncRenderArticleCard = function (article, index, authorPhotos, pluginUrl, options) {
        options = options || {};
        var showCoAuthors = options.showCoAuthors !== false;
        var showAuthorPhotos = options.showAuthorPhotos !== false;
        var showCitedBy   = options.showCitedBy   !== false;
        var showArticleImage = options.showArticleImage === true;
        var blankImg = pluginUrl + 'includes/images/blank_profile.png';

        // Meta line: "2024 • Nature"
        var meta = '';
        if (article.year) { meta += article.year; }
        if (article.year && article.publication) { meta += ' \u2022 '; }
        if (article.publication) { meta += article.publication; }

        // Title: linked if article.link is present and uses http(s)
        var safeLink = (article.link && /^https?:\/\//i.test(article.link)) ? article.link : '';
        var titleText = $('<div>').text((article.title || '').replace(/<[^>]*>/g, '')).html();
        var titleHtml;
        if (safeLink) {
            titleHtml = '<a class="scholar-sync-article-title" href="'
                + safeLink.replace(/"/g, '&quot;')
                + '" target="_blank" rel="noopener noreferrer">'
                + titleText
                + '</a>';
        } else {
            titleHtml = '<span class="scholar-sync-article-title">' + titleText + '</span>';
        }

        // Author chips: circular photo + short name, with optional profile link on name
        var authorsHtml = '';
        var MAX_VISIBLE_AUTHORS = 10;
        if (article.authors) {
            var names         = article.authors.split(', ');
            var overflowCount = Math.max(0, names.length - MAX_VISIBLE_AUTHORS);
            for (var n = 0; n < names.length; n++) {
                var fullName   = names[n];
                var shortName  = window.scholarSyncGenerateShortName(fullName);
                var photoEntry = (fullName && authorPhotos[fullName])
                    ? authorPhotos[fullName]
                    : (shortName && authorPhotos[shortName])
                        ? authorPhotos[shortName]
                        : {};
                var imgSrc     = photoEntry.image_url ? photoEntry.image_url : blankImg;
                var altText    = photoEntry.name ? photoEntry.name : fullName;
                var nameText   = $('<div>').text(shortName).html();
                var nameHtml;
                if (photoEntry.profile_link && /^https?:\/\//i.test(photoEntry.profile_link)) {
                    nameHtml = '<a class="scholar-sync-chip-name-link" href="'
                        + photoEntry.profile_link.replace(/"/g, '&quot;')
                        + '">' + nameText + '</a>';
                } else {
                    nameHtml = '<span>' + nameText + '</span>';
                }
                var isOverflow = n >= MAX_VISIBLE_AUTHORS;
                authorsHtml += '<div class="scholar-sync-author-chip'
                    + (isOverflow ? ' scholar-sync-author-overflow' : '')
                    + (showAuthorPhotos ? '' : ' scholar-sync-author-chip-no-photo') + '"'
                    + (isOverflow ? ' hidden' : '') + '>'
                    + (showAuthorPhotos
                        ? '<img src="' + imgSrc.replace(/"/g, '&quot;') + '"'
                            + ' alt="' + altText.replace(/"/g, '&quot;') + '"'
                            + ' width="50" height="50" />'
                        : '')
                    + nameHtml
                    + '</div>';
                // Insert toggle button between last visible and first overflow chip
                if (n === MAX_VISIBLE_AUTHORS - 1 && overflowCount > 0) {
                    authorsHtml += '<button class="scholar-sync-authors-toggle'
                        + (showAuthorPhotos ? '' : ' scholar-sync-authors-toggle-no-photo') + '" type="button" aria-expanded="false">'
                        + '<span class="scholar-sync-authors-toggle-icon">···</span>'
                        + '<span class="scholar-sync-authors-toggle-label">+' + overflowCount + '</span>'
                        + '</button>';
                }
            }
        }

        // Cited-by badge (only when article has a value).
        var citedByHtml = '';
        if (article.cited_by_value && article.cited_by_value !== '0') {
            var citedByInner = 'Cited by ' + $('<div>').text(article.cited_by_value).html();
            citedByHtml = '<div class="scholar-sync-cited-by"' + (showCitedBy ? '' : ' hidden') + '>' + citedByInner + '</div>';
        }

        // Article image thumbnail (e.g. graphical abstract or poster): only when
        // the feed opts in and the URL passes the same http(s) allowlist as links.
        // Clicking it opens a full-screen lightbox (wired in scholarSyncWireFeedEvents).
        var articleImageHtml = '';
        if (showArticleImage && article.image_url && /^https?:\/\//i.test(article.image_url)) {
            var imageAlt = $('<div>').text(article.title || '').html().replace(/"/g, '&quot;');
            var imageTag = '<img src="' + article.image_url.replace(/"/g, '&quot;') + '"'
                + ' alt="' + imageAlt + '" width="200" height="200" loading="lazy" />';
            articleImageHtml = '<button type="button" class="scholar-sync-article-image">' + imageTag + '</button>';
        }

        var metaHtml    = '<div class="scholar-sync-article-meta">' + $('<div>').text(meta).html() + '</div>';
        var authorsDiv  = '<div class="scholar-sync-article-authors"' + (showCoAuthors ? '' : ' hidden') + '>' + authorsHtml + '</div>';
        var actionsHtml = '<div class="scholar-sync-article-actions">'
            +   '<div class="scholar-sync-actions-row">'
            +     '<button class="scholar-sync-cite-btn" type="button">Cite</button>'
            +     citedByHtml
            +   '</div>'
            +   '<div class="scholar-sync-cite-panel" hidden>'
            +     '<p class="scholar-sync-cite-text"></p>'
            +     '<button class="scholar-sync-copy-cite-btn" type="button">Copy to clipboard</button>'
            +   '</div>'
            + '</div>';

        if (articleImageHtml) {
            // Meta + title span the full top line; the next row holds the author
            // chips on the left and the article image on the right.
            return '<div class="scholar-sync-article-card scholar-sync-has-image" data-article-index="' + index + '">'
                + metaHtml
                + titleHtml
                + '<div class="scholar-sync-article-middle">' + authorsDiv + articleImageHtml + '</div>'
                + actionsHtml
                + '</div>';
        }
        return '<div class="scholar-sync-article-card" data-article-index="' + index + '">'
            + metaHtml
            + titleHtml
            + authorsDiv
            + actionsHtml
            + '</div>';
    };

    /* ── APA7 citation formatter ───────────────────────────── */
    /*
     * Produces a citation string like:
     *   Smith, J. & Doe, A. (2024). Title. Journal, 10(2), 1–5. https://doi.org/...
     */
    window.scholarSyncFormatApa7 = function (article) {
        var authors = article.authors || '';
        var year    = article.year    || 'n.d.';
        var title   = article.title   || '';
        var pub     = article.publication || '';
        var vol     = article.volume  || '';
        var num     = article.number  || '';
        var pages   = article.pages   || '';
        var link    = article.link    || '';

        var formattedAuthors;
        if (/,\s*et al\.?$/i.test(authors)) {
            // Already has "et al." — pass through unchanged
            formattedAuthors = authors;
        } else {
            var nameList = authors.split(', ').map(function (fullName) {
                var parts = fullName.trim().split(/\s+/);
                if (parts.length < 2) { return fullName; }
                var last  = parts[parts.length - 1];
                var first = parts[0].charAt(0).toUpperCase() + '.';
                return last + ', ' + first;
            });
            formattedAuthors = nameList.length > 1
                ? nameList.slice(0, -1).join(', ') + ' & ' + nameList[nameList.length - 1]
                : (nameList[0] || authors);
        }

        var citation = formattedAuthors + ' (' + year + '). ' + title + '.';

        var sourceParts = [];
        var volPart = vol ? (num ? vol + '(' + num + ')' : vol) : '';
        if (pub)     { sourceParts.push(pub); }
        if (volPart) { sourceParts.push(volPart); }
        if (pages)   { sourceParts.push(pages); }
        if (sourceParts.length > 0) {
            citation += ' ' + sourceParts.join(', ') + '.';
        }
        if (link) { citation += ' ' + link; }

        return citation;
    };

    /* ── Article image lightbox ────────────────────────────── */
    /*
     * Opens src in a full-screen overlay; any click (or Escape) closes it.
     */
    window.scholarSyncOpenImageLightbox = function (src, alt) {
        var overlay = document.createElement('div');
        overlay.className = 'scholar-sync-image-lightbox';
        var img = document.createElement('img');
        img.src = src;
        img.alt = alt || '';
        overlay.appendChild(img);
        function close() {
            document.removeEventListener('keydown', onKey);
            overlay.remove();
        }
        function onKey(ev) { if (ev.key === 'Escape') { close(); } }
        overlay.addEventListener('click', close);
        document.addEventListener('keydown', onKey);
        document.body.appendChild(overlay);
    };

    /* ── Feed card event wiring ────────────────────────────── */
    /*
     * Attaches a single delegated click listener to containerEl.
     * Reads containerEl._feedArticles (set by the consumer before calling this)
     * to look up the article data lazily on first Cite click.
     */
    window.scholarSyncWireFeedEvents = function (containerEl) {
        containerEl.addEventListener('click', function (e) {
            // Cite button: toggle inline citation panel
            if (e.target.classList.contains('scholar-sync-cite-btn')) {
                var card       = e.target.closest('.scholar-sync-article-card');
                if (!card) { return; }
                var panel      = card.querySelector('.scholar-sync-cite-panel');
                var citeTextEl = card.querySelector('.scholar-sync-cite-text');
                if (panel.hidden) {
                    if (!citeTextEl.textContent) {
                        var idx      = parseInt(card.dataset.articleIndex, 10);
                        var articles = containerEl._feedArticles || [];
                        if (articles[idx]) {
                            citeTextEl.textContent = window.scholarSyncFormatApa7(articles[idx]);
                        }
                    }
                    panel.hidden = false;
                } else {
                    panel.hidden = true;
                }
            }
            // Article image: open full-screen lightbox
            var imageBtn = e.target.closest('.scholar-sync-article-image');
            if (imageBtn) {
                var thumb = imageBtn.querySelector('img');
                if (thumb) { window.scholarSyncOpenImageLightbox(thumb.src, thumb.alt); }
            }
            // Authors overflow toggle
            var toggleEl = e.target.closest('.scholar-sync-authors-toggle');
            if (toggleEl) {
                var authorsDiv    = toggleEl.closest('.scholar-sync-article-authors');
                var overflowChips = authorsDiv.querySelectorAll('.scholar-sync-author-overflow');
                var isExpanded    = toggleEl.getAttribute('aria-expanded') === 'true';
                overflowChips.forEach(function (chip) { chip.hidden = isExpanded; });
                toggleEl.setAttribute('aria-expanded', isExpanded ? 'false' : 'true');
                toggleEl.querySelector('.scholar-sync-authors-toggle-icon').textContent = isExpanded ? '···' : '↑';
                toggleEl.querySelector('.scholar-sync-authors-toggle-label').textContent = isExpanded
                    ? '+' + overflowChips.length
                    : 'less';
            }
            // Copy-to-clipboard button
            if (e.target.classList.contains('scholar-sync-copy-cite-btn')) {
                var citePanel = e.target.closest('.scholar-sync-cite-panel');
                if (!citePanel) { return; }
                var text = citePanel.querySelector('.scholar-sync-cite-text').textContent;
                if (navigator.clipboard) {
                    navigator.clipboard.writeText(text).then(function () {
                        var btn = e.target;
                        btn.textContent = 'Copied!';
                        setTimeout(function () { btn.textContent = 'Copy to clipboard'; }, 2000);
                    }).catch(function () { /* clipboard write not supported in this context */ });
                }
            }
        });
    };

}(jQuery));
