// TribeTruth — live community surfaces (Supabase-backed, zero-build).
// Loaded BEFORE page-tt-rest.jsx so CommunityPage can lean on the shared
// data layer below. Mirrors the mobile app's cloud services:
//   App/src/services/cloud/forumService.ts
//   App/src/services/cloud/sharedReflectionsService.ts
//   App/src/services/cloud/testimonyService.ts
//   App/src/services/cloud/blessingDiscussionService.ts
// Guests can read everything (public RLS); writes require a session.

// =============================================================================
// FORUM CATEGORIES — ids MUST match the app's DB keys (data/forumCategories.ts)
// =============================================================================
const TT_FORUM_CATEGORIES = [
  { id: "general",           label: "General",               img: `${CDN}/Forums/thumbs/ChatGPT%20Image%20Mar%2011%2C%202026%2C%2003_52_59%20PM.png` },
  { id: "old-testament",     label: "Old Testament",         img: `${CDN}/Forums/thumbs/Old%20Testament%20(2).png` },
  { id: "new-testament",     label: "New Testament",         img: `${CDN}/Forums/thumbs/New%20Testament%20(2).png` },
  { id: "the-path",          label: "The Path",              img: `${CDN}/Forums/thumbs/thepath%20(2).png` },
  { id: "blessings",         label: "Blessings",             img: `${CDN}/Forums/thumbs/Blessings.png` },
  { id: "prayer-reflection", label: "Prayer & Reflection",   img: `${CDN}/Forums/thumbs/prayerandreflection.png` },
  { id: "bible-study",       label: "Bible Study",           img: `${CDN}/Forums/thumbs/Biblestudy.png` },
  { id: "questions-insight", label: "Questions for Insight", img: `${CDN}/Forums/thumbs/questionsforinsight.png` },
];

function ttCategoryInfo(key) {
  return TT_FORUM_CATEGORIES.find((c) => c.id === key) || { id: key, label: key, img: null };
}

// Blessing ids in the cloud tables are numeric strings ("1".."12").
function ttBlessingName(blessingId) {
  const t = TRIBES[Number(blessingId) - 1];
  return t ? t.name : (blessingId ? `Blessing ${blessingId}` : "");
}

// Relative timestamps — "Just now", "5m ago", "3h ago", "2d ago", "Mar 4".
function ttTimeAgo(iso) {
  if (!iso) return "";
  const then = new Date(iso).getTime();
  if (!isFinite(then)) return "";
  const s = Math.max(0, (Date.now() - then) / 1000);
  if (s < 60) return "Just now";
  if (s < 3600) return `${Math.floor(s / 60)}m ago`;
  if (s < 86400) return `${Math.floor(s / 3600)}h ago`;
  if (s < 86400 * 7) return `${Math.floor(s / 86400)}d ago`;
  const d = new Date(then);
  return d.toLocaleDateString(undefined, { month: "short", day: "numeric" });
}

// =============================================================================
// DATA LAYER — same query shapes as the app's cloud services.
// Fetch rows plain → one profiles .in() lookup → merge author names/avatars.
// =============================================================================
async function ttFetchProfiles(userIds) {
  const unique = [...new Set(userIds)].filter(Boolean);
  if (unique.length === 0) return {};
  const { data } = await window.sb
    .from("profiles")
    .select("id, display_name, avatar_url")
    .in("id", unique);
  const map = {};
  (data || []).forEach((p) => {
    map[p.id] = { name: p.display_name || "Anonymous", avatar: p.avatar_url || null };
  });
  return map;
}

const ttCommunityApi = {
  /** Browse posts (optionally per category) with authors + reply/bless counts. Public read. */
  async browseForumPosts(category) {
    let q = window.sb
      .from("forum_posts")
      .select("*, forum_replies(count), forum_post_blessings(count)")
      .order("is_pinned", { ascending: false })
      .order("created_at", { ascending: false });
    if (category) q = q.eq("category", category);
    const { data, error } = await q;
    if (error) throw new Error(error.message);
    const rows = data || [];
    const profiles = await ttFetchProfiles(rows.map((r) => r.user_id));
    return rows
      .map((row) => ({
        ...row,
        author_name: profiles[row.user_id]?.name || "Anonymous",
        author_avatar: profiles[row.user_id]?.avatar || null,
        reply_count: row.forum_replies?.[0]?.count ?? 0,
        blessing_count: row.forum_post_blessings?.[0]?.count ?? 0,
        forum_replies: undefined,
        forum_post_blessings: undefined,
      }))
      .filter((p) => !p.moderation_status || p.moderation_status === "active");
  },

  /** Single post with author + counts. Public read. */
  async getForumPost(postId) {
    const { data, error } = await window.sb
      .from("forum_posts")
      .select("*, forum_replies(count), forum_post_blessings(count)")
      .eq("id", postId)
      .single();
    if (error) throw new Error(error.message);
    const profiles = await ttFetchProfiles([data.user_id]);
    return {
      ...data,
      author_name: profiles[data.user_id]?.name || "Anonymous",
      author_avatar: profiles[data.user_id]?.avatar || null,
      reply_count: data.forum_replies?.[0]?.count ?? 0,
      blessing_count: data.forum_post_blessings?.[0]?.count ?? 0,
      forum_replies: undefined,
      forum_post_blessings: undefined,
    };
  },

  /** Replies for a post, oldest first, enriched. Public read. */
  async getForumReplies(postId) {
    const { data, error } = await window.sb
      .from("forum_replies")
      .select("*")
      .eq("post_id", postId)
      .order("created_at");
    if (error) throw new Error(error.message);
    const rows = data || [];
    const profiles = await ttFetchProfiles(rows.map((r) => r.user_id));
    return rows
      .map((row) => ({
        ...row,
        author_name: profiles[row.user_id]?.name || "Anonymous",
        author_avatar: profiles[row.user_id]?.avatar || null,
      }))
      .filter((r) => !r.moderation_status || r.moderation_status === "active");
  },

  /** Create a post (requires auth). Server RLS/moderation still applies. */
  async createForumPost(userId, input) {
    const { data, error } = await window.sb
      .from("forum_posts")
      .insert({ user_id: userId, title: input.title, body: input.body, category: input.category, blessing_id: input.blessingId || null })
      .select()
      .single();
    if (error) throw new Error(error.message);
    return data;
  },

  /** Create a reply (requires auth). */
  async createForumReply(userId, postId, body) {
    const { data, error } = await window.sb
      .from("forum_replies")
      .insert({ post_id: postId, user_id: userId, body })
      .select()
      .single();
    if (error) throw new Error(error.message);
    return data;
  },

  /** Bless / unbless a post (requires auth). */
  async blessPost(userId, postId) {
    const { error } = await window.sb
      .from("forum_post_blessings")
      .upsert({ post_id: postId, user_id: userId }, { onConflict: "post_id,user_id" });
    if (error) throw new Error(error.message);
  },
  async unblessPost(userId, postId) {
    const { error } = await window.sb
      .from("forum_post_blessings")
      .delete()
      .eq("post_id", postId)
      .eq("user_id", userId);
    if (error) throw new Error(error.message);
  },

  /** Which of these posts has the current user blessed? Empty set for guests. */
  async getUserBlessedPostIds(postIds) {
    try {
      if (!postIds.length) return new Set();
      const { data: s } = await window.sb.auth.getSession();
      const uid = s.session?.user?.id;
      if (!uid) return new Set();
      const { data, error } = await window.sb
        .from("forum_post_blessings")
        .select("post_id")
        .eq("user_id", uid)
        .in("post_id", postIds);
      if (error) return new Set();
      return new Set((data || []).map((r) => r.post_id));
    } catch {
      return new Set();
    }
  },

  /** Live post counts per category (active posts only). Cheap: two columns. */
  async getForumCategoryCounts() {
    const { data, error } = await window.sb
      .from("forum_posts")
      .select("category, moderation_status");
    if (error) throw new Error(error.message);
    const counts = {};
    (data || []).forEach((r) => {
      if (r.moderation_status && r.moderation_status !== "active") return;
      counts[r.category] = (counts[r.category] || 0) + 1;
    });
    return counts;
  },

  /** Shared reflections (newest first), enriched. Public read. */
  async browseSharedReflections(blessingId) {
    let q = window.sb
      .from("shared_reflections")
      .select("*")
      .order("created_at", { ascending: false })
      .limit(50);
    if (blessingId) q = q.eq("blessing_id", blessingId);
    const { data, error } = await q;
    if (error) throw new Error(error.message);
    const rows = data || [];
    const profiles = await ttFetchProfiles(rows.map((r) => r.user_id));
    return rows.map((r) => ({
      ...r,
      author_name: profiles[r.user_id]?.name || "Anonymous",
      author_avatar: profiles[r.user_id]?.avatar || null,
    }));
  },

  /** Shared video testimonies (newest first), enriched. Public read. */
  async browseTestimonies() {
    const { data, error } = await window.sb
      .from("shared_testimonies")
      .select("*")
      .order("created_at", { ascending: false })
      .range(0, 19);
    if (error) throw new Error(error.message);
    const rows = data || [];
    const profiles = await ttFetchProfiles(rows.map((r) => r.user_id));
    return rows.map((r) => ({
      ...r,
      author_name: profiles[r.user_id]?.name || "Anonymous",
      author_avatar: profiles[r.user_id]?.avatar || null,
    }));
  },

  /** Per-blessing discussion thread. Public read. blessingId is "1".."12". */
  async browseBlessingDiscussions(blessingId) {
    const { data, error } = await window.sb
      .from("blessing_discussions")
      .select("*")
      .eq("blessing_id", blessingId)
      .order("created_at", { ascending: false });
    if (error) throw new Error(error.message);
    const rows = (data || []).filter((d) => !d.moderation_status || d.moderation_status === "active");
    const profiles = await ttFetchProfiles(rows.map((r) => r.user_id));
    return rows.map((r) => ({
      ...r,
      author_name: profiles[r.user_id]?.name || "Anonymous",
      author_avatar: profiles[r.user_id]?.avatar || null,
    }));
  },

  /** Add to a blessing discussion (requires auth). */
  async createBlessingDiscussion(userId, blessingId, body) {
    const { data, error } = await window.sb
      .from("blessing_discussions")
      .insert({ user_id: userId, blessing_id: blessingId, body })
      .select()
      .single();
    if (error) throw new Error(error.message);
    return data;
  },
};

// =============================================================================
// SMALL SHARED UI
// =============================================================================
const ttInputStyle = {
  width: "100%", padding: "12px 14px",
  background: T.bg, color: T.paper,
  border: `1px solid ${T.gold}33`,
  fontFamily: "'Cormorant Garamond', serif", fontSize: 16,
  outline: "none", boxSizing: "border-box",
};

function TTAvatar({ name, avatar, size = 32 }) {
  if (avatar) {
    return <img src={avatar} alt={name || "Author"} style={{ width: size, height: size, borderRadius: "50%", objectFit: "cover", flexShrink: 0 }} />;
  }
  return (
    <div style={{
      width: size, height: size, borderRadius: "50%", flexShrink: 0,
      background: `linear-gradient(135deg, ${T.gold}, ${T.goldDeep})`, color: T.ink,
      display: "flex", alignItems: "center", justifyContent: "center",
      fontFamily: "'Cinzel', serif", fontWeight: 600, fontSize: Math.round(size * 0.44),
    }}>{(name || "A").slice(0, 1).toUpperCase()}</div>
  );
}

// Inline "sign in to write" prompt — same look as the Progress/Profile banner.
function TTSignInCard({ nav, headline = "Sign in to join the conversation", body = "Reading is open to everyone. Writing requires a free account — the same one you use in the app." }) {
  return (
    <div style={{ padding: 28, background: `${T.gold}10`, border: `1px solid ${T.gold}44` }}>
      <SmallCaps color={T.gold}>{headline}</SmallCaps>
      <p style={{ marginTop: 8, fontFamily: "'Cormorant Garamond', serif", fontSize: 16, color: T.paperDim, fontStyle: "italic", marginBottom: 0 }}>
        {body}
      </p>
      <div style={{ marginTop: 16, display: "flex", gap: 10, flexWrap: "wrap" }}>
        <GoldButton small onClick={() => nav("auth")}>Sign in</GoldButton>
        <GoldButton small secondary onClick={() => nav("auth", { mode: "signup" })}>Create account</GoldButton>
      </div>
    </div>
  );
}

function TTAuthorLine({ name, avatar, when, extra }) {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
      <TTAvatar name={name} avatar={avatar} />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontFamily: "'Cinzel', serif", fontSize: 13, color: T.paper, letterSpacing: "0.04em" }}>{name}</div>
        <div style={{ fontSize: 11, color: T.paperFaint, fontFamily: "'Cormorant Garamond', serif", fontStyle: "italic" }}>
          {when}{extra ? <> · {extra}</> : null}
        </div>
      </div>
    </div>
  );
}

// =============================================================================
// FORUM — category listing (#community/:category)
// =============================================================================
function ForumCategoryPage({ nav, params }) {
  const category = params?.category || "general";
  const info = ttCategoryInfo(category);
  const { session } = useSession();

  const [posts, setPosts] = useState(null);
  const [state, setState] = useState("loading"); // loading | loaded | error
  const [draftTitle, setDraftTitle] = useState("");
  const [draftBody, setDraftBody] = useState("");
  const [posting, setPosting] = useState(false);
  const [postError, setPostError] = useState(null);

  useEffect(() => {
    let alive = true;
    setState("loading");
    setPosts(null);
    ttCommunityApi.browseForumPosts(category)
      .then((rows) => { if (alive) { setPosts(rows); setState("loaded"); } })
      .catch(() => { if (alive) setState("error"); });
    return () => { alive = false; };
  }, [category]);

  async function submitPost() {
    if (!session || !draftTitle.trim() || !draftBody.trim() || posting) return;
    setPosting(true);
    setPostError(null);
    try {
      const row = await ttCommunityApi.createForumPost(session.user.id, {
        title: draftTitle.trim(), body: draftBody.trim(), category,
      });
      const enriched = {
        ...row,
        author_name: sessionDisplayName(session), author_avatar: null,
        reply_count: 0, blessing_count: 0,
      };
      setPosts((prev) => [enriched, ...(prev || [])]);
      setDraftTitle("");
      setDraftBody("");
    } catch (e) {
      setPostError(e.message || "Could not publish the post.");
    }
    setPosting(false);
  }

  return (
    <div style={{ background: T.bg, color: T.paper }}>
      {/* Category banner */}
      <section style={{ position: "relative", overflow: "hidden", borderBottom: `1px solid ${T.gold}1a` }}>
        {info.img && (
          <img src={info.img} alt={info.label} style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", opacity: 0.25 }} />
        )}
        <div style={{ position: "absolute", inset: 0, background: `linear-gradient(180deg, ${T.bg}88 0%, ${T.bg} 100%)` }} />
        <div style={{ position: "relative", maxWidth: 1100, margin: "0 auto", padding: "110px 48px 46px" }}>
          <button onClick={() => nav("community")} style={{ background: "transparent", border: "none", color: T.paperDim, cursor: "pointer", fontFamily: "'Cinzel', serif", fontSize: 11, letterSpacing: "0.24em", textTransform: "uppercase", marginBottom: 20, padding: 0 }}>
            ← Community
          </button>
          <div>
            <SmallCaps color={T.gold} letterSpacing="0.4em">The Forum</SmallCaps>
          </div>
          <h1 style={{ fontFamily: "'Cinzel', serif", fontSize: 56, fontWeight: 500, margin: "14px 0 8px", color: T.paper, letterSpacing: "0.02em", lineHeight: 1 }}>
            {info.label}
          </h1>
          <p style={{ margin: 0, fontSize: 18, color: T.paperDim, fontStyle: "italic", fontFamily: "'Cormorant Garamond', serif" }}>
            {state === "loaded" ? `${posts.length} ${posts.length === 1 ? "conversation" : "conversations"}` : " "}
          </p>
        </div>
      </section>

      <section style={{ padding: "48px 48px 100px" }}>
        <div style={{ maxWidth: 1100, margin: "0 auto" }}>

          {/* Composer */}
          <div style={{ marginBottom: 40 }}>
            <SmallCaps color={T.goldDeep}>Start a conversation</SmallCaps>
            <div style={{ marginTop: 16 }}>
              {session ? (
                <div style={{ padding: 24, background: T.bgRise, border: `1px solid ${T.gold}22` }}>
                  <input
                    value={draftTitle}
                    onChange={(e) => setDraftTitle(e.target.value)}
                    placeholder="Title"
                    style={ttInputStyle}
                  />
                  <textarea
                    value={draftBody}
                    onChange={(e) => setDraftBody(e.target.value)}
                    placeholder={`Share something with the ${info.label} forum…`}
                    rows={4}
                    style={{ ...ttInputStyle, marginTop: 10, resize: "vertical", lineHeight: 1.5 }}
                  />
                  {postError && (
                    <p style={{ margin: "10px 0 0", color: "#e08b8b", fontFamily: "'Cormorant Garamond', serif", fontSize: 15, fontStyle: "italic" }}>{postError}</p>
                  )}
                  <div style={{ marginTop: 14, display: "flex", justifyContent: "space-between", alignItems: "center", gap: 12, flexWrap: "wrap" }}>
                    <span style={{ fontSize: 13, color: T.paperFaint, fontFamily: "'Cormorant Garamond', serif", fontStyle: "italic" }}>
                      Posting as {sessionDisplayName(session)} · {info.label}
                    </span>
                    <GoldButton small onClick={submitPost} style={{ opacity: draftTitle.trim() && draftBody.trim() && !posting ? 1 : 0.5 }}>
                      {posting ? "Publishing…" : "Publish post"}
                    </GoldButton>
                  </div>
                </div>
              ) : (
                <TTSignInCard nav={nav} headline="Sign in to post" body="Reading the forum is open to everyone. Starting a conversation requires a free account — the same one you use in the app." />
              )}
            </div>
          </div>

          {/* Posts */}
          <SmallCaps color={T.goldDeep}>Conversations</SmallCaps>
          <div style={{ marginTop: 16, display: "grid", gap: 14 }}>
            {state === "loading" && (
              <div style={{ padding: 32, background: T.bgRise, border: `1px solid ${T.gold}22`, textAlign: "center" }}>
                <p style={{ margin: 0, color: T.paperFaint, fontStyle: "italic", fontFamily: "'Cormorant Garamond', serif", fontSize: 16 }}>Loading conversations…</p>
              </div>
            )}
            {state === "error" && (
              <div style={{ padding: 32, background: T.bgRise, border: `1px solid ${T.gold}22`, textAlign: "center" }}>
                <p style={{ margin: 0, color: T.paperDim, fontStyle: "italic", fontFamily: "'Cormorant Garamond', serif", fontSize: 16 }}>
                  The forum couldn't be reached. Check your connection and try again.
                </p>
              </div>
            )}
            {state === "loaded" && posts.length === 0 && (
              <div style={{ padding: 32, background: T.bgRise, border: `1px dashed ${T.gold}44`, textAlign: "center" }}>
                <p style={{ margin: 0, color: T.paperDim, fontStyle: "italic", fontFamily: "'Cormorant Garamond', serif", fontSize: 16 }}>
                  No conversations here yet. Be the first to start one.
                </p>
              </div>
            )}
            {state === "loaded" && posts.map((p) => (
              <div
                key={p.id}
                onClick={() => nav("communityPost", { id: p.id })}
                style={{ padding: "22px 26px", background: T.bgRise, border: `1px solid ${T.gold}22`, cursor: "pointer", transition: "all 0.15s" }}
                onMouseEnter={(e) => { e.currentTarget.style.borderColor = T.gold + "66"; }}
                onMouseLeave={(e) => { e.currentTarget.style.borderColor = T.gold + "22"; }}
              >
                <TTAuthorLine
                  name={p.author_name}
                  avatar={p.author_avatar}
                  when={ttTimeAgo(p.created_at)}
                  extra={p.blessing_id ? ttBlessingName(p.blessing_id) : null}
                />
                <h3 style={{ margin: "14px 0 8px", fontFamily: "'Cinzel', serif", fontSize: 20, fontWeight: 500, color: T.paper, letterSpacing: "0.02em", lineHeight: 1.25 }}>
                  {p.is_pinned ? <span style={{ color: T.gold, marginRight: 8 }}>◆</span> : null}{p.title}
                </h3>
                <p style={{
                  margin: 0, fontFamily: "'Cormorant Garamond', serif", fontSize: 16, lineHeight: 1.55, color: T.paperDim,
                  display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", overflow: "hidden",
                }}>
                  {p.body}
                </p>
                <div style={{ marginTop: 14, display: "flex", gap: 18, fontSize: 12, color: T.paperFaint, fontFamily: "'Cinzel', serif", letterSpacing: "0.14em", textTransform: "uppercase" }}>
                  <span style={{ color: p.blessing_count ? T.gold : T.paperFaint }}>✦ {p.blessing_count} {p.blessing_count === 1 ? "Blessing" : "Blessings"}</span>
                  <span>✉ {p.reply_count} {p.reply_count === 1 ? "Reply" : "Replies"}</span>
                </div>
              </div>
            ))}
          </div>

          {/* Other categories */}
          <div style={{ marginTop: 56 }}>
            <SmallCaps color={T.goldDeep}>Other categories</SmallCaps>
            <div style={{ marginTop: 14, display: "flex", gap: 8, flexWrap: "wrap" }}>
              {TT_FORUM_CATEGORIES.filter((c) => c.id !== category).map((c) => (
                <button key={c.id} onClick={() => nav("communityCategory", { category: c.id })}
                  style={{ background: "transparent", border: `1px solid ${T.gold}33`, color: T.paperDim, padding: "8px 16px", fontFamily: "'Cinzel', serif", fontSize: 11, letterSpacing: "0.18em", textTransform: "uppercase", cursor: "pointer" }}
                  onMouseEnter={(e) => { e.currentTarget.style.borderColor = T.gold; e.currentTarget.style.color = T.gold; }}
                  onMouseLeave={(e) => { e.currentTarget.style.borderColor = T.gold + "33"; e.currentTarget.style.color = T.paperDim; }}
                >
                  {c.label}
                </button>
              ))}
            </div>
          </div>

        </div>
      </section>
    </div>
  );
}

// =============================================================================
// FORUM — post detail (#community/post/:id)
// =============================================================================
function ForumPostPage({ nav, params }) {
  const postId = params?.id;
  const { session } = useSession();

  const [post, setPost] = useState(null);
  const [replies, setReplies] = useState(null);
  const [state, setState] = useState("loading"); // loading | loaded | error
  const [blessed, setBlessed] = useState(false);
  const [blessCount, setBlessCount] = useState(0);
  const [blessBusy, setBlessBusy] = useState(false);
  const [draft, setDraft] = useState("");
  const [replying, setReplying] = useState(false);
  const [replyError, setReplyError] = useState(null);

  useEffect(() => {
    if (!postId) { setState("error"); return; }
    let alive = true;
    setState("loading");
    Promise.all([
      ttCommunityApi.getForumPost(postId),
      ttCommunityApi.getForumReplies(postId),
      ttCommunityApi.getUserBlessedPostIds([postId]),
    ])
      .then(([p, rs, blessedIds]) => {
        if (!alive) return;
        setPost(p);
        setReplies(rs);
        setBlessCount(p.blessing_count || 0);
        setBlessed(blessedIds.has(postId));
        setState("loaded");
      })
      .catch(() => { if (alive) setState("error"); });
    return () => { alive = false; };
  }, [postId, session?.user?.id]);

  async function toggleBless() {
    if (!session) { nav("auth"); return; }
    if (blessBusy || !post) return;
    setBlessBusy(true);
    const next = !blessed;
    // Optimistic flip, reverted on failure.
    setBlessed(next);
    setBlessCount((c) => Math.max(0, c + (next ? 1 : -1)));
    try {
      if (next) await ttCommunityApi.blessPost(session.user.id, postId);
      else await ttCommunityApi.unblessPost(session.user.id, postId);
    } catch {
      setBlessed(!next);
      setBlessCount((c) => Math.max(0, c + (next ? -1 : 1)));
    }
    setBlessBusy(false);
  }

  async function submitReply() {
    if (!session || !draft.trim() || replying) return;
    setReplying(true);
    setReplyError(null);
    try {
      const row = await ttCommunityApi.createForumReply(session.user.id, postId, draft.trim());
      setReplies((prev) => [...(prev || []), { ...row, author_name: sessionDisplayName(session), author_avatar: null }]);
      setDraft("");
    } catch (e) {
      setReplyError(e.message || "Could not post the reply.");
    }
    setReplying(false);
  }

  const catInfo = post ? ttCategoryInfo(post.category) : null;

  return (
    <div style={{ background: T.bg, color: T.paper }}>
      <section style={{ padding: "110px 48px 100px" }}>
        <div style={{ maxWidth: 900, margin: "0 auto" }}>

          <button
            onClick={() => (post ? nav("communityCategory", { category: post.category }) : nav("community"))}
            style={{ background: "transparent", border: "none", color: T.paperDim, cursor: "pointer", fontFamily: "'Cinzel', serif", fontSize: 11, letterSpacing: "0.24em", textTransform: "uppercase", marginBottom: 28, padding: 0 }}
          >
            ← {catInfo ? catInfo.label : "Community"}
          </button>

          {state === "loading" && (
            <div style={{ padding: 40, background: T.bgRise, border: `1px solid ${T.gold}22`, textAlign: "center" }}>
              <p style={{ margin: 0, color: T.paperFaint, fontStyle: "italic", fontFamily: "'Cormorant Garamond', serif", fontSize: 16 }}>Loading the conversation…</p>
            </div>
          )}
          {state === "error" && (
            <div style={{ padding: 40, background: T.bgRise, border: `1px solid ${T.gold}22`, textAlign: "center" }}>
              <p style={{ margin: 0, color: T.paperDim, fontStyle: "italic", fontFamily: "'Cormorant Garamond', serif", fontSize: 16 }}>
                This post couldn't be loaded. It may have been removed.
              </p>
            </div>
          )}

          {state === "loaded" && post && (
            <>
              {/* Post */}
              <div style={{ padding: "30px 32px", background: T.bgRise, border: `1px solid ${T.gold}33` }}>
                <SmallCaps color={T.goldDeep} size={10}>{catInfo.label}{post.blessing_id ? ` · ${ttBlessingName(post.blessing_id)}` : ""}</SmallCaps>
                <h1 style={{ fontFamily: "'Cinzel', serif", fontSize: 34, fontWeight: 500, margin: "14px 0 18px", color: T.paper, letterSpacing: "0.02em", lineHeight: 1.15 }}>
                  {post.is_pinned ? <span style={{ color: T.gold, marginRight: 10 }}>◆</span> : null}{post.title}
                </h1>
                <TTAuthorLine name={post.author_name} avatar={post.author_avatar} when={ttTimeAgo(post.created_at)} />
                <p style={{ margin: "20px 0 0", fontFamily: "'Cormorant Garamond', serif", fontSize: 18, lineHeight: 1.65, color: T.paperDim, whiteSpace: "pre-wrap" }}>
                  {post.body}
                </p>
                <div style={{ marginTop: 24, display: "flex", alignItems: "center", gap: 16, flexWrap: "wrap" }}>
                  <button
                    onClick={toggleBless}
                    title={session ? (blessed ? "Remove your blessing" : "Bless this post") : "Sign in to bless"}
                    style={{
                      background: blessed ? T.gold : "transparent",
                      color: blessed ? T.ink : T.gold,
                      border: `1px solid ${T.gold}${blessed ? "" : "55"}`,
                      padding: "10px 20px", cursor: "pointer",
                      fontFamily: "'Cinzel', serif", fontSize: 11, letterSpacing: "0.2em", textTransform: "uppercase",
                      fontWeight: blessed ? 700 : 500, transition: "all 0.15s",
                    }}
                  >
                    ✦ {blessed ? "Blessed" : "Bless"} · {blessCount}
                  </button>
                  <span style={{ fontSize: 12, color: T.paperFaint, fontFamily: "'Cinzel', serif", letterSpacing: "0.14em", textTransform: "uppercase" }}>
                    ✉ {(replies || []).length} {(replies || []).length === 1 ? "Reply" : "Replies"}
                  </span>
                </div>
              </div>

              {/* Replies */}
              <div style={{ marginTop: 40 }}>
                <SmallCaps color={T.goldDeep}>Replies</SmallCaps>
                <div style={{ marginTop: 16, display: "grid", gap: 12 }}>
                  {(replies || []).length === 0 && (
                    <div style={{ padding: 24, background: T.bgRise, border: `1px dashed ${T.gold}44` }}>
                      <p style={{ margin: 0, color: T.paperDim, fontStyle: "italic", fontFamily: "'Cormorant Garamond', serif", fontSize: 16 }}>
                        No replies yet. Say the first word.
                      </p>
                    </div>
                  )}
                  {(replies || []).map((r) => (
                    <div key={r.id} style={{ padding: "18px 22px", background: T.bgRise, border: `1px solid ${T.gold}22` }}>
                      <TTAuthorLine name={r.author_name} avatar={r.author_avatar} when={ttTimeAgo(r.created_at)} />
                      <p style={{ margin: "12px 0 0", fontFamily: "'Cormorant Garamond', serif", fontSize: 16, lineHeight: 1.6, color: T.paperDim, whiteSpace: "pre-wrap" }}>
                        {r.body}
                      </p>
                    </div>
                  ))}
                </div>

                {/* Reply composer */}
                <div style={{ marginTop: 24 }}>
                  {session ? (
                    <div style={{ padding: 20, background: T.bgRise, border: `1px solid ${T.gold}22` }}>
                      <textarea
                        value={draft}
                        onChange={(e) => setDraft(e.target.value)}
                        placeholder="Write a reply…"
                        rows={3}
                        style={{ ...ttInputStyle, resize: "vertical", lineHeight: 1.5 }}
                      />
                      {replyError && (
                        <p style={{ margin: "10px 0 0", color: "#e08b8b", fontFamily: "'Cormorant Garamond', serif", fontSize: 15, fontStyle: "italic" }}>{replyError}</p>
                      )}
                      <div style={{ marginTop: 12, display: "flex", justifyContent: "flex-end" }}>
                        <GoldButton small onClick={submitReply} style={{ opacity: draft.trim() && !replying ? 1 : 0.5 }}>
                          {replying ? "Posting…" : "Post reply"}
                        </GoldButton>
                      </div>
                    </div>
                  ) : (
                    <TTSignInCard nav={nav} headline="Sign in to reply" />
                  )}
                </div>
              </div>
            </>
          )}

        </div>
      </section>
    </div>
  );
}

// =============================================================================
// SHARED REFLECTIONS (#community/reflections)
// =============================================================================
function CommunityReflectionsPage({ nav }) {
  const { session } = useSession();
  const [reflections, setReflections] = useState(null);
  const [state, setState] = useState("loading"); // loading | loaded | error

  useEffect(() => {
    let alive = true;
    ttCommunityApi.browseSharedReflections()
      .then((rows) => { if (alive) { setReflections(rows); setState("loaded"); } })
      .catch(() => { if (alive) setState("error"); });
    return () => { alive = false; };
  }, []);

  return (
    <div style={{ background: T.bg, color: T.paper }}>
      <PageHeader
        eyebrow="Walk together"
        title="Shared"
        accent="Reflections."
        subtitle="Journal entries and video reflections the community has chosen to share — one blessing at a time."
      />

      <section style={{ padding: "48px 48px 100px" }}>
        <div style={{ maxWidth: 1500, margin: "0 auto" }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 16, flexWrap: "wrap" }}>
            <SmallCaps color={T.goldDeep}>
              {state === "loaded" ? `${reflections.length} ${reflections.length === 1 ? "reflection" : "reflections"}` : "From the community"}
            </SmallCaps>
            <button onClick={() => nav("community")} style={{ background: "transparent", border: "none", color: T.paperDim, cursor: "pointer", fontFamily: "'Cinzel', serif", fontSize: 11, letterSpacing: "0.24em", textTransform: "uppercase", padding: 0 }}>
              ← Community
            </button>
          </div>

          <div style={{ marginTop: 20, display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 18 }}>
            {state === "loading" && (
              <div style={{ gridColumn: "1 / -1", padding: 40, background: T.bgRise, border: `1px solid ${T.gold}22`, textAlign: "center" }}>
                <p style={{ margin: 0, color: T.paperFaint, fontStyle: "italic", fontFamily: "'Cormorant Garamond', serif", fontSize: 16 }}>Loading reflections…</p>
              </div>
            )}
            {state === "error" && (
              <div style={{ gridColumn: "1 / -1", padding: 40, background: T.bgRise, border: `1px solid ${T.gold}22`, textAlign: "center" }}>
                <p style={{ margin: 0, color: T.paperDim, fontStyle: "italic", fontFamily: "'Cormorant Garamond', serif", fontSize: 16 }}>
                  Reflections couldn't be reached. Check your connection and try again.
                </p>
              </div>
            )}
            {state === "loaded" && reflections.length === 0 && (
              <div style={{ gridColumn: "1 / -1", padding: 40, background: T.bgRise, border: `1px dashed ${T.gold}44`, textAlign: "center" }}>
                <p style={{ margin: 0, color: T.paperDim, fontStyle: "italic", fontFamily: "'Cormorant Garamond', serif", fontSize: 16 }}>
                  Nothing shared yet. Reflections shared from the app will appear here.
                </p>
              </div>
            )}
            {state === "loaded" && reflections.map((r) => (
              <div key={r.id} style={{ padding: "20px 22px", background: T.bgRise, border: `1px solid ${T.gold}22`, display: "flex", flexDirection: "column", gap: 12 }}>
                <TTAuthorLine
                  name={r.author_name}
                  avatar={r.author_avatar}
                  when={ttTimeAgo(r.created_at)}
                  extra={ttBlessingName(r.blessing_id)}
                />
                {r.prompt_title && (
                  <div style={{ padding: "10px 14px", borderLeft: `3px solid ${T.gold}`, background: `${T.gold}08` }}>
                    <p style={{ margin: 0, fontFamily: "'Cormorant Garamond', serif", fontSize: 14, fontStyle: "italic", color: T.gold }}>{r.prompt_title}</p>
                  </div>
                )}
                {(r.media_type === "video" || r.media_type === "audio") && r.media_url ? (
                  r.media_type === "video" ? (
                    <video src={r.media_url} controls preload="metadata" poster={r.poster_url || undefined} style={{ width: "100%", maxHeight: 320, background: T.ink }} />
                  ) : (
                    <audio src={r.media_url} controls style={{ width: "100%" }} />
                  )
                ) : null}
                {r.body && (
                  <p style={{ margin: 0, fontFamily: "'Cormorant Garamond', serif", fontSize: 16, lineHeight: 1.55, color: T.paperDim, fontStyle: "italic" }}>
                    &ldquo;{r.body}&rdquo;
                  </p>
                )}
              </div>
            ))}
          </div>

          {/* Sharing happens in the app / after sign-in */}
          {!session && (
            <div style={{ marginTop: 36, maxWidth: 640 }}>
              <TTSignInCard
                nav={nav}
                headline="Sign in to share"
                body="Reflections are shared from your journal in the TribeTruth app. Sign in on the web to keep your account in step."
              />
            </div>
          )}
        </div>
      </section>
    </div>
  );
}

// =============================================================================
// BLESSING DISCUSSION — wired section used by BlessingDetail (pages-detail.jsx)
// blessingId is the cloud id: "1".."12" (String(tribe.n)).
// =============================================================================
function BlessingDiscussionSection({ blessingId, nav }) {
  const { session } = useSession();
  const [entries, setEntries] = useState(null);
  const [state, setState] = useState("loading"); // loading | loaded | error
  const [draft, setDraft] = useState("");
  const [posting, setPosting] = useState(false);
  const [postError, setPostError] = useState(null);

  useEffect(() => {
    let alive = true;
    setState("loading");
    setEntries(null);
    ttCommunityApi.browseBlessingDiscussions(blessingId)
      .then((rows) => { if (alive) { setEntries(rows); setState("loaded"); } })
      .catch(() => { if (alive) setState("error"); });
    return () => { alive = false; };
  }, [blessingId]);

  async function submit() {
    if (!session || !draft.trim() || posting) return;
    setPosting(true);
    setPostError(null);
    try {
      const row = await ttCommunityApi.createBlessingDiscussion(session.user.id, blessingId, draft.trim());
      setEntries((prev) => [{ ...row, author_name: sessionDisplayName(session), author_avatar: null }, ...(prev || [])]);
      setDraft("");
    } catch (e) {
      setPostError(e.message || "Could not post to the discussion.");
    }
    setPosting(false);
  }

  return (
    <div style={{ marginTop: 18 }}>
      {/* Composer */}
      {session ? (
        <div style={{ padding: 20, background: T.bgRise, border: `1px solid ${T.gold}22`, marginBottom: 14 }}>
          <textarea
            value={draft}
            onChange={(e) => setDraft(e.target.value)}
            placeholder="What is this blessing teaching you?"
            rows={3}
            style={{ ...ttInputStyle, resize: "vertical", lineHeight: 1.5 }}
          />
          {postError && (
            <p style={{ margin: "10px 0 0", color: "#e08b8b", fontFamily: "'Cormorant Garamond', serif", fontSize: 15, fontStyle: "italic" }}>{postError}</p>
          )}
          <div style={{ marginTop: 12, display: "flex", justifyContent: "space-between", alignItems: "center", gap: 12, flexWrap: "wrap" }}>
            <span style={{ fontSize: 13, color: T.paperFaint, fontFamily: "'Cormorant Garamond', serif", fontStyle: "italic" }}>
              Posting as {sessionDisplayName(session)} · shared with the app community
            </span>
            <GoldButton small onClick={submit} style={{ opacity: draft.trim() && !posting ? 1 : 0.5 }}>
              {posting ? "Posting…" : "Post"}
            </GoldButton>
          </div>
        </div>
      ) : (
        <div style={{ marginBottom: 14 }}>
          <TTSignInCard nav={nav} headline="Sign in to join the discussion" body="Reading is open to everyone. Adding your voice requires a free account — the same conversations sync to the mobile app." />
        </div>
      )}

      {/* Entries */}
      {state === "loading" && (
        <div style={{ padding: 24, background: T.bgRise, border: `1px solid ${T.gold}22` }}>
          <p style={{ margin: 0, color: T.paperFaint, fontStyle: "italic", fontFamily: "'Cormorant Garamond', serif", fontSize: 16 }}>Loading discussion…</p>
        </div>
      )}
      {state === "error" && (
        <div style={{ padding: 24, background: T.bgRise, border: `1px solid ${T.gold}22` }}>
          <p style={{ margin: 0, color: T.paperDim, fontStyle: "italic", fontFamily: "'Cormorant Garamond', serif", fontSize: 16 }}>
            The discussion couldn't be reached. Check your connection and try again.
          </p>
        </div>
      )}
      {state === "loaded" && entries.length === 0 && (
        <div style={{ padding: 24, background: T.bgRise, border: `1px dashed ${T.gold}44` }}>
          <p style={{ margin: 0, color: T.paperDim, fontStyle: "italic", fontFamily: "'Cormorant Garamond', serif", fontSize: 16 }}>
            No one has written here yet this month. Begin the conversation.
          </p>
        </div>
      )}
      {state === "loaded" && entries.length > 0 && (
        <div style={{ display: "grid", gap: 12 }}>
          {entries.map((d) => (
            <div key={d.id} style={{ padding: "18px 22px", background: T.bgRise, border: `1px solid ${T.gold}22` }}>
              <TTAuthorLine name={d.author_name} avatar={d.author_avatar} when={ttTimeAgo(d.created_at)} />
              <p style={{ margin: "12px 0 0", fontFamily: "'Cormorant Garamond', serif", fontSize: 16, lineHeight: 1.6, color: T.paperDim, whiteSpace: "pre-wrap" }}>
                {d.body}
              </p>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

Object.assign(window, {
  TT_FORUM_CATEGORIES, ttCommunityApi, ttTimeAgo, ttBlessingName, ttCategoryInfo,
  ForumCategoryPage, ForumPostPage, CommunityReflectionsPage,
  BlessingDiscussionSection, TTSignInCard, TTAvatar, TTAuthorLine,
});
