// Import — bring your library with you, on your terms.
// Two paths in, one culling step in the middle:
//   1. A YouTube playlist URL → its videos land in Saved Videos.
//   2. A Google Takeout subscriptions.csv → channels join your feed.
// Nothing is imported unchecked: you choose what deserves to come along.

const { useState: useStateIm, useRef: useRefIm } = React;

function playlistIdFrom(input) {
  const s = String(input || '').trim();
  if (!s) return null;
  if (/^(PL|UU|LL|FL|OL|RD)[\w-]{10,}$/.test(s)) return s;
  try {
    const u = new URL(/^https?:\/\//.test(s) ? s : 'https://' + s);
    const list = u.searchParams.get('list');
    if (list) return list;
  } catch { /* not a URL */ }
  return null;
}

function ImportModal({ state, dispatch }) {
  const [mode, setMode] = useStateIm('choose'); // choose | playlist | csv | working | done | error
  const [plUrl, setPlUrl] = useStateIm('');
  const [plTitle, setPlTitle] = useStateIm('');
  const [items, setItems] = useStateIm([]);        // playlist videos OR csv channels
  const [checked, setChecked] = useStateIm(new Set());
  const [kind, setKind] = useStateIm(null);        // 'playlist' | 'csv'
  const [progress, setProgress] = useStateIm({ done: 0, total: 0, label: '' });
  const [failures, setFailures] = useStateIm([]);
  const [summary, setSummary] = useStateIm('');
  const [error, setError] = useStateIm(null);
  const cancelRef = useRefIm(false);

  const close = () => { cancelRef.current = true; dispatch({ type: 'close-import' }); };
  const toggle = (id) => setChecked(s => { const n = new Set(s); n.has(id) ? n.delete(id) : n.add(id); return n; });
  const setAll = (on) => setChecked(on ? new Set(items.map(i => i.id)) : new Set());

  // ---- path 1: playlist ----
  const loadPlaylist = async () => {
    const id = playlistIdFrom(plUrl);
    if (!id) { setError('That doesn’t look like a playlist URL — it needs a "list=" parameter.'); setMode('error'); return; }
    setMode('working');
    setProgress({ done: 0, total: 0, label: 'Reading playlist…' });
    try {
      const r = await fetch('/api/playlist?id=' + encodeURIComponent(id));
      const body = await r.json();
      if (!r.ok) throw new Error(body?.error || `Playlist fetch failed (${r.status})`);
      const vids = (body.videos || []).filter(v => !state.videos.find(x => x.id === v.id));
      if (!vids.length) { setError('No new videos found in that playlist (already imported, or it’s empty/private).'); setMode('error'); return; }
      setPlTitle(body.title || 'Playlist');
      setItems(vids);
      setChecked(new Set(vids.map(v => v.id)));
      setKind('playlist');
      setMode('cull');
    } catch (e) {
      setError(String(e?.message || e));
      setMode('error');
    }
  };

  // ---- path 2: Takeout CSV ----
  const loadCsv = async (file) => {
    if (!file) return;
    try {
      const text = await file.text();
      const subs = window.SoloUtils.parseTakeoutSubscriptions(text)
        .filter(c => !state.channels.find(x => x.id === c.id));
      if (!subs.length) { setError('No new channels found in that file. Expected Google Takeout’s subscriptions.csv.'); setMode('error'); return; }
      setItems(subs);
      setChecked(new Set(subs.map(c => c.id)));
      setKind('csv');
      setMode('cull');
    } catch (e) {
      setError(String(e?.message || e));
      setMode('error');
    }
  };

  // ---- the actual import ----
  const runImport = async () => {
    const selected = items.filter(i => checked.has(i.id));
    if (!selected.length) return;
    cancelRef.current = false;
    setFailures([]);
    setMode('working');

    if (kind === 'playlist') {
      setProgress({ done: 0, total: selected.length, label: 'Adding to Saved Videos…' });
      dispatch({ type: 'add-videos-bulk', videos: selected });
      setSummary(`${selected.length} video${selected.length === 1 ? '' : 's'} from “${plTitle}” added to Saved Videos.`);
      setMode('done');
      return;
    }

    // CSV channels: resolve + fetch recent uploads, one channel at a time.
    const failed = [];
    let added = 0;
    for (let i = 0; i < selected.length; i++) {
      if (cancelRef.current) break;
      const ch = selected[i];
      setProgress({ done: i, total: selected.length, label: ch.title });
      try {
        const r1 = await fetch('/api/resolve-channel?url=' + encodeURIComponent(ch.url));
        const channel = await r1.json();
        if (!r1.ok) throw new Error(channel?.error || `resolve failed (${r1.status})`);
        const u = new URL('/api/channel-videos', window.location.origin);
        if (channel.uploadsPlaylistId) u.searchParams.set('uploadsPlaylistId', channel.uploadsPlaylistId);
        u.searchParams.set('channelId', channel.id);
        u.searchParams.set('max', '10');
        const r2 = await fetch(u);
        const body = await r2.json();
        if (!r2.ok) throw new Error(body?.error || `videos failed (${r2.status})`);
        dispatch({ type: 'add-channel', channel, videos: body.videos || [] });
        added++;
      } catch (e) {
        failed.push({ title: ch.title, why: String(e?.message || e).slice(0, 80) });
      }
    }
    setFailures(failed);
    setSummary(
      cancelRef.current
        ? `Stopped — ${added} channel${added === 1 ? '' : 's'} imported before you cancelled.`
        : `${added} channel${added === 1 ? '' : 's'} imported${failed.length ? `, ${failed.length} failed` : ''}.`
    );
    setMode('done');
  };

  const selCount = checked.size;

  return (
    <div className="modal-back" onMouseDown={(e) => { if (e.target === e.currentTarget && mode !== 'working') close(); }}>
      <div className="modal modal-import">
        <div className="modal-head">
          <span>⇪ IMPORT · BRING YOUR LIBRARY WITH YOU</span>
          <button className="x" onClick={close}>✕</button>
        </div>
        <div className="modal-body">

          {mode === 'choose' && (
            <>
              <div className="modal-step-label">TWO WAYS IN — YOU CULL EITHER WAY</div>
              <h2 className="modal-title">What are you bringing over?</h2>

              <div className="imp-option">
                <div className="imp-option-head">A PLAYLIST</div>
                <p className="modal-desc" style={{margin: '6px 0 10px'}}>
                  Paste a playlist link. Its videos go to <b>Saved Videos</b> — no channels are followed.
                </p>
                <div style={{display:'flex', gap: 8}}>
                  <input
                    className="url" style={{flex:1, marginTop:0}}
                    value={plUrl}
                    onChange={(e) => setPlUrl(e.target.value)}
                    onKeyDown={(e) => { if (e.key === 'Enter') loadPlaylist(); }}
                    placeholder="https://www.youtube.com/playlist?list=PL…"
                  />
                  <button className="btn-primary" disabled={!plUrl.trim()} onClick={loadPlaylist}>Load →</button>
                </div>
              </div>

              <div className="imp-option">
                <div className="imp-option-head">YOUR SUBSCRIPTIONS</div>
                <p className="modal-desc" style={{margin: '6px 0 10px'}}>
                  Export them once from{' '}
                  <a href="https://takeout.google.com" target="_blank" rel="noopener noreferrer" style={{textDecoration:'underline'}}>takeout.google.com</a>
                  {' '}(select only YouTube → subscriptions), then drop the <b>subscriptions.csv</b> here.
                  No Google login required.
                </p>
                <label className="imp-file">
                  <input
                    type="file"
                    accept=".csv,text/csv"
                    style={{display:'none'}}
                    onChange={(e) => loadCsv(e.target.files?.[0])}
                  />
                  ⇪ Choose subscriptions.csv
                </label>
              </div>
            </>
          )}

          {mode === 'cull' && (
            <>
              <div className="modal-step-label">
                {kind === 'playlist' ? `“${plTitle.toUpperCase()}” · ${items.length} VIDEOS` : `${items.length} CHANNELS FOUND`}
              </div>
              <h2 className="modal-title">Choose what deserves to come with you.</h2>
              <p className="modal-desc">
                {kind === 'playlist'
                  ? 'Uncheck the ones you’re honestly never going to watch. They stay on YouTube.'
                  : 'This is the moment to drop the channels you only ever scroll past. Following is a choice.'}
              </p>
              <div className="imp-list-tools">
                <button onClick={() => setAll(true)}>all</button>
                <span>/</span>
                <button onClick={() => setAll(false)}>none</button>
                <span className="imp-count">{selCount} selected</span>
              </div>
              <div className="imp-list">
                {items.map(it => (
                  <label key={it.id} className={`imp-row ${checked.has(it.id) ? 'on' : ''}`}>
                    <input type="checkbox" checked={checked.has(it.id)} onChange={() => toggle(it.id)} />
                    <span className="imp-check"></span>
                    <span className="imp-row-title">{it.title}</span>
                    <span className="imp-row-sub">
                      {kind === 'playlist' ? `${it.sourceName || ''} · ${it.duration}` : it.id.slice(0, 12) + '…'}
                    </span>
                  </label>
                ))}
              </div>
            </>
          )}

          {mode === 'working' && (
            <div style={{padding: '36px 0', textAlign: 'center'}}>
              <div style={{fontFamily:'var(--ff-mono)', fontSize: 11, letterSpacing: '0.14em', color: 'var(--ink-3)', textTransform: 'uppercase'}}>
                {progress.total ? `Importing ${progress.done + 1} / ${progress.total}` : 'Working…'}
              </div>
              <div style={{marginTop: 16, fontFamily:'var(--ff-mono)', fontSize: 12, color: 'var(--ink)'}}>
                {progress.label}
              </div>
              {progress.total > 0 && (
                <div className="imp-progress"><div className="imp-progress-fill" style={{width: (progress.done / progress.total * 100) + '%'}}></div></div>
              )}
              {kind === 'csv' && (
                <button className="btn-ghost" style={{marginTop: 22}} onClick={() => { cancelRef.current = true; }}>
                  Stop here
                </button>
              )}
            </div>
          )}

          {mode === 'done' && (
            <div style={{padding: '28px 0'}}>
              <div style={{fontFamily:'var(--ff-display)', fontSize: 24, fontWeight: 500, letterSpacing:'-0.01em'}}>
                Done.
              </div>
              <p className="modal-desc" style={{marginTop: 10}}>{summary}</p>
              {failures.length > 0 && (
                <div className="imp-failures">
                  {failures.map((f, i) => (
                    <div key={i} className="imp-fail-row"><b>{f.title}</b> — {f.why}</div>
                  ))}
                </div>
              )}
            </div>
          )}

          {mode === 'error' && (
            <div style={{padding: '24px 0'}}>
              <div className="modal-step-label" style={{color: 'var(--new)'}}>THAT DIDN&rsquo;T WORK</div>
              <p className="modal-desc" style={{whiteSpace:'pre-wrap'}}>{error}</p>
            </div>
          )}
        </div>

        <div className="modal-foot">
          <span>
            {mode === 'cull' ? 'Unchecked items are simply left behind' :
             mode === 'choose' ? 'ESC to cancel' : ''}
          </span>
          <div style={{display:'flex', gap:8}}>
            {mode === 'choose' && <button className="btn-ghost" onClick={close}>Cancel</button>}
            {mode === 'cull' && (
              <>
                <button className="btn-ghost" onClick={() => { setItems([]); setMode('choose'); }}>← Back</button>
                <button className="btn-primary" disabled={!selCount} onClick={runImport}>
                  Import {selCount} {kind === 'playlist' ? (selCount === 1 ? 'video' : 'videos') : (selCount === 1 ? 'channel' : 'channels')}
                </button>
              </>
            )}
            {(mode === 'done' || mode === 'error') && (
              <>
                <button className="btn-ghost" onClick={() => { setItems([]); setError(null); setMode('choose'); }}>Import more</button>
                <button className="btn-primary" onClick={close}>Close</button>
              </>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

window.ImportModal = ImportModal;
