// Circles — community destinations
//   /#circles            — discovery (all visible circles, with Join buttons)
//   /#circle:<slug>      — single circle (cover, about, pinned welcome, feed)
//
// Visibility model:
//   • All circles show in discovery. Pathway-gated circles whose pathway is
//     NOT active appear as "Coming soon" — clicking Join adds the user to
//     a notification waitlist (schema_v18 circle_open_waitlist) instead of
//     creating a real membership. When Jamie activates the pathway, she runs
//     SB.promoteCircleOpen(slug) which converts every waitlister to a real
//     member and sends them a bell notification.
//   • The legacy victoria_bc privacy gate (circles_read RLS from schema_v7)
//     still applies — non-locals don't see Victoria BC at all.

// ─── Color theming by circle.category ───────────────────────────────────
// Recovery family = sage/healing green (the working-through space).
// Wellness family = warm amber (the enrichment/training space).
// General = neutral charcoal-green. Local = deep moss.
const CATEGORY_COLORS = {
  recovery: { primary: '#4A6B3E', secondary: '#5a7d4a' }, // sage
  wellness: { primary: '#B45F22', secondary: '#c97a38' }, // amber
  general:  { primary: '#3A433E', secondary: '#4e5852' }, // charcoal-green
  local:    { primary: '#2E3A2F', secondary: '#4a5b4a' }, // deep moss
};
const colorsForCircle = (c) => {
  const cat = c?.category;
  if (cat && CATEGORY_COLORS[cat]) return CATEGORY_COLORS[cat];
  // Fallback: use stored cover_color, else neutral
  const fallback = c?.cover_color || '#3A433E';
  return { primary: fallback, secondary: fallback };
};

// ─── DISCOVERY: /#circles ───────────────────────────────────────────────
const CirclesScreen = ({ theme, onNav }) => {
  const t = theme;
  const { isAuthed, signIn, session } = useApp();
  const userId = session?.user?.id;
  const [circles, setCircles] = React.useState(null);
  const [memberOf, setMemberOf] = React.useState(new Set());
  const [waitingFor, setWaitingFor] = React.useState(new Set());
  const [memberCounts, setMemberCounts] = React.useState({});
  const [filter, setFilter] = React.useState('all'); // 'all' | 'joined'

  // Helper: is this circle's pathway currently active? Circles without a
  // pathway_slug are always considered active (always-on community).
  const isComingSoon = React.useCallback((c) => {
    if (!c?.pathway_slug) return false;
    const cfg = window.OVIO_CONFIG;
    if (!cfg) return false;
    return !cfg.isPathwayActive(c.pathway_slug);
  }, []);

  React.useEffect(() => {
    SB.fetchCircles().then(async (rows) => {
      // Show ALL circles now. Pathway-gated ones render as Coming Soon.
      const all = rows || [];
      setCircles(all);
      // Pull live counts so the discovery feels real even if cached counters drift
      const counts = {};
      await Promise.all(all.map(async c => {
        counts[c.id] = await SB.fetchCircleMemberCount(c.id);
      }));
      setMemberCounts(counts);
    });
    SB.logEvent('circles_discovery_view');
  }, []);

  React.useEffect(() => {
    if (!userId) { setMemberOf(new Set()); setWaitingFor(new Set()); return; }
    SB.fetchMyCircles(userId).then(setMemberOf);
    SB.fetchMyWaitlistCircleIds(userId).then(setWaitingFor);
  }, [userId]);

  const toggleJoin = async (circle) => {
    if (!isAuthed) return signIn();
    // Coming-soon path: add/remove from waitlist (does NOT bump member count)
    if (isComingSoon(circle)) {
      const waiting = waitingFor.has(circle.id);
      setWaitingFor(s => { const n = new Set(s); waiting ? n.delete(circle.id) : n.add(circle.id); return n; });
      SB.logEvent(waiting ? 'circle_waitlist_leave' : 'circle_waitlist_join',
        { circle_id: circle.id, slug: circle.slug, from: 'discovery' });
      if (waiting) await SB.leaveCircleOpenWaitlist({ userId, circleId: circle.id });
      else         await SB.joinCircleOpenWaitlist({ userId, circleId: circle.id });
      return;
    }
    // Live circle: real membership
    const joining = !memberOf.has(circle.id);
    setMemberOf(s => { const n = new Set(s); joining ? n.add(circle.id) : n.delete(circle.id); return n; });
    setMemberCounts(c => ({ ...c, [circle.id]: (c[circle.id] || 0) + (joining ? 1 : -1) }));
    SB.logEvent(joining ? 'circle_join' : 'circle_leave', { circle_id: circle.id, slug: circle.slug, from: 'discovery' });
    await SB.toggleCircleMembership({ userId, circleId: circle.id, joined: joining });
  };

  const filtered = (circles || [])
    .filter(c => !c.is_hidden)  // schema_v19: hidden circles never show
    .filter(c => filter === 'joined' ? (memberOf.has(c.id) || waitingFor.has(c.id)) : true);
  // Split + sort: open circles first, coming soon second.
  // Within each, sort by display_priority asc (General=1, then Recovery=2, etc).
  const sortByPriority = (a, b) => {
    const ap = a.display_priority != null ? a.display_priority : 100;
    const bp = b.display_priority != null ? b.display_priority : 100;
    if (ap !== bp) return ap - bp;
    return (a.name || '').localeCompare(b.name || '');
  };
  const openCircles    = filtered.filter(c => !isComingSoon(c)).sort(sortByPriority);
  const comingSoonList = filtered.filter(c =>  isComingSoon(c)).sort(sortByPriority);

  // Card renderer used by both Open + Coming Soon sections
  const renderCircleCard = (c) => {
    const comingSoon = isComingSoon(c);
    const joined = memberOf.has(c.id);
    const waiting = waitingFor.has(c.id);
    const count = memberCounts[c.id] != null ? memberCounts[c.id] : (typeof c.member_count === 'number' ? c.member_count : 0);
    const { primary, secondary } = colorsForCircle(c);
    return (
      <Card key={c.id} theme={t} padding={0} hover
        onClick={() => comingSoon ? null : onNav('circle:' + c.slug)}
        style={{ overflow: 'hidden', cursor: comingSoon ? 'default' : 'pointer', opacity: comingSoon ? 0.92 : 1 }}>
        <div style={{
          height: 64,
          background: `linear-gradient(115deg, ${primary} 0%, ${primary}dd 55%, ${secondary} 160%)`,
          position: 'relative',
        }}>
          {comingSoon && (
            <span style={{
              position: 'absolute', top: 10, right: 12,
              fontFamily: t.font.mono, fontSize: 9, letterSpacing: '0.08em',
              padding: '3px 9px', borderRadius: t.radius.xl,
              background: 'rgba(255,255,255,0.92)', color: primary,
              textTransform: 'uppercase', fontWeight: 600,
            }}>Coming soon</span>
          )}
        </div>
        <div style={{ padding: 16 }}>
          <div style={{ fontFamily: t.font.serif, fontSize: 20, lineHeight: 1.2 }}>{c.name}</div>
          <div style={{ fontFamily: t.font.mono, fontSize: 10, color: t.c.muted, letterSpacing: '0.06em', marginTop: 4 }}>
            {comingSoon
              ? (waiting ? "YOU'RE ON THE WAITLIST" : 'NOT YET OPEN')
              : `${count.toLocaleString()} MEMBER${count === 1 ? '' : 'S'}`
            }
          </div>
          <p style={{ fontSize: 13, color: t.c.ink2, lineHeight: 1.5, marginTop: 10, minHeight: 56 }}>
            {c.about || c.description}
          </p>
          <div style={{ display: 'flex', gap: 8, marginTop: 12 }}>
            {!comingSoon && (
              <Btn theme={t} variant="primary" size="sm" iconRight="arrow"
                onClick={(ev) => { ev.stopPropagation(); onNav('circle:' + c.slug); }}>
                Open circle
              </Btn>
            )}
            <Btn theme={t} variant={(joined || waiting) ? 'soft' : (comingSoon ? 'primary' : 'ghost')} size="sm"
              onClick={(ev) => { ev.stopPropagation(); toggleJoin(c); }}>
              {comingSoon
                ? (waiting ? '✓ Notify me' : 'Notify me when open')
                : (joined ? '✓ Joined' : 'Join')
              }
            </Btn>
          </div>
        </div>
      </Card>
    );
  };

  return (
    <DesktopShell theme={t} active="circles" onNav={onNav}>
      <div style={{ marginBottom: 24 }}>
        <Eyebrow theme={t}>OH Community communities</Eyebrow>
        <h1 style={{ fontFamily: t.font.serif, fontSize: 44, margin: '6px 0 0', fontWeight: 400, letterSpacing: '-0.015em', lineHeight: 1.05 }}>
          Find the conversation that fits.
        </h1>
        <p style={{ fontSize: 14, color: t.c.ink2, lineHeight: 1.5, marginTop: 8, maxWidth: 620 }}>
          Each circle is a focused space for people working on the same thing. Join one or several. Your circles show on your profile and you can post into them from anywhere.
        </p>
      </div>

      {/* Filter chips */}
      <div style={{ display: 'flex', gap: 6, marginBottom: 18 }}>
        {[
          { id: 'all', label: 'All communities' },
          { id: 'joined', label: 'My circles' },
        ].map(f => (
          <button key={f.id} onClick={() => setFilter(f.id)} style={{
            padding: '6px 14px',
            background: filter === f.id ? t.c.ink : 'transparent',
            color: filter === f.id ? t.c.bg3 : t.c.ink2,
            border: `1px solid ${filter === f.id ? t.c.ink : t.c.edge}`,
            borderRadius: t.radius.xl,
            fontFamily: t.font.sans, fontSize: 13, fontWeight: 500, cursor: 'pointer',
          }}>{f.label}{f.id === 'joined' ? ` · ${memberOf.size}` : ''}</button>
        ))}
      </div>

      {circles === null ? (
        <Card theme={t}><div style={{ padding: 30, textAlign: 'center', color: t.c.muted }}>Loading…</div></Card>
      ) : (openCircles.length + comingSoonList.length) === 0 ? (
        <Card theme={t} style={{ padding: 40, textAlign: 'center' }}>
          <div style={{ fontFamily: t.font.serif, fontSize: 22, color: t.c.ink }}>
            {filter === 'joined' ? "You haven't joined any circles yet." : 'No communities available.'}
          </div>
          {filter === 'joined' && (
            <Btn theme={t} variant="primary" onClick={() => setFilter('all')} style={{ marginTop: 14 }}>
              Browse all
            </Btn>
          )}
        </Card>
      ) : (
        <>
          {/* ─── OPEN NOW ─────────────────────────────────────── */}
          {openCircles.length > 0 && (
            <>
              <SectionHeader theme={t} title="Open now"
                hint="Active communities you can join and post in today." />
              <div style={{
                display: 'grid',
                gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))',
                gap: 16,
                marginBottom: comingSoonList.length > 0 ? 32 : 0,
              }}>
                {openCircles.map(c => renderCircleCard(c))}
              </div>
            </>
          )}

          {/* ─── COMING SOON ──────────────────────────────────── */}
          {comingSoonList.length > 0 && (
            <>
              <SectionHeader theme={t} title="Coming soon"
                hint="Tap Notify me and we'll send a bell notification when each opens. You'll auto-join as a member." />
              <div style={{
                display: 'grid',
                gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))',
                gap: 16,
              }}>
                {comingSoonList.map(c => renderCircleCard(c))}
              </div>
            </>
          )}
        </>
      )}
    </DesktopShell>
  );
};

// ─── SectionHeader — small heading + hint row used between circle groups ─
const SectionHeader = ({ theme, title, hint }) => {
  const t = theme;
  return (
    <div style={{ marginBottom: 14, marginTop: 4 }}>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 12, flexWrap: 'wrap' }}>
        <h2 style={{
          fontFamily: t.font.serif, fontSize: 24, margin: 0, fontWeight: 400,
          letterSpacing: '-0.01em',
        }}>{title}</h2>
        {hint && (
          <span style={{ fontSize: 13, color: t.c.muted, lineHeight: 1.4 }}>{hint}</span>
        )}
      </div>
      <div style={{ marginTop: 8, height: 1, background: t.c.edgeSoft }} />
    </div>
  );
};

// ─── SINGLE CIRCLE: /#circle:<slug> ─────────────────────────────────────
const CirclePage = ({ theme, onNav, slug }) => {
  const t = theme;
  const { isAuthed, signIn, session, me } = useApp();
  const userId = session?.user?.id;

  const [circle, setCircle] = React.useState(undefined); // undefined=loading
  const [posts, setPosts] = React.useState(null);
  const [joined, setJoined] = React.useState(false);
  const [memberCount, setMemberCount] = React.useState(0);
  const [composer, setComposer] = React.useState(false);
  const [composerText, setComposerText] = React.useState('');
  const [busy, setBusy] = React.useState(false);

  React.useEffect(() => {
    if (!slug) { setCircle(null); return; }
    SB.fetchCircleBySlug(slug).then(c => setCircle(c || null));
    SB.logEvent('circle_view', { slug });
  }, [slug]);

  React.useEffect(() => {
    if (!circle) return;
    SB.fetchPostsInCircle(circle.name).then(setPosts);
    SB.fetchCircleMemberCount(circle.id).then(setMemberCount);
  }, [circle?.id]);

  React.useEffect(() => {
    if (!userId || !circle) { setJoined(false); return; }
    SB.fetchMyCircles(userId).then(set => setJoined(set.has(circle.id)));
  }, [userId, circle?.id]);

  const toggleJoin = async () => {
    if (!isAuthed) return signIn();
    if (!circle) return;
    const next = !joined;
    setJoined(next);
    setMemberCount(c => c + (next ? 1 : -1));
    SB.logEvent(next ? 'circle_join' : 'circle_leave', { circle_id: circle.id, slug: circle.slug, from: 'circle_page' });
    await SB.toggleCircleMembership({ userId, circleId: circle.id, joined: next });
  };

  const submit = async () => {
    if (!composerText.trim() || !circle) return;
    if (!isAuthed) return signIn();
    setBusy(true);
    SB.logEvent('post_create_attempt', { length: composerText.length, circle: circle.name });
    const { error } = await SB.createPost({
      authorId: userId,
      body: composerText.trim(),
      circle: circle.name,
      circles: [circle.name],
    });
    setBusy(false);
    if (error) { console.error('createPost', error); return; }
    setComposerText(''); setComposer(false);
    SB.fetchPostsInCircle(circle.name).then(setPosts);
  };

  if (circle === undefined) {
    return <DesktopShell theme={t} active="circles" onNav={onNav}>
      <Card theme={t}><div style={{ padding: 30, textAlign: 'center', color: t.c.muted }}>Loading circle…</div></Card>
    </DesktopShell>;
  }
  if (circle === null) {
    return <DesktopShell theme={t} active="circles" onNav={onNav}>
      <Card theme={t} style={{ padding: 40, textAlign: 'center' }}>
        <div style={{ fontFamily: t.font.serif, fontSize: 24 }}>Circle not found.</div>
        <Btn theme={t} variant="primary" onClick={() => onNav('circles')} style={{ marginTop: 14 }}>
          Browse communities
        </Btn>
      </Card>
    </DesktopShell>;
  }

  const { primary, secondary } = colorsForCircle(circle);

  return (
    <DesktopShell theme={t} active="circles" onNav={onNav}>
      {/* Back link */}
      <button onClick={() => onNav('circles')} style={{
        background: 'none', border: 'none', color: t.c.muted, cursor: 'pointer',
        padding: 0, fontSize: 12, marginBottom: 14,
      }}>← All communities</button>

      {/* Hero header */}
      <Card theme={t} padding={0} style={{ overflow: 'hidden', marginBottom: 20 }}>
        <div style={{
          height: 110,
          background: `linear-gradient(115deg, ${primary} 0%, ${primary}dd 55%, ${secondary} 165%)`,
        }} />
        <div style={{ padding: '20px 24px' }}>
          <div style={{ display: 'flex', alignItems: 'flex-start', gap: 16, flexWrap: 'wrap' }}>
            <div style={{ flex: 1, minWidth: 0 }}>
              <Eyebrow theme={t}>OH Community community</Eyebrow>
              <h1 style={{ fontFamily: t.font.serif, fontSize: 36, margin: '6px 0 0', fontWeight: 400, letterSpacing: '-0.015em', lineHeight: 1.05 }}>
                {circle.name}
              </h1>
              <div style={{ display: 'flex', alignItems: 'center', gap: 14, marginTop: 8, fontSize: 12, color: t.c.muted, fontFamily: t.font.mono, letterSpacing: '0.06em' }}>
                <span>{memberCount.toLocaleString()} MEMBER{memberCount === 1 ? '' : 'S'}</span>
                {circle.description && (
                  <span style={{ fontFamily: t.font.sans, textTransform: 'none', letterSpacing: 0, color: t.c.ink2 }}>
                    · {circle.description}
                  </span>
                )}
              </div>
            </div>
            <Btn theme={t} variant={joined ? 'soft' : 'primary'} icon={joined ? 'check' : 'plus'}
              onClick={toggleJoin}>
              {joined ? 'Joined' : 'Join circle'}
            </Btn>
          </div>
        </div>
      </Card>

      {/* About */}
      {circle.about && (
        <Card theme={t} style={{ marginBottom: 20 }}>
          <Eyebrow theme={t}>About this circle</Eyebrow>
          <p style={{ fontSize: 14, color: t.c.ink2, lineHeight: 1.6, marginTop: 8 }}>
            {circle.about}
          </p>
        </Card>
      )}

      {/* Composer — joined members only */}
      {joined && (
        <Card theme={t} padding={0} style={{ marginBottom: 18, overflow: 'hidden' }}>
          {!composer ? (
            <div style={{ display: 'flex', alignItems: 'center', gap: 14, padding: '14px 18px' }}>
              <Avatar theme={t} name={me?.name || '??'} seed={me?.avatar_seed || 0} size={36}
                photoPath={me?.photo_url} />
              <button onClick={() => setComposer(true)} style={{
                flex: 1, textAlign: 'left',
                background: t.c.bg, border: `1px solid ${t.c.edge}`,
                borderRadius: t.radius.xl, padding: '10px 16px',
                fontFamily: t.font.sans, fontSize: 13, color: t.c.muted, cursor: 'pointer',
              }}>
                Share with the {circle.name} circle…
              </button>
            </div>
          ) : (
            <div style={{ padding: 18 }}>
              <div style={{ display: 'flex', gap: 12, alignItems: 'flex-start' }}>
                <Avatar theme={t} name={me?.name || '??'} seed={me?.avatar_seed || 0} size={36}
                  photoPath={me?.photo_url} />
                <div style={{ flex: 1 }}>
                  <textarea
                    autoFocus value={composerText} onChange={e => setComposerText(e.target.value)}
                    placeholder={`What's on your mind, ${(me?.name || '').split(' ')[0] || 'there'}?`}
                    style={{
                      width: '100%', minHeight: 90,
                      border: 'none', outline: 'none', resize: 'none',
                      fontFamily: t.font.serif, fontSize: 17, lineHeight: 1.45,
                      color: t.c.ink, background: 'transparent',
                    }}
                  />
                </div>
              </div>
              <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end', marginTop: 14, borderTop: `1px solid ${t.c.edgeSoft}`, paddingTop: 14 }}>
                <Btn theme={t} variant="ghost" onClick={() => { setComposer(false); setComposerText(''); }}>Cancel</Btn>
                <Btn theme={t} variant="primary" iconRight="send" onClick={submit}>
                  {busy ? 'Posting…' : `Post to ${circle.name}`}
                </Btn>
              </div>
            </div>
          )}
        </Card>
      )}

      {!joined && isAuthed && (
        <Card theme={t} style={{ marginBottom: 18, padding: 18, background: t.c.bg3, border: `1px dashed ${t.c.edge}` }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
            <Icon name="users" size={20} color={t.c.accent} />
            <div style={{ flex: 1 }}>
              <div style={{ fontFamily: t.font.serif, fontSize: 16 }}>Join to post and follow updates here.</div>
              <div style={{ fontSize: 12, color: t.c.muted, marginTop: 2 }}>You can leave any time. Your other circles aren't affected.</div>
            </div>
            <Btn theme={t} variant="primary" onClick={toggleJoin}>Join {circle.name}</Btn>
          </div>
        </Card>
      )}

      {/* Posts */}
      <Eyebrow theme={t} style={{ marginBottom: 10 }}>Posts in {circle.name}</Eyebrow>
      {posts === null ? (
        <Card theme={t}><div style={{ padding: 30, textAlign: 'center', color: t.c.muted }}>Loading posts…</div></Card>
      ) : posts.length === 0 ? (
        <Card theme={t} style={{ padding: 40, textAlign: 'center' }}>
          <div style={{ fontFamily: t.font.serif, fontSize: 22, color: t.c.ink2 }}>
            No posts yet.
          </div>
          <div style={{ fontSize: 13, color: t.c.muted, marginTop: 6 }}>
            {joined ? 'Be the first to share something.' : 'Join to start the conversation.'}
          </div>
        </Card>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          {posts.map(p => {
            const post = window.transformSbPost ? window.transformSbPost(p) : p;
            return (
              <FeedPost
                key={post.id}
                theme={t}
                post={post}
                reacted={false}
                expanded={false}
                onReact={() => {}}
                onToggleComments={() => {}}
                onNav={onNav}
              />
            );
          })}
        </div>
      )}
    </DesktopShell>
  );
};

window.CirclesScreen = CirclesScreen;
window.CirclePage = CirclePage;
