// ==========================================
// NotesPane Kit — NoteReader
// ==========================================
// Read-mode view: rendered markdown with wikilink chips,
// transclusion embeds, outline/TOC, backlinks panel,
// unlinked mentions, daily note navigation.
// Independently importable.

import { renderNoteMarkdown, attachWikilinkHandlers, resolveTransclusions, extractHeadings } from './markdown.js';

const { useState, useRef, useCallback, useEffect } = window.hooks;
const html = window.html;

/**
 * @param {{
 *   note: object,
 *   backlinks: Array,
 *   onEdit: () => void,
 *   onDelete: () => void,
 *   onCopy: () => void,
 *   onNavigateLink: (title: string) => void,
 *   onBack: () => void,
 *   isDailyNote: boolean,
 *   onDailyPrev: () => void,
 *   onDailyNext: () => void,
 * }} props
 */
export function NoteReader(props) {
    const {
        note, backlinks, onEdit, onDelete, onCopy, onNavigateLink,
        onBack, isDailyNote, onDailyPrev, onDailyNext,
    } = props;

    const contentRef = useRef(null);
    const [backlinksOpen, setBacklinksOpen] = useState(true);
    const [unlinkedMentions, setUnlinkedMentions] = useState([]);

    // ── Render content + wikilinks ──────────
    useEffect(() => {
        if (!contentRef.current || !note) return;
        const { html: rendered } = renderNoteMarkdown(note.content || '');
        contentRef.current.innerHTML = rendered;

        // Attach wikilink click handlers
        attachWikilinkHandlers(contentRef.current, onNavigateLink);

        // Resolve transclusions
        resolveTransclusions(contentRef.current, onNavigateLink);

        // Add IDs to headings for outline scroll-to
        contentRef.current.querySelectorAll('h1, h2, h3').forEach(el => {
            const id = el.textContent.toLowerCase().replace(/[^\w]+/g, '-').replace(/^-|-$/g, '');
            el.id = 'heading-' + id;
        });
    }, [note?.id, note?.content, onNavigateLink]);

    // ── Extract headings for outline ────────
    const headings = note ? extractHeadings(note.content || '') : [];

    // ── Find unlinked mentions ──────────────
    useEffect(() => {
        if (!note?.content) { setUnlinkedMentions([]); return; }
        // Debounce: fetch note titles and check for unlinked mentions
        const timer = setTimeout(async () => {
            try {
                const api = window.sw?.api?.notes;
                if (!api) return;
                // Get all note titles (limited)
                const resp = await api.list({ limit: 200, offset: 0 });
                const allNotes = resp.data || [];
                const content = note.content.toLowerCase();

                // Find titles mentioned in content but not wikilinked
                const linked = new Set();
                const linkRe = /\[\[([^\]|]+?)(?:\|[^\]]+?)?\]\]/g;
                let m;
                while ((m = linkRe.exec(note.content)) !== null) {
                    linked.add(m[1].trim().toLowerCase());
                }

                const mentions = allNotes
                    .filter(n => n.id !== note.id)
                    .filter(n => {
                        const t = n.title.toLowerCase();
                        return t.length > 2 && content.includes(t) && !linked.has(t);
                    })
                    .map(n => n.title)
                    .slice(0, 10);

                setUnlinkedMentions(mentions);
            } catch { setUnlinkedMentions([]); }
        }, 500);
        return () => clearTimeout(timer);
    }, [note?.id, note?.content]);

    if (!note) return null;

    const folderBadge = note.folder_path && note.folder_path !== '/'
        ? html`<span class="sw-notes-pane__item-folder">${note.folder_path}</span>`
        : null;

    const tagChips = (note.tags || []).map(t =>
        html`<span class="sw-notes-pane__item-tag" key=${t}>${t}</span>`
    );

    const today = new Date().toISOString().slice(0, 10);
    const dailyDate = isDailyNote ? note.title.replace('Daily \u2014 ', '') : null;

    const scrollToHeading = (id) => {
        const el = contentRef.current?.querySelector('#heading-' + id);
        if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
    };

    return html`
        <div class="sw-notes-pane__editor-header">
            <button class="sw-notes-pane__toolbar-btn" onClick=${onBack}>← Back</button>
            <span class="sw-notes-pane__editor-header-spacer" />
            <button class="sw-notes-pane__toolbar-btn" onClick=${onCopy} title="Copy to clipboard">Copy</button>
            <button class="sw-notes-pane__toolbar-btn" onClick=${onEdit}>Edit</button>
            <button class="sw-notes-pane__toolbar-btn"
                    style="color:var(--danger);border-color:var(--danger)"
                    onClick=${onDelete}>Delete</button>
        </div>

        <div class=${'sw-notes-pane__reader' + (headings.length > 2 ? ' sw-notes-pane__reader--with-outline' : '')}>
            ${headings.length > 2 && html`
                <div class="sw-notes-pane__outline-sidebar">
                    <div class="sw-notes-pane__outline-title">Outline</div>
                    ${headings.map(h => html`
                        <a key=${h.id}
                           class=${'sw-notes-pane__outline-item sw-notes-pane__outline-item--h' + h.level}
                           onClick=${() => scrollToHeading(h.id)}>
                            ${h.text}
                        </a>`)}
                </div>`}

            <div class="sw-notes-pane__reader-scroll">
                <h1 class="sw-notes-pane__reader-title">${note.title}</h1>

                ${(folderBadge || tagChips.length > 0) && html`
                    <div class="sw-notes-pane__reader-meta">${folderBadge}${tagChips}</div>`}

                ${isDailyNote && html`
                    <div class="sw-notes-pane__daily-nav">
                        <button class="sw-notes-pane__toolbar-btn" onClick=${onDailyPrev}>‹ Prev</button>
                        <span>${dailyDate}</span>
                        <button class="sw-notes-pane__toolbar-btn" onClick=${onDailyNext}
                                disabled=${dailyDate >= today}>Next ›</button>
                    </div>`}

                <div class="sw-notes-pane__reader-content" ref=${contentRef} />

                ${backlinks.length > 0 && html`
                    <div class="sw-notes-pane__backlinks">
                        <div class="sw-notes-pane__backlinks-header"
                             onClick=${() => setBacklinksOpen(p => !p)}>
                            ${backlinksOpen ? '▾' : '▸'} Backlinks
                            <span class="sw-notes-pane__backlinks-badge">${backlinks.length}</span>
                        </div>
                        ${backlinksOpen && html`
                            <div class="sw-notes-pane__backlinks-list">
                                ${backlinks.map(bl => html`
                                    <div key=${bl.id} class="sw-notes-pane__backlink-item"
                                         onClick=${() => onNavigateLink(bl.title)}>
                                        <span>${bl.title}</span>
                                        ${bl.folder_path && bl.folder_path !== '/' && html`
                                            <span class="sw-notes-pane__backlink-folder">${bl.folder_path}</span>`}
                                    </div>`)}
                            </div>`}
                    </div>`}

                ${unlinkedMentions.length > 0 && html`
                    <div class="sw-notes-pane__unlinked">
                        <div class="sw-notes-pane__unlinked-title">Unlinked Mentions</div>
                        ${unlinkedMentions.map(title => html`
                            <span key=${title} class="sw-notes-pane__unlinked-item"
                                  onClick=${() => onNavigateLink(title)} title="Navigate to ${title}">
                                ${title}
                            </span>`)}
                    </div>`}
            </div>
        </div>
    `;
}
