// ============================================================
// LLVIP API · React 接入组件
// 依赖：npm i hls.js
// 用法：<TVParser url="https://v.qq.com/x/cover/xxx/yyy.html" />
// ============================================================
import { useEffect, useState, useRef, useCallback } from 'react';
import Hls from 'hls.js';

const API = 'https://llvipapi.pages.dev';

export default function TVParser({ url }) {
  const [info, setInfo] = useState(null);        // { title, episode_all, ... }
  const [episodes, setEpisodes] = useState([]);  // 全部选集（含直链）
  const [current, setCurrent] = useState(null);  // 当前播放集
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');
  const videoRef = useRef(null);
  const hlsRef = useRef(null);

  /* 解析全剧：一个请求拿全部直链 */
  useEffect(() => {
    if (!url) return;
    setLoading(true); setError('');
    fetch(`${API}/api/resolve?url=${encodeURIComponent(url)}`)
      .then(r => r.json())
      .then(d => {
        if (d.code !== 0) throw new Error(d.msg || '解析失败');
        setInfo(d);
        setEpisodes(d.episodes);
      })
      .catch(e => setError(String(e)))
      .finally(() => setLoading(false));
  }, [url]);

  /* 播放某集（跨域经 /api/hls 代理） */
  const play = useCallback((ep) => {
    if (!ep.link) return;
    setCurrent(ep);
    const video = videoRef.current;
    if (!video) return;
    if (Hls.isSupported()) {
      hlsRef.current?.destroy();
      const hls = new Hls();
      hlsRef.current = hls;
      hls.loadSource(`${API}/api/hls?url=${encodeURIComponent(ep.link)}`);
      hls.attachMedia(video);
    } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
      video.src = `${API}/api/hls?url=${encodeURIComponent(ep.link)}`;
    }
    video.play().catch(() => {});
  }, []);

  /* 组件卸载时释放 hls */
  useEffect(() => () => hlsRef.current?.destroy(), []);

  return (
    <div style={{ maxWidth: 960, margin: '0 auto', fontFamily: 'system-ui' }}>
      <video ref={videoRef} controls playsInline style={{ width: '100%', background: '#000' }} />

      {loading && <p>解析中…</p>}
      {error && <p style={{ color: 'red' }}>{error}</p>}
      {info && (
        <p>
          《{info.title}》{info.episode_all} · 共 {info.zhengpian} 集正片
          （免费 {episodes.filter(e => e.full).length} 集可完整播放）
        </p>
      )}

      <ul style={{ listStyle: 'none', padding: 0, maxHeight: 420, overflowY: 'auto' }}>
        {episodes.map(ep => (
          <li key={ep.vid}
              onClick={() => play(ep)}
              style={{
                display: 'flex', gap: 8, alignItems: 'center',
                padding: '8px 10px', cursor: 'pointer', borderRadius: 8,
                background: current?.vid === ep.vid ? '#16233c' : 'transparent',
              }}>
            <b style={{ minWidth: 32 }}>{ep.n}</b>
            <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
              {ep.title}
            </span>
            <small style={{ color: ep.full ? '#34d399' : '#fbbf24' }}>
              {ep.full ? '✓ 完整版' : '试看'}
            </small>
          </li>
        ))}
      </ul>
    </div>
  );
}
