/**
 * GdSfxPreview — превью 9 звуковых эффектов GD-игры.
 *
 * Маршрут: /admin-preview/gd-sfx
 *
 * Все эффекты процедурные (Web Audio API), не файлы.
 * Один AudioContext на всю страницу, создаётся при первом клике.
 */
import React, { useEffect, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../auth/AuthContext.jsx';
import styles from './GdSfxPreview.module.css';
import { SFX_CATALOG } from './gdSfx/sfxFactories';

function GdSfxPreview() {
  const { userRole, isLoading } = useAuth();
  const navigate = useNavigate();
  const ctxRef = useRef(null);
  const masterRef = useRef(null);
  const [ready, setReady] = useState(false);
  const [lastPlayed, setLastPlayed] = useState(null);

  // Создаём AudioContext по первому клику (autoplay policy)
  const ensureCtx = async () => {
    if (!ctxRef.current) {
      const Ctor = window.AudioContext || window.webkitAudioContext;
      if (!Ctor) {
        alert('Web Audio API не поддерживается в этом браузере');
        return null;
      }
      ctxRef.current = new Ctor();
      masterRef.current = ctxRef.current.createGain();
      masterRef.current.gain.value = 0.8;
      masterRef.current.connect(ctxRef.current.destination);
      setReady(true);
    }
    if (ctxRef.current.state === 'suspended') {
      try { await ctxRef.current.resume(); } catch (e) {}
    }
    return ctxRef.current;
  };

  const playSfx = async (sfx) => {
    const ctx = await ensureCtx();
    if (!ctx) return;
    try {
      sfx.play(ctx, masterRef.current);
      setLastPlayed(sfx.id);
      // Сбросить highlight через duration
      setTimeout(() => setLastPlayed(curr => curr === sfx.id ? null : curr), sfx.durationMs + 200);
    } catch (e) {
      console.error('[gd-sfx]', sfx.id, e);
    }
  };

  const playAll = async () => {
    const ctx = await ensureCtx();
    if (!ctx) return;
    let delay = 0;
    for (const sfx of SFX_CATALOG) {
      setTimeout(() => playSfx(sfx), delay);
      delay += sfx.durationMs + 200;
    }
  };

  // Cleanup
  useEffect(() => () => {
    if (ctxRef.current) {
      try { ctxRef.current.close(); } catch (_) {}
    }
  }, []);

  if (isLoading) return <div className={styles.loading}>Загрузка...</div>;
  if (userRole !== 'admin') {
    return (
      <div className={styles.denied}>
        <h2>Доступ только для администратора</h2>
        <button onClick={() => navigate('/')} className={styles.backBtn}>На главную</button>
      </div>
    );
  }

  return (
    <div className={styles.root}>
      <div className={styles.topbar}>
        <h1 className={styles.h1}>GD-Звуки — превью {SFX_CATALOG.length} эффектов</h1>
        <div className={styles.subline}>
          Все процедурные (Web Audio API), нет файлов.
          Реализация: <code>gdSfx/sfxFactories.js</code>
        </div>
        <div className={styles.controls}>
          <button className={styles.playAllBtn} onClick={playAll}>
            ▶ Проиграть всё подряд
          </button>
          {ready && <span className={styles.statusReady}>🔊 готов</span>}
        </div>
      </div>

      <div className={styles.grid}>
        {SFX_CATALOG.map(sfx => (
          <div
            key={sfx.id}
            className={`${styles.card} ${lastPlayed === sfx.id ? styles.cardActive : ''}`}
          >
            <div className={styles.cardHeader}>
              <span className={styles.emoji}>{sfx.emoji}</span>
              <div>
                <h3 className={styles.title}>{sfx.title}</h3>
                <code className={styles.id}>{sfx.id}</code>
              </div>
            </div>
            <p className={styles.description}>{sfx.description}</p>
            <div className={styles.cardActions}>
              <button className={styles.playBtn} onClick={() => playSfx(sfx)}>
                ▶ Играть
              </button>
              <span className={styles.duration}>{sfx.durationMs} мс</span>
            </div>
          </div>
        ))}
      </div>

      <div className={styles.footer}>
        <p><strong>Где использоваться:</strong></p>
        <ul>
          <li><code>jump</code> — при тапе/Space (в L1+)</li>
          <li><code>death</code> — при касании шипа или падении в холу</li>
          <li><code>orb_tap</code> — при активации Jump Orb (L7+)</li>
          <li><code>bounce</code> — при отскоке от трамплина (L3+)</li>
          <li><code>whoosh</code> — при ускорении от speed pad (L4+)</li>
          <li><code>flip</code> — при перевороте гравитации (L12+)</li>
          <li><code>coin</code> — при сборе монеты (любой уровень)</li>
          <li><code>level_complete</code> — при касании финиш-портала</li>
          <li><code>new_record</code> — поверх level_complete если время лучше прошлого</li>
        </ul>
      </div>
    </div>
  );
}

export default GdSfxPreview;
