// Slide-down Brief banner — appears under the navbar h2 with a Gaussian-glass
// background. Banner data comes from the Brief.to_banner_dict shape on the
// server: {id, kind, title, line_text, post_url, square_url, created_at}.
//
// FYI button → brief.post_url (the post detail; that GET marks the Brief read).
// .note-banner__image (the "square") → brief.square_url (kind-specific
// shortcut; note-unlock briefs jump direct to /billboard/my-notes/).
// NVM dismisses without marking read.
//
// `Note` is preserved as an alias for backwards-compat with any leftover
// caller while the C3 sprint lands; new code should use `Brief.*`.

const Brief = (() => {
    'use strict';

    function showBanner(brief) {
        if (!brief) return;

        const created = new Date(brief.created_at);
        const dateStr = created.toLocaleDateString(undefined, {
            year: 'numeric', month: 'short', day: 'numeric',
        });

        const banner = document.createElement('div');
        banner.className = 'note-banner';

        // The square mirrors my_notes.html's .note-item__image-box (dashed
        // border + "?" placeholder) when the brief carries a square_url —
        // currently note_unlock kind, which jumps direct to /billboard/my-notes/.
        const squareEl = brief.square_url
            ? '<a href="' + _esc(brief.square_url) + '" class="note-banner__image note-item__image-box">?</a>'
            : '<div class="note-banner__image"></div>';

        // line_text is server-rendered prose from drama.Note.grant_if_new
        // (and server-side share_post) — it may carry a `<a class="note-ref">`
        // anchor wrapping the Note name. Insert as HTML, NOT escaped text.
        // Title is plain (no HTML), so it stays escaped.
        banner.innerHTML =
            '<div class="note-banner__body">' +
                '<p class="note-banner__title">'       + _esc(brief.title)     + '</p>' +
                '<p class="note-banner__description">' + (brief.line_text || '') + '</p>' +
                '<time class="note-banner__timestamp" datetime="' + _esc(brief.created_at) + '">' +
                    dateStr +
                '</time>' +
            '</div>' +
            squareEl +
            '<button type="button" class="btn btn-cancel note-banner__nvm">NVM</button>' +
            '<a href="' + _esc(brief.post_url) + '" class="btn btn-info note-banner__fyi">FYI</a>';

        banner.querySelector('.note-banner__nvm').addEventListener('click', function () {
            banner.remove();
        });

        // Prefer the explicit anchor (set in base.html under the messages
        // block, before {% block content %}) — keeps the banner in the
        // visible content flow on pages where the first <h2> is
        // position:absolute (e.g. post.html's rotated navbar header).
        // Falls back to <h2> for pages that pre-date the anchor.
        var anchor = document.getElementById('id_brief_banner_anchor')
                  || document.querySelector('h2');
        if (anchor && anchor.parentNode) {
            anchor.parentNode.insertBefore(banner, anchor.nextSibling);
        } else {
            document.body.insertBefore(banner, document.body.firstChild);
        }
        _alignToH2(banner);
    }

    // Slot the (position:fixed) banner over the page's h2 letter-spread
    // header so it visually portals across the wordmark rather than parking
    // at the top of the viewport.
    //
    // Portrait only: h2 is a horizontal wordmark in `.container .row`; its
    // top edge is navbar-height + row-padding which differs per viewport,
    // so we measure at render-time + set inline `top`.
    //
    // Landscape: h2 is rotated into the fixed --h2-col-w sidebar slot via
    // `writing-mode: vertical-rl`. A horizontally-flowing banner can't
    // "overlay" a vertical h2 without a full reorientation of its own
    // contents (writing-mode + flex-direction restyle). Defer that to a
    // landscape-vertical-banner sprint; for now landscape keeps the SCSS
    // default `top: 0.5rem` (banner reads as a horizontal strip near the
    // top of the page content area).
    function _alignToH2(banner) {
        if (window.innerWidth > window.innerHeight) return;  // landscape: skip
        var h2 = document.querySelector('.row .col-lg-6 h2');
        if (!h2) return;
        var rect = h2.getBoundingClientRect();
        if (rect.height <= 0) return;
        banner.style.top = rect.top + 'px';
    }

    function handleSaveResponse(data) {
        showBanner(data && data.brief);
    }

    // Error-variant banner for "@<username> is already present". Distinct
    // from showBanner because it's purely client-side (no Brief DB row);
    // title carries the recipient handle; there's no date/square/post_url;
    // FYI is a <button> (no navigation) that toggles `.bud-duplicate-flash`
    // onto a caller-supplied target element + dismisses. NVM just dismisses.
    function showDuplicateBanner(opts) {
        if (!opts || !opts.display_name) return;

        var banner = document.createElement('div');
        banner.className = 'note-banner note-banner--duplicate';
        banner.innerHTML =
            '<div class="note-banner__body">' +
                '<p class="note-banner__title">@' + _esc(opts.display_name) + ' is already present</p>' +
            '</div>' +
            '<button type="button" class="btn btn-cancel note-banner__nvm">NVM</button>' +
            '<button type="button" class="btn btn-info note-banner__fyi">FYI</button>';

        banner.querySelector('.note-banner__nvm').addEventListener('click', function () {
            banner.remove();
        });
        banner.querySelector('.note-banner__fyi').addEventListener('click', function () {
            if (opts.target_selector) {
                var target = document.querySelector(opts.target_selector);
                if (target) {
                    target.classList.add('bud-duplicate-flash');
                    // Auto-ease-out — the SCSS rule has a 600ms transition
                    // on color + text-shadow, so removing the class 3s after
                    // FYI lets the peak state breathe before fading back to
                    // the default text styling. Without this the flash
                    // persisted til page refresh.
                    setTimeout(function () {
                        target.classList.remove('bud-duplicate-flash');
                    }, 3000);
                }
            }
            banner.remove();
        });

        var anchor = document.getElementById('id_brief_banner_anchor')
                  || document.querySelector('h2');
        if (anchor && anchor.parentNode) {
            anchor.parentNode.insertBefore(banner, anchor.nextSibling);
        } else {
            document.body.insertBefore(banner, document.body.firstChild);
        }
    }

    function _esc(str) {
        var d = document.createElement('div');
        d.textContent = str || '';
        return d.innerHTML;
    }

    return {
        showBanner:          showBanner,
        showDuplicateBanner: showDuplicateBanner,
        handleSaveResponse:  handleSaveResponse,
    };
})();

// Backwards-compat shim — to be removed once the codebase uniformly uses Brief.
const Note = Brief;

// `const Brief = (...)` at script-tag scope is reachable as a bare name but
// is NOT auto-attached to window — explicit assignment so callers that gate
// on `if (window.Brief)` (e.g. _bud_panel.html's OK handler) succeed.
window.Brief = Brief;
window.Note  = Note;
