/* IslamPlay — App shell */

function mutate(arr, next) {
  arr.splice(0, arr.length, ...(next || []));
}

async function loadAllData() {
  const [tracks, playlists, reciters] = await Promise.all([
    IP_API.tracks().catch(() => []),
    IP_API.playlists().catch(() => []),
    IP_API.reciters().catch(() => []),
  ]);
  mutate(IP_YASIN_TRACKS, tracks);
  mutate(IP_PLAYLISTS, playlists);
  mutate(IP_RECITERS, reciters);
  // Hydrate playlists with their tracks so PlaylistScreen has them
  const full = await Promise.all(
    playlists.map(p => IP_API.playlist(p.id).catch(() => null))
  );
  full.forEach((p, i) => { if (p) IP_PLAYLISTS[i].tracks = p.tracks; });
  const recent = await IP_API.recent().catch(() => []);
  mutate(IP_RECENT, recent.length ? recent : tracks.slice(0, 6));
}

// Delegated wheel handler — any element with data-hscroll or class ip-hscroll
// gets vertical mouse wheel translated to horizontal scroll, which is what
// desktop users expect on carousel-style rows.
if (typeof window !== 'undefined' && !window.__ipHScrollWired) {
  window.__ipHScrollWired = true;
  document.addEventListener('wheel', (e) => {
    const el = e.target.closest && e.target.closest('.ip-hscroll');
    if (!el) return;
    // Only translate when the element is horizontally scrollable and the
    // gesture is primarily vertical (trackpads pass deltaX natively).
    if (el.scrollWidth <= el.clientWidth) return;
    if (Math.abs(e.deltaY) <= Math.abs(e.deltaX)) return;
    el.scrollLeft += e.deltaY;
    e.preventDefault();
  }, { passive: false });
}

function IslamPlayApp() {
  const [route, setRoute] = React.useState('splash');
  const [tab, setTab] = React.useState('home');
  const [playlist, setPlaylist] = React.useState(null);
  const [user, setUser] = React.useState(null);
  const [currentTrack, setCurrentTrack] = React.useState(null);
  const [playing, setPlaying] = React.useState(false);
  const [progress, setProgress] = React.useState(0);
  const [duration, setDuration] = React.useState(0);
  const [playerOpen, setPlayerOpen] = React.useState(false);
  const [reciterSlug, setReciterSlug] = React.useState(
    () => (typeof localStorage !== 'undefined' && localStorage.getItem('ip-reciter-slug')) || ''
  );
  React.useEffect(() => {
    if (reciterSlug) localStorage.setItem('ip-reciter-slug', reciterSlug);
  }, [reciterSlug]);
  const [, forceRerender] = React.useReducer(x => x + 1, 0);
  const audioRef = React.useRef(null);
  const historyLogged = React.useRef(new Set());

  // Boot: check auth, then load data & go to right screen
  React.useEffect(() => {
    (async () => {
      const me = await IP_API.me();
      await loadAllData();
      // Default reciter = first one available (if not already set)
      if (!reciterSlug && IP_RECITERS[0]) setReciterSlug(IP_RECITERS[0].slug);
      if (me) {
        setUser(me);
        setCurrentTrack(IP_YASIN_TRACKS[0] || null);
        setTimeout(() => setRoute('tabs'), 1200);
      } else {
        setTimeout(() => setRoute('login'), 1200);
      }
      forceRerender();
    })();
  }, []);

  // Wire audio element
  React.useEffect(() => {
    const a = audioRef.current;
    if (!a) return;
    const onTime = () => {
      if (a.duration && Number.isFinite(a.duration)) setProgress(a.currentTime / a.duration);
    };
    const onMeta = () => {
      if (a.duration && Number.isFinite(a.duration)) setDuration(a.duration);
    };
    const onEnd = () => ctxRef.current.next();
    const onPlay = () => setPlaying(true);
    const onPause = () => setPlaying(false);
    a.addEventListener('timeupdate', onTime);
    a.addEventListener('loadedmetadata', onMeta);
    a.addEventListener('durationchange', onMeta);
    a.addEventListener('ended', onEnd);
    a.addEventListener('play', onPlay);
    a.addEventListener('pause', onPause);
    return () => {
      a.removeEventListener('timeupdate', onTime);
      a.removeEventListener('loadedmetadata', onMeta);
      a.removeEventListener('durationchange', onMeta);
      a.removeEventListener('ended', onEnd);
      a.removeEventListener('play', onPlay);
      a.removeEventListener('pause', onPause);
    };
  }, []);

  // When track changes, set src and play
  React.useEffect(() => {
    const a = audioRef.current;
    if (!a || !currentTrack?.audioUrl) return;
    if (a.src !== location.origin + currentTrack.audioUrl) {
      a.src = currentTrack.audioUrl;
      setDuration(0);  // reset until new metadata loads
      setProgress(0);
    }
    if (playing) a.play().catch(() => {});
    // Log play once per track per session
    if (user && !historyLogged.current.has(currentTrack.id)) {
      historyLogged.current.add(currentTrack.id);
      IP_API.logPlay(currentTrack.id, 0);
    }
  }, [currentTrack?.id]);

  // Play/pause sync
  React.useEffect(() => {
    const a = audioRef.current;
    if (!a) return;
    if (playing) a.play().catch(() => {});
    else a.pause();
  }, [playing]);

  const ctx = {
    user,
    setTab, tab,
    openPlaylist: async (pl) => {
      // Always get fresh tracks (in case playlist wasn't hydrated)
      const full = await IP_API.playlist(pl.id);
      setPlaylist(full || pl);
      setRoute('playlist');
    },
    playTrack: (t) => {
      setCurrentTrack(t);
      setPlaying(true);
      setPlayerOpen(true);
      if (audioRef.current) {
        audioRef.current.src = t.audioUrl;
        audioRef.current.play().catch(() => {});
      }
    },
    togglePlay: () => setPlaying(p => !p),
    next: () => {
      if (!currentTrack) return;
      const list = (playlist?.tracks || IP_YASIN_TRACKS);
      const i = list.findIndex(t => t.id === currentTrack.id);
      const nx = list[(i + 1) % list.length];
      if (nx) { setCurrentTrack(nx); setPlaying(true); setProgress(0); }
    },
    prev: () => {
      if (!currentTrack) return;
      const list = (playlist?.tracks || IP_YASIN_TRACKS);
      const i = list.findIndex(t => t.id === currentTrack.id);
      const pv = list[(i - 1 + list.length) % list.length];
      if (pv) { setCurrentTrack(pv); setPlaying(true); setProgress(0); }
    },
    progress,
    duration,
    setProgress: (p) => {
      setProgress(p);
      const a = audioRef.current;
      if (a && a.duration) a.currentTime = a.duration * p;
    },
    playing, currentTrack,
    refreshPlaylists: loadAllData,
    reciterSlug,
    setReciterSlug,
    // Tracks filtered to current default reciter (fallback: all if unset/missing).
    tracksForReciter: () => {
      if (!reciterSlug) return IP_YASIN_TRACKS;
      const filtered = IP_YASIN_TRACKS.filter(t => t.reciterSlug === reciterSlug);
      return filtered.length ? filtered : IP_YASIN_TRACKS;
    },
    closePlayer: () => setPlayerOpen(false),
    openPlayer: () => setPlayerOpen(true),
    back: () => { setRoute('tabs'); setPlaylist(null); },
    onLogout: async () => {
      await IP_API.logout();
      setUser(null);
      setPlaying(false);
      setRoute('login');
    },
  };
  const ctxRef = React.useRef(ctx);
  ctxRef.current = ctx;

  async function handleAuthSuccess(u, chosenReciterSlug) {
    setUser(u);
    await loadAllData();
    if (chosenReciterSlug) setReciterSlug(chosenReciterSlug);
    // Pick a first track — prefer the selected reciter's Al-Fatihah (surah 1)
    const slug = chosenReciterSlug || reciterSlug;
    const first =
      (slug && IP_YASIN_TRACKS.find(t => t.reciterSlug === slug && t.surah === 1)) ||
      IP_YASIN_TRACKS.find(t => t.surah === 1) ||
      IP_YASIN_TRACKS[0];
    if (first) setCurrentTrack(first);
    setRoute('tabs');
    forceRerender();
  }

  const screens = (
    <div className="ip-app-canvas" style={{ position: 'relative', background: '#0f0d0a', overflow: 'hidden' }}>
      <audio ref={audioRef} preload="metadata" crossOrigin="anonymous"/>
      {route === 'splash' && <SplashScreen onContinue={() => {}}/>}
      {route === 'login' && <LoginScreen onLogin={handleAuthSuccess} onGoRegister={() => setRoute('register')}/>}
      {route === 'register' && <RegisterScreen onRegister={handleAuthSuccess} onGoLogin={() => setRoute('login')}/>}
      {route === 'tabs' && user && tab === 'home' && <HomeScreen ctx={ctx}/>}
      {route === 'tabs' && user && tab === 'search' && <SearchScreen ctx={ctx}/>}
      {route === 'tabs' && user && tab === 'library' && <LibraryScreen ctx={ctx}/>}
      {route === 'tabs' && user && tab === 'profile' && <ProfileScreen ctx={ctx}/>}
      {route === 'playlist' && playlist && <PlaylistScreen ctx={ctx} playlist={playlist}/>}

      {user && (route === 'tabs' || route === 'playlist') && !playerOpen && currentTrack && (
        <>
          <IPMiniPlayer track={currentTrack} playing={playing} progress={progress}
            onPlay={ctx.togglePlay} onOpen={ctx.openPlayer}/>
          <IPTabBar active={tab} onChange={(t) => { setTab(t); if (route === 'playlist') setRoute('tabs'); }}/>
        </>
      )}

      {user && (route === 'tabs' || route === 'playlist') && !playerOpen && !currentTrack && (
        <IPTabBar active={tab} onChange={(t) => { setTab(t); if (route === 'playlist') setRoute('tabs'); }}/>
      )}

      {playerOpen && currentTrack && (
        <div style={{
          position: 'absolute', inset: 0, zIndex: 30,
          animation: 'ipSlideUp 0.3s ease-out',
        }}>
          <FullPlayerScreen ctx={ctx}/>
        </div>
      )}

      {/* Portal root for bottom sheets (modals). Rendered here so they overlay
          everything above — including the mini-player and tab bar. */}
      <div id="ip-sheet-root" style={{ position: 'absolute', inset: 0, pointerEvents: 'none', zIndex: 9999 }}>
        <style>{`#ip-sheet-root > * { pointer-events: auto; }`}</style>
      </div>
    </div>
  );

  return (
    <div className="ip-app-frame">
      <DesktopHero/>
      {screens}
      <style>{`
        @keyframes ipSlideUp {
          from { transform: translateY(24px); opacity: 0; }
          to { transform: translateY(0); opacity: 1; }
        }
      `}</style>
    </div>
  );
}

function DesktopHero() {
  const features = [
    { icon: 'book',  title: '114 сур', sub: 'Полный Коран в MP3' },
    { icon: 'mic',   title: '2 чтеца', sub: 'Ясир Ад-Доссари, Мухаммад Аль Лихидан' },
    { icon: 'heart', title: 'Избранное', sub: 'Сохраняйте любимые суры' },
    { icon: 'queue', title: 'Плейлисты', sub: 'Создавайте свои подборки' },
  ];
  return (
    <aside className="ip-hero">
      <div className="ip-hero-bismillah">﷽</div>
      <h1>Ислам Плей<span className="accent">Коран в каждом дне</span></h1>
      <div className="ip-hero-arabic">القرآن الكريم</div>
      <p className="ip-hero-lead">
        Слушайте полный Коран в исполнении лучших чтецов мира. Бесплатно, без рекламы, с любого устройства.
      </p>
      <div className="ip-hero-features">
        {features.map(f => (
          <div key={f.title} className="ip-hero-feature">
            <div className="ip-hero-feature-ico">
              <IPIcon name={f.icon} size={20} color="#e9c97a"/>
            </div>
            <div>
              <div className="ip-hero-feature-title">{f.title}</div>
              <div className="ip-hero-feature-sub">{f.sub}</div>
            </div>
          </div>
        ))}
      </div>
      <div className="ip-hero-footer">
        <span className="ip-hero-footer-dot"/>
        Доступно онлайн · Никаких подписок
      </div>
    </aside>
  );
}

function Root() {
  return <IslamPlayApp/>;
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Root/>);
