 //
            //
            // region PROFILE DETAILS
            //
            //

            // Strip Skool mention syntax [@Name](obj://user/...) -> @Name
            const cleanMentions = (text) => text.replace(/\[@([^\]]+)\]\(obj:\/\/user\/[^)]+\)/g, '@$1');

            // Member Notes functions
            async function loadMemberNotes(skoolId) {
                const container = document.getElementById('member-notes-list');
                if (!container) return;
                const notes = await MemberNote.forMember(skoolId);
                if (!notes.length) {
                    container.innerHTML = '<small style="color:#8b949e">No notes yet</small>';
                    return;
                }
                let html = '';
                for (const note of notes) {
                    const date = note.created_at ? new Date(note.created_at * 1000).toLocaleString() : '';
                    const escaped = (note.content || '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
                    html += `<article style="margin:4px 0;padding:8px;border-left:3px solid #f0ad4e;position:relative;">`;
                    html += `<small style="color:#8b949e">${date}</small>`;
                    html += `<button onclick="deleteMemberNote(${note.id},'${skoolId}')" style="position:absolute;right:4px;top:4px;background:none;border:none;color:#f85149;cursor:pointer;font-size:14px;" title="Delete note">x</button>`;
                    html += `<div style="white-space:pre-wrap;margin-top:4px;">${escaped}</div>`;
                    html += `</article>`;
                }
                container.innerHTML = html;
            }

            async function saveNewNote() {
                const section = document.getElementById('member-notes-section');
                const input = document.getElementById('new-note-input');
                if (!section || !input) return;
                const skoolId = section.dataset.skoolId;
                const content = input.value.trim();
                if (!content) return;
                const note = new MemberNote({ member_skool_id: skoolId, content });
                const res = await note.save();
                if (res.ok) {
                    input.value = '';
                    await loadMemberNotes(skoolId);
                }
            }

            async function deleteMemberNote(noteId, skoolId) {
                const note = new MemberNote({ id: noteId });
                note.id = noteId;
                await note.delete();
                await loadMemberNotes(skoolId);
            }

            // Align community activity data to the same date range as the reference heatmap.
            // Returns a counts array with the same length/startDate as the reference.
            let alignActivityData = (communityData, refStartDate, refTotalDays) => {
                const aligned = new Array(refTotalDays).fill(0);
                if (!communityData || !communityData.counts || !communityData.startDate) return aligned;

                const refStart = new Date(refStartDate);
                const commStart = new Date(communityData.startDate);
                const offsetDays = Math.round((commStart - refStart) / (24 * 60 * 60 * 1000));

                for (let i = 0; i < communityData.counts.length; i++) {
                    const idx = offsetDays + i;
                    if (idx >= 0 && idx < refTotalDays) {
                        aligned[idx] = communityData.counts[i];
                    }
                }
                return aligned;
            };

            // Render a GitHub-style activity heatmap SVG
            // counts + startDate are required, title is the heading
            let renderActivityHeatmap = (counts, startDate, title) => {
                let html = '';
                const maxVal = Math.max(...counts, 1);
                const totalActivity = counts.reduce((a, b) => a + b, 0);
                const activeDays = counts.filter(c => c > 0).length;

                html += `<h4>${title} (${totalActivity} actions, ${activeDays} active days)</h4>`;

                const cellSize = 10;
                const cellGap = 2;
                const step = cellSize + cellGap;
                const dayLabels = ['', 'Mon', '', 'Wed', '', 'Fri', ''];
                const labelWidth = 28;

                const startDow = startDate.getUTCDay(); // 0=Sun
                const totalDays = counts.length;
                const totalWeeks = Math.ceil((startDow + totalDays) / 7);

                const svgWidth = labelWidth + totalWeeks * step + 2;
                const svgHeight = 7 * step + 18; // +18 for month labels

                html += `<div style="overflow-x: auto; margin: 8px 0;">`;
                html += `<svg width="${svgWidth}" height="${svgHeight}" style="font-size:9px; font-family:monospace">`;

                // Day-of-week labels
                for (let d = 0; d < 7; d++) {
                    if (dayLabels[d]) {
                        html += `<text x="0" y="${18 + d * step + cellSize - 1}" fill="#888">${dayLabels[d]}</text>`;
                    }
                }

                // Month labels
                const [r, g, b] = lib.primaryColorRGB;
                let lastMonth = -1;
                for (let i = 0; i < totalDays; i++) {
                    const date = new Date(startDate);
                    date.setUTCDate(date.getUTCDate() + i);
                    const month = date.getUTCMonth();
                    const weekCol = Math.floor((startDow + i) / 7);
                    if (month !== lastMonth) {
                        const monthNames = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
                        html += `<text x="${labelWidth + weekCol * step}" y="10" fill="#888">${monthNames[month]}</text>`;
                        lastMonth = month;
                    }
                }

                // Activity cells
                for (let i = 0; i < totalDays; i++) {
                    const date = new Date(startDate);
                    date.setUTCDate(date.getUTCDate() + i);
                    const dow = (startDow + i) % 7;
                    const weekCol = Math.floor((startDow + i) / 7);
                    const val = counts[i];
                    const dateStr = date.toISOString().slice(0, 10);

                    let fill;
                    if (val === 0) {
                        fill = document.documentElement.getAttribute('data-theme') === 'dark'
                            ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)';
                    } else {
                        const intensity = Math.min(val / maxVal, 1);
                        const alpha = 0.2 + intensity * 0.8;
                        fill = `rgba(${r},${g},${b},${alpha.toFixed(2)})`;
                    }

                    const x = labelWidth + weekCol * step;
                    const y = 18 + dow * step;
                    html += `<rect x="${x}" y="${y}" width="${cellSize}" height="${cellSize}" rx="2" fill="${fill}">`;
                    html += `<title>${dateStr}: ${val} action${val !== 1 ? 's' : ''}</title></rect>`;
                }

                html += `</svg></div>`;
                return html;
            };

            // render profile details
            let loadAndRenderProfileDetails = (memberId) => {
                (async ()=>{
                    lib.showLoading();

                    // Ensure the secondary view panel is visible before writing to it
                    // Clear currentSecondaryView so no action button gets highlighted
                    currentSecondaryView = "";
                    if (!secondaryViewVisible) {
                        secondaryViewVisible = true;
                    }
                    updateActionButtons();
                    await renderMembersView();

                    const secondaryView = document.getElementById("secondary-view");
                    if (!secondaryView) {
                        console.error("secondary-view container not found after attempting to show it");
                        lib.hideLoading();
                        return;
                    }
                    secondaryView.innerHTML = `<h3>Loading...</h3>`;
                    console.log(`[ProfileDetails] Loading user with DB id=${memberId}`);
                    const user = await User.get(memberId);
                    if (!user) {
                        console.error(`[ProfileDetails] User.get(${memberId}) returned null - API call failed or user not found`);
                        secondaryView.innerHTML = `<h3>User not found</h3><small>Could not load user with ID ${memberId}. The user may have been deleted.</small>`;
                        lib.hideLoading();
                        return;
                    }
                    const skoolId = user.skool_id;

                    // Fetch posts, communities, liked posts, comments, daily activities, and community activities in parallel
                    const [postsRes, communitiesRes, profileCommunitiesRes, likedPostsRes, commentsRes, dailyActivitiesRes, communityActivitiesRes] = await Promise.all([
                        get(`/api/user/${skoolId}/posts`),
                        get(`/api/user/${skoolId}/communities`),
                        get(`/api/user/${skoolId}/profile-communities`),
                        get(`/api/user/${skoolId}/liked-posts`),
                        get(`/api/user/${skoolId}/comments`),
                        get(`/api/user/${skoolId}/daily-activities`),
                        get(`/api/user/${skoolId}/community-activities`)
                    ]);
                    const posts = postsRes.ok ? postsRes.data : [];
                    const communities = communitiesRes.ok ? communitiesRes.data : [];
                    const profileCommunities = profileCommunitiesRes.ok ? profileCommunitiesRes.data : [];
                    const likedPosts = likedPostsRes.ok ? likedPostsRes.data : [];
                    const comments = commentsRes.ok ? commentsRes.data : [];
                    const dailyActivities = dailyActivitiesRes.ok ? dailyActivitiesRes.data : null;
                    const communityActivities = communityActivitiesRes.ok ? communityActivitiesRes.data : null;

                    // Render user info with profile picture
                    const [r, g, b] = lib.primaryColorRGB;
                    let profileImgHtml = '';
                    if (hideProfileImages) {
                        const initial = (user.first_name || user.name || '?')[0].toUpperCase();
                        const hue = (user.skool_id || '').split('').reduce((a, c) => a + c.charCodeAt(0), 0) % 360;
                        profileImgHtml = `<div style="width:64px;height:64px;min-width:64px;border-radius:50%;background:hsl(${hue},55%,45%);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:bold;font-size:24px;">${initial}</div>`;
                    } else {
                        const imgSrc = user.skool_id ? `/api/image/${user.skool_id}` : '';
                        profileImgHtml = imgSrc
                            ? `<img src="${imgSrc}" style="width:64px;height:64px;min-width:64px;border-radius:50%;object-fit:cover;" onerror="this.style.display='none'">`
                            : '';
                    }
                    let html = `<div style="display:flex;align-items:center;gap:14px;margin-bottom:8px;">`;
                    html += profileImgHtml;
                    html += `<div>`;
                    html += `<h3 style="margin:0;">${user.first_name} ${user.last_name}</h3>`;
                    html += `<small>@${user.name} | Role: ${user.member_role || '-'}</small>`;
                    html += `</div></div>`;

                    // Determine reference date range from general activity data
                    const hasGeneral = dailyActivities && dailyActivities.counts && dailyActivities.counts.length > 0;
                    const refStartDate = hasGeneral ? new Date(dailyActivities.startDate) : null;
                    const refTotalDays = hasGeneral ? dailyActivities.counts.length : 0;

                    // Render general daily activity heatmap
                    if (hasGeneral) {
                        html += renderActivityHeatmap(dailyActivities.counts, refStartDate, 'SKOOL ACTIVITIES');
                    }

                    // Render community-specific activity heatmap (always shown, aligned to general)
                    if (hasGeneral) {
                        const alignedCounts = alignActivityData(communityActivities, refStartDate, refTotalDays);
                        html += renderActivityHeatmap(alignedCounts, refStartDate, 'COMMUNITY ACTIVITIES');
                    }

                    // Render communities from profile (more complete)
                    html += `<h4>COMMUNITIES (${profileCommunities.length || communities.length})</h4>`;
                    const communityPillStyle = `margin-right: 8px; margin-bottom: 4px; padding: 2px 6px; background: rgba(${r},${g},${b},0.15); border: 1px solid rgba(${r},${g},${b},0.3); border-radius: 4px; display: inline-block; cursor: pointer`;
                    if (profileCommunities.length) {
                        const maxVisible = 5;
                        html += `<div>`;
                        for (let i = 0; i < Math.min(profileCommunities.length, maxVisible); i++) {
                            const c = profileCommunities[i];
                            html += `<small style="${communityPillStyle}"
                                onclick="window.location.href='/communities.html?community=${encodeURIComponent(c.slug)}'">${c.name}</small>`;
                        }
                        html += `</div>`;
                        if (profileCommunities.length > maxVisible) {
                            html += `<details><summary style="cursor:pointer;margin-top:4px"><small>Show ${profileCommunities.length - maxVisible} more...</small></summary><div style="margin-top:4px">`;
                            for (let i = maxVisible; i < profileCommunities.length; i++) {
                                const c = profileCommunities[i];
                                html += `<small style="${communityPillStyle}"
                                    onclick="window.location.href='/communities.html?community=${encodeURIComponent(c.slug)}'">${c.name}</small>`;
                            }
                            html += `</div></details>`;
                        }
                    } else if (communities.length) {
                        // Fallback to user table communities
                        const maxVisible = 5;
                        html += `<div>`;
                        for (let i = 0; i < Math.min(communities.length, maxVisible); i++) {
                            html += `<small style="${communityPillStyle}"
                                onclick="window.location.href='/communities.html?community=${encodeURIComponent(communities[i])}'">${communities[i]}</small>`;
                        }
                        html += `</div>`;
                        if (communities.length > maxVisible) {
                            html += `<details><summary style="cursor:pointer;margin-top:4px"><small>Show ${communities.length - maxVisible} more...</small></summary><div style="margin-top:4px">`;
                            for (let i = maxVisible; i < communities.length; i++) {
                                html += `<small style="${communityPillStyle}"
                                    onclick="window.location.href='/communities.html?community=${encodeURIComponent(communities[i])}'">${communities[i]}</small>`;
                            }
                            html += `</div></details>`;
                        }
                    } else {
                        html += `<small>No communities found (profile not fetched yet)</small>`;
                    }

                    // INTERESTS section
                    const interestsList = memberInterests.get(skoolId);
                    if (interestsList && interestsList.length > 0) {
                        html += `<h4>INTERESTS</h4>`;
                        html += `<div style="display:flex;flex-direction:column;gap:6px;">`;
                        for (const t of interestsList) {
                            const hue = categoryToHue(t.category);
                            const pct = Math.round(t.weight * 100);
                            const barWidth = Math.max(pct, 5);
                            html += `<div style="display:flex;align-items:center;gap:8px;">`;
                            html += `<span style="padding:2px 8px;border-radius:4px;font-size:0.85em;min-width:140px;
                                background:hsl(${hue},50%,25%);color:hsl(${hue},80%,80%);
                                border:1px solid hsl(${hue},50%,35%);">${t.category}</span>`;
                            html += `<div style="flex:1;height:8px;background:rgba(255,255,255,0.1);border-radius:4px;overflow:hidden;">`;
                            html += `<div style="width:${barWidth}%;height:100%;background:hsl(${hue},60%,50%);border-radius:4px;"></div>`;
                            html += `</div>`;
                            html += `<small style="color:#8b949e;min-width:45px;text-align:right;">${pct}%</small>`;
                            html += `</div>`;
                        }
                        html += `</div>`;
                    } else if (labelsLoaded) {
                        // Labels loaded but no interests for this member — try individual fetch
                        (async () => {
                            try {
                                const res = await fetch(`/api/member-interests?skool_id=${encodeURIComponent(skoolId)}`);
                                if (!res.ok) return;
                                const data = await res.json();
                                if (data.interests && data.interests.length > 0) {
                                    memberInterests.set(skoolId, data.interests);
                                    const anchor = document.getElementById('profile-interests-placeholder');
                                    if (anchor) {
                                        let ihtml = `<h4>INTERESTS</h4>`;
                                        ihtml += `<div style="display:flex;flex-direction:column;gap:6px;">`;
                                        for (const t of data.interests) {
                                            const hue = categoryToHue(t.category);
                                            const pct = Math.round(t.weight * 100);
                                            const barWidth = Math.max(pct, 5);
                                            ihtml += `<div style="display:flex;align-items:center;gap:8px;">`;
                                            ihtml += `<span style="padding:2px 8px;border-radius:4px;font-size:0.85em;min-width:140px;
                                                background:hsl(${hue},50%,25%);color:hsl(${hue},80%,80%);
                                                border:1px solid hsl(${hue},50%,35%);">${t.category}</span>`;
                                            ihtml += `<div style="flex:1;height:8px;background:rgba(255,255,255,0.1);border-radius:4px;overflow:hidden;">`;
                                            ihtml += `<div style="width:${barWidth}%;height:100%;background:hsl(${hue},60%,50%);border-radius:4px;"></div>`;
                                            ihtml += `</div>`;
                                            ihtml += `<small style="color:#8b949e;min-width:45px;text-align:right;">${pct}%</small>`;
                                            ihtml += `</div>`;
                                        }
                                        ihtml += `</div>`;
                                        anchor.innerHTML = ihtml;
                                    }
                                }
                            } catch (e) { /* ignore */ }
                        })();
                        html += `<div id="profile-interests-placeholder"></div>`;
                    }

                    // Helper: render a single post article
                    const renderPostArticle = (post, borderColor) => {
                        const meta = post.metadata ? JSON.parse(post.metadata) : {};
                        const title = meta.title || post.name || '(Untitled)';
                        return `<article style="margin: 4px 0; padding: 8px; border-left: 3px solid ${borderColor}">
                            <b>${title}</b><br>
                            <small>
                                ${post.upvotes || 0} upvotes | ${post.comments || 0} comments |
                                ${post.community_slug}
                            </small>
                        </article>`;
                    };

                    // Helper: render a single comment article
                    const renderCommentArticle = (comment) => {
                        const meta = comment.metadata ? JSON.parse(comment.metadata) : {};
                        const content = cleanMentions(meta.content || '(No content)');
                        const preview = content.length > 120 ? content.slice(0, 120) + '...' : content;
                        return `<article style="margin: 4px 0; padding: 8px; border-left: 3px solid #2ecc71">
                            <small>${preview}</small><br>
                            <small style="color: #888">
                                on post ${comment.root_id ? comment.root_id.slice(0, 8) + '...' : '-'} |
                                ${comment.upvotes || 0} upvotes |
                                ${comment.community_slug}
                            </small>
                        </article>`;
                    };

                    // Render posts (newest first, rest collapsible)
                    html += `<h4>POSTS (${posts.length})</h4>`;
                    if (posts.length) {
                        html += renderPostArticle(posts[0], '#3498db');
                        if (posts.length > 1) {
                            html += `<details><summary style="cursor:pointer;margin-top:4px"><small>Show ${posts.length - 1} older posts...</small></summary>`;
                            for (let i = 1; i < posts.length; i++) {
                                html += renderPostArticle(posts[i], '#3498db');
                            }
                            html += `</details>`;
                        }
                    } else {
                        html += `<small>No posts found</small>`;
                    }

                    // Render comments by this user (newest first, rest collapsible)
                    html += `<h4>COMMENTS (${comments.length})</h4>`;
                    if (comments.length) {
                        html += renderCommentArticle(comments[0]);
                        if (comments.length > 1) {
                            html += `<details><summary style="cursor:pointer;margin-top:4px"><small>Show ${comments.length - 1} older comments...</small></summary>`;
                            for (let i = 1; i < comments.length; i++) {
                                html += renderCommentArticle(comments[i]);
                            }
                            html += `</details>`;
                        }
                    } else {
                        html += `<small>No comments found</small>`;
                    }

                    // Render liked content (newest first, rest collapsible)
                    html += `<h4>LIKED CONTENT (${likedPosts.length})</h4>`;
                    if (likedPosts.length) {
                        const renderLikedPostArticle = (post) => {
                            const meta = post.metadata ? JSON.parse(post.metadata) : {};
                            const isComment = post.is_toplevel === 0;
                            let displayText;
                            if (isComment) {
                                const content = cleanMentions(meta.content || '(No content)');
                                displayText = content.length > 120 ? content.slice(0, 120) + '...' : content;
                            } else {
                                displayText = meta.title || post.name || '(Untitled)';
                            }
                            const borderColor = isComment ? '#2ecc71' : '#e74c3c';
                            const typeLabel = isComment ? 'Comment' : 'Post';
                            return `<article style="margin: 4px 0; padding: 8px; border-left: 3px solid ${borderColor}">
                                ${isComment ? `<small>${displayText}</small>` : `<b>${displayText}</b>`}<br>
                                <small>
                                    <span style="color:${borderColor}">[${typeLabel}]</span>
                                    by <b>${post.user_name || '-'}</b> |
                                    ${post.upvotes || 0} upvotes |
                                    ${post.community_slug}
                                </small>
                            </article>`;
                        };
                        html += renderLikedPostArticle(likedPosts[0]);
                        if (likedPosts.length > 1) {
                            html += `<details><summary style="cursor:pointer;margin-top:4px"><small>Show ${likedPosts.length - 1} older liked content...</small></summary>`;
                            for (let i = 1; i < likedPosts.length; i++) {
                                html += renderLikedPostArticle(likedPosts[i]);
                            }
                            html += `</details>`;
                        }
                    } else {
                        html += `<small>No liked posts found (likes not fetched yet)</small>`;
                    }

                    // Notes section
                    html += `<h4>NOTES</h4>`;
                    html += `<div id="member-notes-section" data-skool-id="${skoolId}">`;
                    html += `<div id="member-notes-list"><small>Loading notes...</small></div>`;
                    html += `<div style="margin-top:8px;">`;
                    html += `<textarea id="new-note-input" rows="3" placeholder="Add a note..." style="width:100%;background:#1a1a1a;color:whitesmoke;border:1px solid #374151;border-radius:4px;padding:6px;resize:vertical;"></textarea>`;
                    html += `<button onclick="saveNewNote()" style="margin-top:4px;padding:4px 12px;">Save Note</button>`;
                    html += `</div></div>`;

                    // Load notes after render
                    setTimeout(() => loadMemberNotes(skoolId), 0);
                    const rawData = {
                        user,
                        posts,
                        communities,
                        profileCommunities,
                        likedPosts,
                        comments,
                        dailyActivities,
                        communityActivities
                    };
                    html += `<details><summary>Raw JSON</summary><pre>${JSON.stringify(rawData, null, 2)}</pre></details>`;

                    secondaryView.innerHTML = html;
                    lib.hideLoading();
                })();
            };
