/* ============================================================================
 * Wildy — 온보딩 플로우 컴포넌트 (Welcome → GameSelect → Complete)
 * ----------------------------------------------------------------------------
 *   spec Section 8 (Phase 1B 온보딩)
 *
 *   파일 형식: .jsx — Babel-standalone이 type="text/babel"로 fetch + 변환.
 *   양쪽 HTML에서 같은 파일 재사용:
 *     <script type="text/babel" src="lib/components/onboarding.jsx" data-presets="env,react"></script>
 *
 *   글로벌 노출:
 *     window.WildyComponents.OnboardingFlow
 *
 *   사용 예 (App 안에서):
 *     {showOnboarding && <window.WildyComponents.OnboardingFlow
 *        supabaseClient={supabaseClient}
 *        user={user}
 *        lang={preferredLang}
 *        onComplete={() => setShowOnboarding(false)}
 *      />}
 * ========================================================================= */
(function (global) {
  'use strict';

  if (typeof React === 'undefined') {
    console.error('[onboarding.jsx] React not loaded — order matters');
    return;
  }
  const { useState, useEffect, useMemo } = React;

  // 5개 언어 키 매핑 (B-4 ko.json 작성 후 i18n으로 교체 가능 — 현재는 인라인 ko)
  const T = {
    welcomeTitle:    (n) => `안녕, ${n || 'Wilder'}! Wildy에 온 걸 환영해 ⭐`,
    welcomeSub:      '좋아하는 게임을 3개 이상 선택하고 시작해보세요.',
    welcomeStart:    '시작하기 →',
    selectTitle:     '좋아하는 게임을 골라주세요',
    selectCounter:   (n) => `${n}/3 이상`,
    selectSearch:    '게임 검색',
    selectEmpty:     '검색 결과가 없어요',
    selectNext:      (n) => n >= 3 ? '다음' : `${3 - n}개 더 선택`,
    selectPrev:      '이전',
    completeTitle:   '준비 완료! 🎉',
    completeSub:     (n) => `${n}개 Wild를 자동 팔로우했어요`,
    completeHome:    '홈으로 가기',
    errorMin:        '게임을 3개 이상 선택해주세요',
    errorRpc:        '저장 중 문제가 발생했어요',
  };

  // ───────────────────────────────────────────────────────────
  // WelcomeScreen
  // ───────────────────────────────────────────────────────────
  function WelcomeScreen({ nickname, onStart }) {
    return (
      <div className="min-h-screen w-full bg-gradient-to-b from-sky-50 to-white px-5 pt-12 pb-12 flex flex-col" style={{ maxWidth: 480, margin: '0 auto' }}>
        <div className="flex-1 flex flex-col items-center justify-center text-center">
          <div className="text-7xl mb-6">⭐</div>
          <h1 className="font-display text-3xl font-black text-wildy-ink leading-tight">
            {T.welcomeTitle(nickname)}
          </h1>
          <p className="mt-4 text-sm text-slate-600 max-w-xs">
            {T.welcomeSub}
          </p>
        </div>
        <button onClick={onStart} className="mt-8 w-full rounded-full bg-wildy-ink py-4 font-bold text-white text-base hover:-translate-y-0.5 transition shadow-ink">
          {T.welcomeStart}
        </button>
      </div>
    );
  }

  // ───────────────────────────────────────────────────────────
  // GameSelectScreen
  // ───────────────────────────────────────────────────────────
  function GameSelectScreen({ supabaseClient, selected, onToggle, onNext, onBack, submitting, error, lang }) {
    const [games, setGames] = useState([]);
    const [loading, setLoading] = useState(true);
    const [search, setSearch] = useState('');
    const [loadError, setLoadError] = useState('');

    useEffect(() => {
      let active = true;
      (async () => {
        try {
          if (supabaseClient) {
            const { data, error } = await supabaseClient
              .from('wilds')
              .select('id,name,short_name,emoji,category,title_en,title_ja,title_zh,title_id,icon_url,short_description,member_count,rank_in_discover')
              .eq('is_curated', true)
              .order('rank_in_discover', { ascending: true });
            if (!active) return;
            if (error) throw error;
            setGames(data || []);
          } else {
            // 데모 모드 — 인라인 mock
            setGames([
              { id: 'valorant', name: '발로란트', emoji: '🔥', short_description: '5v5 전술 FPS', category: 'FPS', rank_in_discover: 1 },
              { id: 'lol', name: '리그 오브 레전드', emoji: '🎮', short_description: '5v5 정통 MOBA', category: 'MOBA', rank_in_discover: 8 },
              { id: 'genshin', name: '원신', emoji: '🌟', short_description: '오픈월드 액션 RPG', category: 'RPG', rank_in_discover: 13 },
            ]);
          }
        } catch (e) {
          if (!active) return;
          setLoadError('게임 목록을 불러오지 못했어요. 잠시 후 다시 시도해주세요.');
        } finally {
          if (active) setLoading(false);
        }
      })();
      return () => { active = false; };
    }, [supabaseClient]);

    const localized = (g) => {
      if (lang === 'en' && g.title_en) return g.title_en;
      if (lang === 'ja' && g.title_ja) return g.title_ja;
      if (lang === 'zh' && g.title_zh) return g.title_zh;
      if (lang === 'id' && g.title_id) return g.title_id;
      return g.name;
    };

    const filtered = useMemo(() => {
      if (!search) return games;
      const q = search.toLowerCase().trim();
      return games.filter(g =>
        (g.name || '').toLowerCase().includes(q) ||
        (g.title_en || '').toLowerCase().includes(q) ||
        (g.short_name || '').toLowerCase().includes(q) ||
        (g.short_description || '').toLowerCase().includes(q)
      );
    }, [games, search]);

    return (
      <div className="min-h-screen w-full bg-white px-5 pt-6 pb-32" style={{ maxWidth: 480, margin: '0 auto' }}>
        <div className="sticky top-0 -mx-5 px-5 pt-4 pb-3 bg-white/95 backdrop-blur z-10 border-b border-slate-100">
          <div className="flex items-center justify-between mb-3">
            <h2 className="font-display text-xl font-black text-wildy-ink">{T.selectTitle}</h2>
            <span className={`rounded-full px-3 py-1 text-xs font-bold ${selected.length >= 3 ? 'bg-emerald-100 text-emerald-700' : 'bg-sky-100 text-sky-700'}`}>
              {T.selectCounter(selected.length)}
            </span>
          </div>
          <input
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="w-full rounded-2xl border-2 border-sky-100 px-4 py-2.5 text-sm outline-none focus:border-sky-300"
            placeholder={T.selectSearch}
          />
        </div>

        {loading && <div className="py-12 text-center text-slate-400 text-sm">로딩 중...</div>}
        {loadError && <div className="my-4 rounded-2xl bg-rose-50 px-4 py-3 text-sm text-rose-600">{loadError}</div>}

        {!loading && !loadError && (
          <div className="grid grid-cols-2 gap-2.5 mt-4">
            {filtered.length === 0 && (
              <div className="col-span-2 py-8 text-center text-slate-400 text-sm">{T.selectEmpty}</div>
            )}
            {filtered.map(g => {
              const isSel = selected.includes(g.id);
              return (
                <button
                  key={g.id}
                  onClick={() => onToggle(g.id)}
                  className={`relative flex flex-col items-start gap-1.5 rounded-2xl border-2 px-3 py-3 text-left transition ${isSel ? 'border-wildy-ink bg-wildy-cloud' : 'border-slate-100 bg-white hover:border-sky-200'}`}
                >
                  {isSel && (
                    <span className="absolute top-2 right-2 flex h-6 w-6 items-center justify-center rounded-full bg-wildy-ink text-white text-xs font-bold">✓</span>
                  )}
                  <div className="flex items-center gap-2">
                    {g.icon_url ? (
                      <img src={g.icon_url} alt="" className="h-9 w-9 rounded-lg object-cover" onError={(e) => { e.target.style.display = 'none'; }} />
                    ) : (
                      <span className="text-2xl">{g.emoji || '🎮'}</span>
                    )}
                  </div>
                  <div className="font-bold text-sm text-wildy-ink line-clamp-1">{localized(g)}</div>
                  <div className="text-xs text-slate-500 line-clamp-1">{g.short_description || g.category}</div>
                </button>
              );
            })}
          </div>
        )}

        {error && <div className="mt-4 rounded-2xl bg-rose-50 px-4 py-3 text-sm text-rose-600">{error}</div>}

        {/* 하단 sticky CTA */}
        <div className="fixed bottom-0 left-0 right-0 px-5 py-3 bg-white border-t border-slate-100" style={{ maxWidth: 480, margin: '0 auto' }}>
          <div className="flex gap-2">
            <button onClick={onBack} className="rounded-full border-2 border-slate-200 px-5 py-3 text-sm font-bold text-slate-600">
              {T.selectPrev}
            </button>
            <button
              onClick={onNext}
              disabled={selected.length < 3 || submitting}
              className="flex-1 rounded-full bg-wildy-ink py-3 font-bold text-white disabled:bg-slate-300 disabled:cursor-not-allowed"
            >
              {submitting ? '저장 중...' : T.selectNext(selected.length)}
            </button>
          </div>
        </div>
      </div>
    );
  }

  // ───────────────────────────────────────────────────────────
  // CompleteScreen — 2.5초 후 자동 onComplete()
  // ───────────────────────────────────────────────────────────
  function CompleteScreen({ count, onHome, autoMs = 2500 }) {
    useEffect(() => {
      if (autoMs <= 0) return;
      const t = setTimeout(onHome, autoMs);
      return () => clearTimeout(t);
    }, []);
    return (
      <div className="min-h-screen w-full bg-gradient-to-b from-sky-50 to-white px-5 flex flex-col items-center justify-center text-center" style={{ maxWidth: 480, margin: '0 auto' }}>
        <div className="text-7xl mb-6 animate-bounce">🎉</div>
        <h2 className="font-display text-2xl font-black text-wildy-ink">{T.completeTitle}</h2>
        <p className="mt-3 text-slate-600">{T.completeSub(count)}</p>
        <button onClick={onHome} className="mt-8 rounded-full bg-wildy-ink px-8 py-3.5 font-bold text-white text-sm">
          {T.completeHome}
        </button>
        <p className="mt-3 text-xs text-slate-400">잠시 후 자동으로 홈으로 이동해요</p>
      </div>
    );
  }

  // ───────────────────────────────────────────────────────────
  // OnboardingFlow — 메인 컨테이너
  // ───────────────────────────────────────────────────────────
  function OnboardingFlow({ supabaseClient, user, lang = 'ko', onComplete }) {
    const [step, setStep] = useState('welcome');     // welcome | select | complete
    const [selected, setSelected] = useState([]);
    const [submitting, setSubmitting] = useState(false);
    const [error, setError] = useState('');

    // 진입 시 mark_onboarding_started (idempotent — coalesce로 첫 진입만 기록)
    useEffect(() => {
      if (!supabaseClient || !user?.id) return;
      supabaseClient.rpc('mark_onboarding_started', { p_user_id: user.id }).catch(() => {});
    }, [supabaseClient, user?.id]);

    const toggle = (id) => {
      setSelected(prev => prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id]);
    };

    // RPC complete_onboarding 우선 — 실패 시 한 개씩 fallback
    const submit = async () => {
      setError('');
      if (selected.length < 3) { setError(T.errorMin); return; }

      setSubmitting(true);
      try {
        if (supabaseClient && user?.id) {
          const { error: rpcErr } = await supabaseClient.rpc('complete_onboarding', {
            p_user_id: user.id,
            p_wild_ids: selected,
          });
          if (rpcErr) {
            // Fallback — 한 개씩 INSERT 재시도 + 수동 마킹
            console.warn('[onboarding] RPC failed, falling back to per-row insert:', rpcErr);
            const failures = [];
            for (const wid of selected) {
              const { error: insErr } = await supabaseClient
                .from('wild_subscriptions')
                .insert({ user_id: user.id, wild_id: wid, source: 'onboarding' });
              if (insErr && !String(insErr.message || '').includes('duplicate')) {
                failures.push(wid);
              }
            }
            await supabaseClient.from('users')
              .update({ onboarding_completed_at: new Date().toISOString() })
              .eq('id', user.id);
            if (failures.length > 0) {
              console.warn('[onboarding] partial failures:', failures);
            }
          }
        }
        setStep('complete');
      } catch (e) {
        console.error('[onboarding] submit error', e);
        setError(e?.message || T.errorRpc);
      } finally {
        setSubmitting(false);
      }
    };

    if (step === 'welcome') {
      return <WelcomeScreen nickname={user?.nickname} onStart={() => setStep('select')} />;
    }
    if (step === 'select') {
      return (
        <GameSelectScreen
          supabaseClient={supabaseClient}
          selected={selected}
          onToggle={toggle}
          onNext={submit}
          onBack={() => setStep('welcome')}
          submitting={submitting}
          error={error}
          lang={lang}
        />
      );
    }
    if (step === 'complete') {
      return <CompleteScreen count={selected.length} onHome={onComplete || (() => { window.location.href = '/'; })} />;
    }
    return null;
  }

  global.WildyComponents = global.WildyComponents || {};
  global.WildyComponents.OnboardingFlow = OnboardingFlow;
  global.WildyComponents.WelcomeScreen = WelcomeScreen;
  global.WildyComponents.GameSelectScreen = GameSelectScreen;
  global.WildyComponents.CompleteScreen = CompleteScreen;
})(typeof window !== 'undefined' ? window : globalThis);
