/* ============================================================================
 * Wildy — 공통 우측 사이드바 (Home / Wilds / 게임 다운로드 / 프로필)
 * ----------------------------------------------------------------------------
 *   용어 정의 (사용자 확정):
 *     · Wild  = 게임별 네트워킹 허브 전체 (실시간채팅+DM+공지+이벤트+소통)
 *               = World + Guild + You
 *     · 길드  = Wild 안에서 사용자가 만드는 작은 그룹/채팅방 단위
 *     → 사이드바의 "내 Wild"는 사용자가 팔로우한 Wild 목록.
 *
 *   섹션:
 *     1. 내 Wild   — followedGames prop(단일 진실)의 id로 wilds 조회
 *     2. Wild 추천 — followedGames에 없는 인기 wilds
 *     3. 베타 가입자 혜택 (정적)
 *
 *   ⚠ 데이터 소스 통일: wild_subscriptions를 직접 쿼리하지 않고
 *      App의 followedGames prop을 신뢰. App이 DB와 동기화 책임.
 *      → BrowsePage에서 팔로우 토글 시 사이드바 즉시 반영.
 *
 *   사용:
 *     <window.WildyComponents.RightSidebar
 *        supabaseClient={...}
 *        user={user}
 *        lang="ko"
 *        followedGames={['lol', 'val']}      // 단일 진실 (App이 DB 동기화)
 *        onOpenWild={(wildId) => ...}
 *        onToggleFollow={(wildId) => ...}
 *        onNavigate={(page) => ...}
 *     />
 *
 *   글로벌 노출:
 *     window.WildyComponents.RightSidebar
 * ========================================================================= */
(function (global) {
  'use strict';

  if (typeof React === 'undefined') {
    console.error('[right-sidebar.jsx] React not loaded');
    return;
  }
  const { useState, useEffect } = React;

  function localizeWild(w, lang) {
    if (!w) return '';
    if (lang === 'en' && w.title_en) return w.title_en;
    if (lang === 'ja' && w.title_ja) return w.title_ja;
    if (lang === 'zh' && w.title_zh) return w.title_zh;
    if (lang === 'id' && w.title_id) return w.title_id;
    return w.short_name || w.name || w.id;
  }

  function compactCount(n) {
    if (!n || n < 1) return '';
    if (n >= 1_000_000) return (n / 1_000_000).toFixed(1) + 'M';
    if (n >= 1_000) return (n / 1_000).toFixed(1) + 'k';
    return String(n);
  }

  function withTimeout(promise, ms, fallback) {
    return Promise.race([
      promise,
      new Promise(resolve => setTimeout(() => resolve(fallback), ms)),
    ]);
  }

  function RightSidebar({
    supabaseClient, user, lang = 'ko',
    followedGames = [],
    onOpenWild, onToggleFollow, onNavigate,
  }) {
    const cache = global.__WILDY_RIGHT_RAIL_CACHE || (global.__WILDY_RIGHT_RAIL_CACHE = {
      wilds: null,
      wildsAt: 0,
      pulse: [],
      pulseAt: 0,
    });
    const [allWilds, setAllWilds] = useState(cache.wilds);   // null = loading — wilds metadata cache
    const [pulsePosts, setPulsePosts] = useState(cache.pulse || []);
    const [pulseLoading, setPulseLoading] = useState(false);

    // wilds 메타데이터 일괄 로드 (한 번) — 내 Wild + 추천 모두 여기서 매핑
    useEffect(() => {
      if (!supabaseClient) { setAllWilds([]); return; }
      if (cache.wilds && Date.now() - cache.wildsAt < 5 * 60 * 1000) {
        setAllWilds(cache.wilds);
        return;
      }
      let active = true;
      (async () => {
        try {
          // ⚠ wilds 스키마(002): 활동량 = active_now, 활성 플래그 = is_curated.
          //    과거 코드에서 존재하지 않는 is_active/active_users_count 를 참조해
          //    PostgREST 422 → setAllWilds([]) → "내 Wild" 박스 영구 빈 상태였음.
          //    필터 없이 limit(200) — 028 시드 45개 + 016 legacy ~15개 모두 커버.
          //    followedGames 의 wild_id 가 빠짐없이 매핑돼야 박스가 그려짐.
          const { data, error } = await withTimeout(
            supabaseClient
              .from('wilds')
              .select('id,name,short_name,emoji,member_count,active_now,title_en,title_ja,title_zh,title_id')
              .order('member_count', { ascending: false, nullsFirst: false })
              .limit(200),
            3000,
            { data: [], error: new Error('wilds_timeout') }
          );
          if (!active) return;
          if (error) throw error;
          const fallback = (global.WILDY_GAMES || []).map(g => ({
            id: g.id,
            name: g.name,
            short_name: g.short,
            emoji: g.emoji,
            member_count: parseFloat(String(g.users || '0')) * (String(g.users || '').toLowerCase().includes('k') ? 1000 : 1),
            active_now: 0,
          }));
          const byId = new Map([...fallback, ...(data || [])].map(w => [w.id, w]));
          const nextWilds = Array.from(byId.values());
          cache.wilds = nextWilds;
          cache.wildsAt = Date.now();
          setAllWilds(nextWilds);
        } catch (e) {
          console.warn('[RightSidebar] wilds load', e.message);
          if (active) {
            const fallbackWilds = (global.WILDY_GAMES || []).map(g => ({
            id: g.id,
            name: g.name,
            short_name: g.short,
            emoji: g.emoji,
            member_count: parseFloat(String(g.users || '0')) * (String(g.users || '').toLowerCase().includes('k') ? 1000 : 1),
            active_now: 0,
            }));
            cache.wilds = fallbackWilds;
            cache.wildsAt = Date.now();
            setAllWilds(fallbackWilds);
          }
        }
      })();
      return () => { active = false; };
    }, [supabaseClient]);

    useEffect(() => {
      if (!supabaseClient) { setPulsePosts([]); setPulseLoading(false); return; }
      if (Date.now() - cache.pulseAt < 60 * 1000) {
        setPulsePosts(cache.pulse || []);
        setPulseLoading(false);
        return;
      }
      let active = true;
      setPulseLoading(true);
      (async () => {
        try {
          const { data, error } = await withTimeout(
            supabaseClient
              .from('posts')
              .select('id,text,game_tag,created_at,type')
              .eq('is_deleted', false)
              .eq('visibility', 'public')
              .eq('type', 'pulse')
              .order('created_at', { ascending: false })
              .limit(3),
            2000,
            { data: [], error: null }
          );
          if (!active) return;
          if (error) throw error;
          cache.pulse = data || [];
          cache.pulseAt = Date.now();
          setPulsePosts(cache.pulse);
        } catch (e) {
          console.warn('[RightSidebar] pulse load', e?.message || e);
          if (active) setPulsePosts([]);
        } finally {
          if (active) setPulseLoading(false);
        }
      })();
      return () => { active = false; };
    }, [supabaseClient]);

    // followedGames(단일 진실) → 내 Wild / 추천 분리
    const followedSet = new Set(followedGames || []);
    const myWilds = allWilds === null ? null
      : (followedGames || [])
          .map(id => allWilds.find(w => w.id === id))
          .filter(Boolean);
    const recommended = allWilds === null ? null
      : allWilds.filter(w => !followedSet.has(w.id)).slice(0, 4);

    const showRec = Array.isArray(recommended) && recommended.length > 0;

    return (
      <aside className="space-y-4 text-sm">
        {/* ─── 내 Wild ─── */}
        <div className="rounded-3xl border border-sky-100 bg-white p-4 shadow-cloud">
          <div className="mb-3 flex items-center justify-between">
            <h3 className="font-display text-sm font-black text-wildy-ink">내 Wild</h3>
            {user?.id && onNavigate && (
              <button
                onClick={() => onNavigate('browse')}
                className="text-[11px] font-bold text-sky-600 hover:underline"
              >
                + 추가
              </button>
            )}
          </div>
          {!user?.id ? (
            <div className="text-xs text-slate-500" style={{ wordBreak: 'keep-all' }}>
              로그인하면 팔로우한 Wild가 여기 모여요.
            </div>
          ) : myWilds === null ? (
            <div className="space-y-2 py-1">
              {Array.from({ length: 3 }).map((_, i) => (
                <div key={i} className="flex items-center gap-2 rounded-xl px-2 py-2">
                  <span className="h-6 w-6 animate-pulse rounded-full bg-sky-50"></span>
                  <span className="h-3 flex-1 animate-pulse rounded bg-slate-100"></span>
                </div>
              ))}
            </div>
          ) : myWilds.length === 0 ? (
            <div className="rounded-2xl border-2 border-dashed border-sky-200 px-3 py-4 text-center text-xs text-slate-500" style={{ wordBreak: 'keep-all' }}>
              <div className="text-2xl mb-1">🎮</div>
              아직 팔로우한 Wild가 없어요
              {onNavigate && (
                <button
                  onClick={() => onNavigate('browse')}
                  className="mt-2 block w-full rounded-full bg-wildy-ink py-1.5 text-[11px] font-bold text-white hover:-translate-y-0.5 transition"
                >
                  Wilds 둘러보기 →
                </button>
              )}
            </div>
          ) : (
            <div className="space-y-1">
              {myWilds.slice(0, 5).map(w => {
                const active = w.active_now || w.member_count || 0;
                return (
                  <button
                    key={w.id}
                    onClick={() => onOpenWild && onOpenWild(w.id)}
                    className="flex w-full items-center gap-2 rounded-xl px-2 py-2 text-left hover:bg-sky-50 transition"
                  >
                    <span className="text-base flex-shrink-0">{w.emoji || '🎮'}</span>
                    <div className="flex-1 min-w-0">
                      <div className="text-xs font-bold text-wildy-ink truncate">{localizeWild(w, lang)}</div>
                      {active > 0 && (
                        <div className="text-[10px] text-slate-400">{compactCount(active)} 활동 중</div>
                      )}
                    </div>
                    <span className="text-slate-300 text-xs">›</span>
                  </button>
                );
              })}
              {myWilds.length > 5 && onNavigate && (
                <button
                  onClick={() => onNavigate('profile')}
                  className="block w-full text-center text-[11px] font-bold text-sky-600 hover:underline pt-2"
                >
                  {myWilds.length - 5}개 더 보기
                </button>
              )}
            </div>
          )}
        </div>

        {/* ─── Live Pulse ─── */}
        <div className="rounded-3xl border border-sky-100 bg-white p-4 shadow-cloud">
          <div className="mb-3 flex items-center justify-between gap-2">
            <h3 className="font-display text-sm font-black text-wildy-ink">Live Pulse</h3>
            <span className="rounded-full bg-sky-50 px-2 py-1 text-[10px] font-black text-sky-600">LIVE</span>
          </div>
          {pulseLoading ? (
            <div className="space-y-2">
              <div className="h-3 w-24 animate-pulse rounded bg-sky-50"></div>
              <div className="h-3 w-full animate-pulse rounded bg-slate-100"></div>
              <div className="h-3 w-2/3 animate-pulse rounded bg-slate-100"></div>
            </div>
          ) : pulsePosts.length > 0 ? (
            <div className="space-y-2">
              {pulsePosts.map(p => {
                const title = String(p.text || '').split('\n').map(s => s.trim()).find(Boolean) || 'Wildy Pulse';
                return (
                  <button
                    key={p.id}
                    onClick={() => p.game_tag && onOpenWild && onOpenWild(p.game_tag)}
                    className="w-full rounded-2xl bg-sky-50/60 px-3 py-3 text-left transition hover:bg-sky-100/70"
                  >
                    <div className="text-[11px] font-black uppercase tracking-wide text-sky-600">📡 Wildy Pulse</div>
                    <div className="mt-1 text-xs font-bold leading-snug text-wildy-ink" style={{ wordBreak: 'keep-all' }}>{title}</div>
                  </button>
                );
              })}
            </div>
          ) : (
            <div className="rounded-2xl border border-dashed border-sky-200 bg-sky-50/40 px-3 py-5 text-center text-xs font-bold text-slate-500" style={{ wordBreak: 'keep-all' }}>
              오늘의 Pulse를 준비 중이에요
            </div>
          )}
        </div>

        {/* ─── 팔로우 추천 ─── */}
        {showRec && (
          <div className="rounded-3xl border border-sky-100 bg-white p-4 shadow-cloud">
            <h3 className="mb-3 font-display text-sm font-black text-wildy-ink">팔로우 추천</h3>
            <div className="space-y-1">
              {recommended.map(w => {
                const active = w.active_now || w.member_count || 0;
                const isFollowing = followedGames.includes(w.id);
                return (
                  <div key={w.id} className="flex items-center gap-2 rounded-xl px-2 py-2">
                    <button
                      onClick={() => onOpenWild && onOpenWild(w.id)}
                      className="flex-1 flex items-center gap-2 text-left min-w-0"
                    >
                      <span className="text-base flex-shrink-0">{w.emoji || '🎮'}</span>
                      <div className="flex-1 min-w-0">
                        <div className="text-xs font-bold text-wildy-ink truncate">{localizeWild(w, lang)}</div>
                        {active > 0 && (
                          <div className="text-[10px] text-slate-400">{compactCount(active)} 활동 중</div>
                        )}
                      </div>
                    </button>
                    {onToggleFollow && (
                      <button
                        onClick={() => onToggleFollow(w.id)}
                        className={`flex-shrink-0 rounded-full px-2 py-1 text-[10px] font-bold transition ${
                          isFollowing
                            ? 'bg-emerald-100 text-emerald-700'
                            : 'bg-sky-500 text-white hover:bg-sky-600'
                        }`}
                      >
                        {isFollowing ? '✓' : '팔로우'}
                      </button>
                    )}
                  </div>
                );
              })}
            </div>
          </div>
        )}

        {/* ─── 베타 가입자 혜택 ─── */}
        <div className="rounded-3xl border-2 border-amber-200 bg-gradient-to-br from-amber-50 to-yellow-50 p-4">
          <div className="flex items-center gap-1.5 mb-2">
            <span className="text-base">🎁</span>
            <h3 className="font-display text-sm font-black text-wildy-ink">베타 가입자 혜택</h3>
          </div>
          <p className="text-xs text-slate-700 leading-relaxed" style={{ wordBreak: 'keep-all' }}>
            <span className="font-bold text-wildy-ink">Pro 멤버십 3개월 무료</span> +
            <span className="font-bold text-wildy-ink"> 출시 한정 뱃지</span> 보유 중
          </p>
          <p className="mt-2 text-[10px] text-amber-700 opacity-80" style={{ wordBreak: 'keep-all' }}>
            정식 출시일부터 3개월간 자동 적용됩니다.
          </p>
        </div>
      </aside>
    );
  }

  global.WildyComponents = global.WildyComponents || {};
  global.WildyComponents.RightSidebar = RightSidebar;
})(typeof window !== 'undefined' ? window : globalThis);
