import { useEffect, useState } from "react";
import { NDKEvent } from "@nostr-dev-kit/ndk";
import { useUIStore } from "../../stores/ui";
import { fetchNoteById } from "../../lib/nostr";
import { useProfile } from "../../hooks/useProfile";
import { shortenPubkey } from "../../lib/utils";
import { ImageLightbox } from "../shared/ImageLightbox";
import { parseContent } from "../../lib/parsing";
import { renderTextSegments } from "./TextSegments";
import { VideoBlock, AudioBlock, YouTubeCard, VimeoCard, SpotifyCard, TidalCard } from "./MediaCards";
import { FountainCard } from "./FountainCard";
function ImageGrid({ images, onImageClick }: { images: string[]; onImageClick: (index: number) => void }) {
const count = images.length;
if (count === 0) return null;
const maxVisible = Math.min(count, 4);
const extraCount = count - 4;
const visible = images.slice(0, maxVisible);
if (count === 1) {
return (

{ e.stopPropagation(); onImageClick(0); }}
onError={(e) => { (e.target as HTMLImageElement).style.display = "none"; }}
/>
);
}
if (count === 2) {
return (
{visible.map((src, idx) => (

{ e.stopPropagation(); onImageClick(idx); }}
onError={(e) => { (e.target as HTMLImageElement).style.display = "none"; }}
/>
))}
);
}
if (count === 3) {
return (

{ e.stopPropagation(); onImageClick(0); }}
onError={(e) => { (e.target as HTMLImageElement).style.display = "none"; }}
/>

{ e.stopPropagation(); onImageClick(1); }}
onError={(e) => { (e.target as HTMLImageElement).style.display = "none"; }}
/>

{ e.stopPropagation(); onImageClick(2); }}
onError={(e) => { (e.target as HTMLImageElement).style.display = "none"; }}
/>
);
}
// 4+ images: 2x2 grid with "+N more" overlay on 4th
return (
{visible.map((src, idx) => (

{ e.stopPropagation(); onImageClick(idx); }}
onError={(e) => { (e.target as HTMLImageElement).style.display = "none"; }}
/>
{idx === 3 && extraCount > 0 && (
{ e.stopPropagation(); onImageClick(idx); }}
>
+{extraCount}
)}
))}
);
}
function QuotePreview({ eventId }: { eventId: string }) {
const [event, setEvent] = useState(null);
const { openThread, currentView } = useUIStore();
const profile = useProfile(event?.pubkey ?? "");
useEffect(() => {
if (!eventId) return;
fetchNoteById(eventId).then(setEvent);
}, [eventId]);
if (!event) return null;
const rawName = profile?.displayName || profile?.name;
const name = (typeof rawName === "string" ? rawName : null) || shortenPubkey(event.pubkey);
const preview = event.content.slice(0, 160) + (event.content.length > 160 ? "…" : "");
return (
{ e.stopPropagation(); openThread(event, currentView as "feed" | "profile"); }}
>
{profile?.picture && (

{ (e.target as HTMLImageElement).style.display = "none"; }} />
)}
{name}
{preview}
);
}
interface NoteContentProps {
content: string;
/** Render only inline text (no media blocks). Used inside the clickable area. */
inline?: boolean;
/** Render only media blocks (videos, embeds, quotes). Used outside the clickable area. */
mediaOnly?: boolean;
}
export function NoteContent({ content, inline, mediaOnly }: NoteContentProps) {
const { openHashtag } = useUIStore();
const segments = parseContent(content);
const images: string[] = segments.filter((s) => s.type === "image").map((s) => s.value);
const videos: string[] = segments.filter((s) => s.type === "video").map((s) => s.value);
const audios: string[] = segments.filter((s) => s.type === "audio").map((s) => s.value);
const youtubes = segments.filter((s) => s.type === "youtube");
const vimeos = segments.filter((s) => s.type === "vimeo");
const spotifys = segments.filter((s) => s.type === "spotify");
const tidals = segments.filter((s) => s.type === "tidal");
const fountains = segments.filter((s) => s.type === "fountain");
const quoteIds: string[] = segments.filter((s) => s.type === "quote").map((s) => s.value);
const [lightboxIndex, setLightboxIndex] = useState(null);
// --- Inline text + images (safe inside clickable wrapper) ---
if (inline) {
return (
{renderTextSegments(segments, openHashtag, { resolveMentions: true })}
{lightboxIndex !== null && (
setLightboxIndex(null)}
onNavigate={setLightboxIndex}
/>
)}
);
}
// --- Media blocks only (rendered OUTSIDE the clickable wrapper) ---
if (mediaOnly) {
const hasMedia = videos.length > 0 || audios.length > 0 || youtubes.length > 0
|| vimeos.length > 0 || spotifys.length > 0 || tidals.length > 0 || fountains.length > 0 || quoteIds.length > 0;
if (!hasMedia) return null;
return (
e.stopPropagation()}>
{youtubes.map((seg, i) =>
)}
{vimeos.map((seg, i) =>
)}
{spotifys.map((seg, i) =>
)}
{tidals.map((seg, i) =>
)}
{fountains.map((seg, i) =>
)}
{quoteIds.map((id) =>
)}
);
}
// --- Default: full render (used in ThreadView, SearchView, etc.) ---
return (
{renderTextSegments(segments, openHashtag)}
{lightboxIndex !== null && (
setLightboxIndex(null)}
onNavigate={setLightboxIndex}
/>
)}
{youtubes.map((seg, i) => )}
{vimeos.map((seg, i) => )}
{spotifys.map((seg, i) => )}
{tidals.map((seg, i) => )}
{fountains.map((seg, i) => )}
{quoteIds.map((id) => )}
);
}