// Reel — root component: onboarding check + main app navigation

// ── Codec support detection (run once, cached) ──────────────────────────
const CODEC_SUPPORT = (() => {
  const v = document.createElement('video');
  const can = (type) => v.canPlayType(type) !== '';
  return {
    h264:    can('video/mp4; codecs="avc1.42E01E"'),
    h265:    can('video/mp4; codecs="hvc1"') || can('video/mp4; codecs="hev1"'),
    vp9:     can('video/webm; codecs="vp9"'),
    vp8:     can('video/webm; codecs="vp8"'),
    av1:     can('video/webm; codecs="av01.0.05M.08"'),
    mkvH264: can('video/x-matroska; codecs="avc1"'),
    mkvH265: can('video/x-matroska; codecs="hvc1"') || can('video/x-matroska; codecs="hev1"'),
  };
})();
window.REEL_CODEC_SUPPORT = CODEC_SUPPORT;

const TWEAK_DEFAULTS = {
  accent: '#ef4444',
  theme: 'dark',
  layout: 'grid',
  chrome: 'full',
  subtitleStyle: 'cinema',
  skipSeconds: 10,
};

function ReelRoot() {
  const [onboarded, setOnboarded] = React.useState(() => !!localStorage.getItem('reel-onboarded'));
  const [videos, setVideos]       = React.useState([]);
  const [tweaks, setTweak]        = useTweaks(TWEAK_DEFAULTS);
  const [loading, setLoading]     = React.useState(true);
  // 'ok' | 'banner' | 'permission' | null
  // 'ok'         — files accessible (silent rescan worked)
  // 'permission' — folder handle exists, needs one user tap to grant permission
  // 'banner'     — no folder handle (file-picker mode), needs full re-scan
  // null         — no videos in library yet
  const [reconnect, setReconnect] = React.useState(null);

  React.useEffect(() => {
    if (!onboarded) { setLoading(false); return; }
    REEL_DB.open()
      .then(() => REEL_DB.getAllVideos())
      .then(async vs => {
        setVideos(vs || []);

        if (vs && vs.length > 0) {
          // Attempt a silent rescan on every startup
          try {
            const result = await REEL_SCANNER.silentRescan(() => {});
            if (Array.isArray(result) && result.length > 0) {
              // Permission already granted — merge results into DB quietly
              await REEL_DB.putVideos(result);
              const fresh = await REEL_DB.getAllVideos();
              setVideos(fresh);
              setReconnect('ok');
            } else if (result === 'needs-permission') {
              // Folder handle stored but browser needs one tap from user
              setReconnect('permission');
            } else {
              // No stored handle (used file-picker) — show restore banner
              setReconnect('banner');
            }
          } catch (e) {
            setReconnect('banner');
          }
        }

        setLoading(false);
      })
      .catch(() => setLoading(false));
  }, [onboarded]);

  const handleOnboardDone = (scanned) => {
    setVideos(scanned || []);
    setOnboarded(true);
    setLoading(false);
    setReconnect(scanned && scanned.length > 0 ? 'ok' : null);
  };

  if (!onboarded) return <OnboardingFlow onDone={handleOnboardDone}/>;
  if (loading)    return <LoadingScreen/>;

  return (
    <ReelApp
      videos={videos}
      setVideos={setVideos}
      tweaks={tweaks}
      setTweak={setTweak}
      reconnect={reconnect}
      setReconnect={setReconnect}
    />
  );
}

function LoadingScreen() {
  const T = REEL_TOKENS;
  return (
    <div style={{ position:'fixed',inset:0,background:T.bg,display:'flex',alignItems:'center',justifyContent:'center' }}>
      <style>{`@keyframes spin{to{transform:rotate(360deg)}}`}</style>
      <div style={{ width:40,height:40,border:'3px solid rgba(255,255,255,0.1)',borderTopColor:T.accent,borderRadius:'50%',animation:'spin 0.8s linear infinite' }}/>
    </div>
  );
}

// ── Reconnect banner ────────────────────────────────────────────────────
function ReconnectBanner({ kind, accent, onRestore, onDismiss }) {
  const T = REEL_TOKENS;
  const isPermission = kind === 'permission';
  return (
    <div style={{ margin:'10px 14px 0',borderRadius:14,background:T.surface,border:'1px solid '+T.border,padding:'12px 14px',display:'flex',alignItems:'center',gap:12 }}>
      <div style={{ width:38,height:38,borderRadius:11,background:accentSoftColor(accent),display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0 }}>
        <Icon name="folder" size={20} color={accent}/>
      </div>
      <div style={{ flex:1,minWidth:0 }}>
        <div style={{ fontSize:13,fontWeight:700,color:T.text }}>
          {isPermission ? 'Tap to restore your library' : 'Re-link your videos'}
        </div>
        <div style={{ fontSize:11,color:T.textDim,marginTop:1,lineHeight:1.4 }}>
          {isPermission
            ? 'Your folder is saved — one tap restores everything'
            : 'Your history is safe. Pick your videos folder to play them again.'}
        </div>
      </div>
      <div style={{ display:'flex',gap:6,flexShrink:0 }}>
        <button onClick={onRestore} style={{ padding:'8px 14px',borderRadius:10,border:'none',background:accent,color:'#000',fontSize:12,fontWeight:700,fontFamily:'inherit',cursor:'pointer',whiteSpace:'nowrap' }}>
          {isPermission ? 'Restore' : 'Re-link'}
        </button>
        <button onClick={onDismiss} style={{ width:32,height:32,borderRadius:10,border:'none',background:T.surface2,color:T.textDim,display:'flex',alignItems:'center',justifyContent:'center',cursor:'pointer',flexShrink:0 }}>
          <Icon name="close" size={16}/>
        </button>
      </div>
    </div>
  );
}

// ── Main app with navigation ────────────────────────────────────────────
function ReelApp({ videos, setVideos, tweaks, setTweak, reconnect, setReconnect }) {
  const T = REEL_TOKENS;
  const accent = tweaks.accent || T.accent;
  const dark = tweaks.theme !== 'light';

  // Screen stack: [{ kind, payload }]
  const [stack, setStack] = React.useState([{ kind:'home' }]);
  const push = entry => setStack(s => [...s, entry]);
  const pop  = ()    => setStack(s => s.length > 1 ? s.slice(0, -1) : s);
  const setTab = id  => setStack([{ kind: id === 'home' ? 'home' : id }]);

  const top = stack[stack.length - 1];

  const tabForTop = (() => {
    if (top.kind === 'folder' || top.kind === 'folders') return 'folders';
    if (top.kind === 'playlists' || top.kind === 'private') return 'playlists';
    if (top.kind === 'settings') return 'settings';
    return 'home';
  })();

  const [overlay, setOverlay]   = React.useState(null);
  const [dualSubs, setDualSubs] = React.useState(false);
  const [nowPlaying, setNowPlaying] = React.useState(null);
  const [npPlaying, setNpPlaying]   = React.useState(false);
  const [scanning, setScanning]     = React.useState(false);
  const [speed, setSpeed]           = React.useState(1);

  const openVideo = video => {
    setNowPlaying(video);
    push({ kind:'player', payload:video });
    setOverlay(null);
  };

  const [scanModal, setScanModal] = React.useState(false);

  const doScan = async (mode) => {
    setScanModal(false);
    setScanning(true);
    try {
      let results = null;
      if (!mode) {
        // Try re-use existing handle first (will prompt permission if needed)
        results = await REEL_SCANNER.rescan((c,n,f) => {});
      }
      if (!results) {
        results = await REEL_SCANNER.scan((c,n,f) => {}, mode || undefined);
      }
      if (results && results.length > 0) {
        await REEL_DB.putVideos(results);
        const fresh = await REEL_DB.getAllVideos();
        setVideos(fresh);
        setReconnect('ok'); // files are accessible now
      }
    } catch (e) {}
    setScanning(false);
  };

  // Called from reconnect banner — for 'permission' kind use rescan()
  // which will prompt permission; for 'banner' kind open the scan picker
  const handleReconnect = async () => {
    if (reconnect === 'permission') {
      setScanning(true);
      setReconnect(null);
      try {
        const results = await REEL_SCANNER.rescan(() => {});
        if (results && results.length > 0) {
          await REEL_DB.putVideos(results);
          const fresh = await REEL_DB.getAllVideos();
          setVideos(fresh);
          setReconnect('ok');
        } else {
          setScanModal(true); // fallback to picker if handle failed
        }
      } catch (e) { setScanModal(true); }
      setScanning(false);
    } else {
      setScanModal(true);
    }
  };

  const handleRescan = () => setScanModal(true);

  const handleVideoUpdate = (id, pos, dur) => {
    setVideos(vs => vs.map(v => v.id === id ? { ...v, resumePos:pos, progress:dur>0?Math.min(1,pos/dur):0, lastPlayed:Date.now() } : v));
    if (nowPlaying && nowPlaying.id === id) {
      setNowPlaying(prev => ({ ...prev, resumePos:pos, progress:dur>0?Math.min(1,pos/dur):0 }));
    }
  };

  const handleToggleFav = async (id) => {
    const newFav = await REEL_DB.toggleFav(id);
    setVideos(vs => vs.map(v => v.id === id ? { ...v, fav:newFav } : v));
  };

  const inPlayer = top.kind === 'player';

  // ── File Handling API (launchQueue) — opens when user double-clicks a video in Explorer ──
  React.useEffect(() => {
    if (!('launchQueue' in window)) return;
    window.launchQueue.setConsumer(async (launchParams) => {
      if (!launchParams.files || !launchParams.files.length) return;
      const entries = [];
      for (const fileHandle of launchParams.files) {
        try {
          const file = await fileHandle.getFile();
          if (!REEL_SCANNER.isVideo(file.name)) continue;
          const entry = REEL_SCANNER.entryFromFile(file, 'Opened Files', fileHandle);
          entries.push(entry);
        } catch(e) {}
      }
      if (!entries.length) return;
      await REEL_DB.putVideos(entries);
      const fresh = await REEL_DB.getAllVideos();
      setVideos(fresh);
      setReconnect('ok');
      // Open the first file immediately
      openVideo(entries[0]);
    });
  }, []);

  // ── Global drag-and-drop — drag any video file onto the window ──
  React.useEffect(() => {
    const prevent = e => { e.preventDefault(); e.stopPropagation(); };
    const onDrop = async e => {
      e.preventDefault(); e.stopPropagation();
      setDragOver(false);
      const files = Array.from(e.dataTransfer.files || []).filter(f => REEL_SCANNER.isVideo(f.name));
      if (!files.length) return;
      const entries = files.map(f => REEL_SCANNER.entryFromFile(f, 'Dropped Files', null));
      await REEL_DB.putVideos(entries);
      const fresh = await REEL_DB.getAllVideos();
      setVideos(fresh);
      setReconnect('ok');
      // Open the first dropped file immediately
      openVideo(entries[0]);
    };
    const onDragEnter = e => { e.preventDefault(); if (!inPlayer) setDragOver(true); };
    const onDragLeave = e => { if (!e.relatedTarget || !document.body.contains(e.relatedTarget)) setDragOver(false); };
    window.addEventListener('dragover',  prevent);
    window.addEventListener('dragenter', onDragEnter);
    window.addEventListener('dragleave', onDragLeave);
    window.addEventListener('drop',      onDrop);
    return () => {
      window.removeEventListener('dragover',  prevent);
      window.removeEventListener('dragenter', onDragEnter);
      window.removeEventListener('dragleave', onDragLeave);
      window.removeEventListener('drop',      onDrop);
    };
  }, [inPlayer]);

  const [dragOver, setDragOver] = React.useState(false);

  // Show reconnect banner only on home screen, not in player
  const showBanner = !inPlayer && (reconnect === 'banner' || reconnect === 'permission') && videos.length > 0;

  // Player fav-scenes and bookmarks for the overlay
  const [playerFavScenes, setPlayerFavScenes] = React.useState([]);
  const [playerBookmarks, setPlayerBookmarks] = React.useState([]);
  React.useEffect(() => {
    if (inPlayer && top.payload) {
      REEL_DB.getFavScenes(top.payload.id).then(s => setPlayerFavScenes(s||[]));
      REEL_DB.getBookmarks(top.payload.id).then(b => setPlayerBookmarks(b||[]));
    }
  }, [inPlayer, top.payload?.id]);

  return (
    <div style={{ position:'fixed',inset:0,background:dark?T.bg:'#f7f5f0',color:dark?T.text:'#161513',fontFamily:T.sans,display:'flex',flexDirection:'column',overflow:'hidden' }}>

      {inPlayer ? (
        <PlayerScreen
          video={top.payload}
          onBack={pop}
          accent={accent}
          chromeStyle={tweaks.chrome}
          subtitleStyle={tweaks.subtitleStyle}
          overlay={overlay}
          setOverlay={setOverlay}
          dualSubs={dualSubs}
          skipSeconds={tweaks.skipSeconds || 10}
          onVideoUpdate={handleVideoUpdate}
          speed={speed}
        />
      ) : (
        <>
          {/* Reconnect banner — shown at the top when files need re-linking */}
          {showBanner && (
            <ReconnectBanner
              kind={reconnect}
              accent={accent}
              onRestore={handleReconnect}
              onDismiss={() => setReconnect(null)}
            />
          )}

          <div style={{ flex:1,overflow:'auto',position:'relative',WebkitOverflowScrolling:'touch' }}>
            {top.kind === 'home' && (
              <LibraryScreen videos={videos} open={openVideo} onSearch={() => push({ kind:'search' })} layout={tweaks.layout} accent={accent} onRescan={handleRescan} scanning={scanning}/>
            )}
            {top.kind === 'folders' && (
              <FoldersScreen videos={videos} openFolder={f => push({ kind:'folder', payload:f })} accent={accent} onRescan={handleRescan}/>
            )}
            {top.kind === 'folder' && (
              <FolderDetail folder={top.payload} open={openVideo} onBack={pop} accent={accent}/>
            )}
            {top.kind === 'search' && (
              <SearchScreen videos={videos} onBack={pop} open={openVideo} accent={accent}/>
            )}
            {top.kind === 'playlists' && (
              <PlaylistsScreen videos={videos} accent={accent} onPrivate={() => push({ kind:'private' })}/>
            )}
            {top.kind === 'settings' && (
              <SettingsScreen accent={accent} tweaks={tweaks} setTweak={setTweak} onRescan={handleRescan} onHistory={() => push({ kind:'history' })} videoCount={videos.length}/>
            )}
            {top.kind === 'private' && (
              <PrivateLock onBack={pop} accent={accent}/>
            )}
            {top.kind === 'history' && (
              <HistoryScreen onBack={pop} open={openVideo} videos={videos} accent={accent}/>
            )}
          </div>

          {nowPlaying && top.kind !== 'private' && (
            <NowPlayingBar video={nowPlaying} playing={npPlaying} accent={accent} onPlay={() => setNpPlaying(p=>!p)} onExpand={() => push({ kind:'player', payload:nowPlaying })}/>
          )}

          {top.kind !== 'private' && top.kind !== 'history' && (
            <TabBar tab={tabForTop} setTab={setTab} accent={accent}/>
          )}
        </>
      )}

      {/* Player overlays — rendered over everything */}
      {overlay === 'subtitle' && (
        <SubtitleSheet onClose={() => setOverlay(null)} accent={accent} dualSubs={dualSubs} setDualSubs={setDualSubs} onAdd={kind => setOverlay('add-' + kind)}/>
      )}
      {overlay === 'add-file'   && <Sheet title="Add subtitle from device" onClose={() => setOverlay('subtitle')} accent={accent}><div style={{ padding:'20px 0',textAlign:'center',color:REEL_TOKENS.textDim }}>Pick an .srt or .vtt file from your device</div></Sheet>}
      {overlay === 'add-online' && <Sheet title="OpenSubtitles" onClose={() => setOverlay('subtitle')}><div style={{ padding:'20px 0',textAlign:'center',color:REEL_TOKENS.textDim }}>Search coming soon</div></Sheet>}
      {overlay === 'speed'     && <SpeedSheet onClose={() => setOverlay(null)} accent={accent} speed={speed} onSpeed={s => { setSpeed(s); const vid=document.querySelector('video'); if(vid) vid.playbackRate=s; }}/>}
      {overlay === 'eq'        && <EQSheet onClose={() => setOverlay(null)} accent={accent}/>}
      {overlay === 'sleep'     && <SleepSheet onClose={() => setOverlay(null)} accent={accent}/>}
      {(overlay === 'bookmarks' || overlay === 'chapters') && (
        <BookmarksSheet onClose={() => setOverlay(null)} accent={accent} favScenes={playerFavScenes} bookmarks={playerBookmarks}/>
      )}
      {overlay === 'audio'     && <AudioSheet onClose={() => setOverlay(null)} accent={accent}/>}
      {overlay === 'settings'  && <PlayerSettingsSheet onClose={() => setOverlay(null)} accent={accent} setOverlay={setOverlay}/>}
      {overlay === 'rotation'  && <RotationSheet onClose={() => setOverlay(null)} accent={accent}/>}
      {overlay === 'more'      && <PlayerSettingsSheet onClose={() => setOverlay(null)} accent={accent} setOverlay={setOverlay}/>}
      {overlay === 'pip' && nowPlaying && (
        <PiPOverlay video={nowPlaying} onClose={() => setOverlay(null)} accent={accent}/>
      )}
      {overlay === 'pip' && inPlayer && (
        <PiPOverlay video={top.payload} onClose={() => setOverlay(null)} accent={accent}/>
      )}

      {/* Scan method picker modal */}
      {scanModal && <ScanPickerModal accent={accent} onPick={doScan} onClose={() => setScanModal(false)}/>}

      {/* Drag-and-drop overlay */}
      {dragOver && (
        <div style={{ position:'fixed',inset:0,zIndex:100,background:'rgba(0,0,0,0.85)',display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',gap:16,backdropFilter:'blur(8px)',border:`3px dashed ${accent}`,pointerEvents:'none' }}>
          <div style={{ width:80,height:80,borderRadius:24,background:accentSoftColor(accent),display:'flex',alignItems:'center',justifyContent:'center' }}>
            <Icon name="film" size={40} color={accent}/>
          </div>
          <div style={{ fontSize:22,fontWeight:800,color:'#fff',letterSpacing:-0.3 }}>Drop to play</div>
          <div style={{ fontSize:14,color:'rgba(255,255,255,0.5)' }}>Drop any video file — it loads instantly</div>
        </div>
      )}
    </div>
  );
}

// Mount the app
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<ReelRoot/>);
