/**
 * share-player.jsx — frontend-pub 전용
 *
 * URL: https://songfilm-pub.jskimoffice.com?sharedID={64-char-hex}
 *
 * 1. URL에서 sharedID 파라미터를 읽는다.
 * 2. storage-api의 GET /share-links/:shareId 로 앨범 데이터를 가져온다.
 *    (서버 측에서 만료 검증 → 만료 시 410 응답)
 * 3. 성공하면 AlbumPlayerView로 앨범을 표시한다.
 * 4. 만료/없음/에러 상태는 각각 전용 페이지를 보여준다.
 */

const {
  useState:  useStateSP,
  useEffect: useEffectSP,
  useCallback: useCallbackSP,
  useMemo:   useMemoSP,
} = React;

// ── 상태 페이지 ────────────────────────────────────────────────────

function ShareExpiredPage() {
  return (
    <div className="share-status-page">
      <div className="share-status-icon">⏰</div>
      <h2>공유 링크가 만료되었습니다</h2>
      <p>
        이 공유 링크의 유효 기간(5일)이 지났습니다.<br/>
        앨범 소유자에게 새로운 링크를 요청해 주세요.
      </p>
    </div>
  );
}

function ShareNotFoundPage({ message }) {
  const { Icon } = window;
  return (
    <div className="share-status-page">
      <div className="share-status-icon">🔍</div>
      <h2>앨범을 찾을 수 없습니다</h2>
      <p>{message || '공유 링크가 올바르지 않거나 앨범이 삭제되었습니다.'}</p>
      <a
        className="pill-btn"
        href="https://songfilm.jskimoffice.com/"
        title="SongFilm App으로 이동"
        aria-label="SongFilm App으로 이동"
      >
        <Icon.Home size={12}/> SongFilm App
      </a>
    </div>
  );
}

function ShareErrorPage({ message }) {
  const { Icon } = window;
  return (
    <div className="share-status-page">
      <div className="share-status-icon">⚠️</div>
      <h2>오류가 발생했습니다</h2>
      <p>{message || '앨범을 불러오는 중 오류가 발생했습니다. 잠시 후 다시 시도해 주세요.'}</p>
      <button className="pill-btn" onClick={() => window.location.reload()}>다시 시도</button>
      <a
        className="pill-btn"
        href="https://songfilm.jskimoffice.com/"
        title="SongFilm App으로 이동"
        aria-label="SongFilm App으로 이동"
      >
        <Icon.Home size={12}/> SongFilm App
      </a>
    </div>
  );
}

// ── 앨범 플레이어 ──────────────────────────────────────────────────

function SharedAlbumPlayer({ shareData }) {
  const { album, expiresAt } = shareData;

  const hasAudioAsset = (song) => !!(
    song?.audioServerUrl ||
    song?.audio?.filename ||
    song?.audio?.url ||
    song?.exportState?.audioFilename
  );
  const hasVideoAsset = (song) => !!(
    song?.exportState?.videoFilename ||
    song?.exportState?.jobId
  );

  const resolveAudioUrl = useCallbackSP(async (song) => {
    const ref = String(
      song?.audioServerUrl ||
      song?.audio?.filename ||
      song?.audio?.url ||
      song?.exportState?.audioFilename || ''
    ).trim();
    if (!ref) return '';
    return window.SongfilmApiConfig.buildMediaUrl('audio', ref);
  }, []);

  const resolveVideoUrl = useCallbackSP((song) => {
    const vf = String(song?.exportState?.videoFilename || '').trim();
    if (vf) return window.SongfilmApiConfig.buildMediaUrl('video', vf);
    const jobId = String(song?.exportState?.jobId || '').trim();
    if (jobId) return `${window.SongfilmApiConfig.getBase('remotion')}/render/${jobId}/file`;
    return '';
  }, []);

  const expiresStr = useMemoSP(() => {
    if (!expiresAt) return '';
    return new Date(expiresAt).toLocaleDateString('ko-KR', {
      year: 'numeric', month: 'long', day: 'numeric',
      hour: '2-digit', minute: '2-digit',
    });
  }, [expiresAt]);

  const renderPanelExtra = useCallbackSP(() => (
    expiresStr ? (
      <div style={{ padding: '8px 0 4px', borderTop: '1px solid var(--line)' }}>
        <span style={{ fontSize: 11.5, color: 'var(--ink-4)', fontFamily: 'var(--font-mono)' }}>
          링크 만료: {expiresStr}
        </span>
      </div>
    ) : null
  ), [expiresStr]);

  // AlbumPlayerView는 albums 배열을 받는다.
  // 공유 앨범은 하나뿐이므로 단일 wrapper item으로 포장한다.
  const wrapperItem = useMemoSP(() => ({
    id:        'shared-album',
    album,
    title:     album?.title     || 'Album',
    artist:    album?.artist    || '',
    songCount: album?.songs?.length || 0,
  }), [album]);

  return (
    <AlbumPlayerView
      albums={[wrapperItem]}
      initialAlbumId="shared-album"
      onExit={() => {}}
      copy={{
        headerLabel: 'SHARED ALBUM',
        title:       '공유된 앨범',
        subtitle:    '앨범 소유자가 공유한 앨범입니다.',
        loadingText: '앨범을 불러오는 중입니다.',
        emptyText:   '앨범을 찾을 수 없습니다.',
      }}
      hasAudioAsset={hasAudioAsset}
      hasVideoAsset={hasVideoAsset}
      resolveAudioUrl={resolveAudioUrl}
      resolveVideoUrl={resolveVideoUrl}
      getAlbumItems={(items) => items}
      getAlbumFromItem={(item) => item?.album || null}
      getItemId={(item) => item?.id || ''}
      getCardTitle={(item, alb) => alb?.title || 'Album'}
      getCardSubtitle={(item, alb) => {
        const count = alb?.songs?.length ?? 0;
        return `${alb?.artist || 'Unknown'} · ${count}곡`;
      }}
      getCardBadge={() => 'SHARED'}
      getPanelLabel={() => '공유 앨범'}
      getPanelPublisher={(item, alb) => alb?.artist || ''}
      getSelectedMissingText={() => '앨범 데이터를 불러오지 못했습니다.'}
      renderPanelExtra={renderPanelExtra}
      showSongfilmAppLink={true}
      showCloseButton={false}
    />
  );
}

// ── 앱 진입점 ──────────────────────────────────────────────────────

function SharePlayerApp() {
  const [status,   setStatus]   = useStateSP('loading');
  const [shareData, setShareData] = useStateSP(null);
  const [errorMsg, setErrorMsg] = useStateSP('');

  useEffectSP(() => {
    const params   = new URLSearchParams(window.location.search);
    const sharedID = params.get('sharedID');

    if (!sharedID) {
      setStatus('notfound');
      setErrorMsg('URL에 sharedID 파라미터가 없습니다.');
      return;
    }

    const base = window.SongfilmApiConfig.getBase('storage');
    fetch(`${base}/share-links/${encodeURIComponent(sharedID)}`)
      .then((res) => res.json().then((data) => ({ ok: res.ok, httpStatus: res.status, data })))
      .then(({ ok, httpStatus, data }) => {
        if (httpStatus === 410 || data.expired) {
          setStatus('expired');
          return;
        }
        if (!ok) {
          setStatus('notfound');
          setErrorMsg(data.error || '앨범을 찾을 수 없습니다.');
          return;
        }
        setShareData({ album: data.album, expiresAt: data.expiresAt });
        setStatus('ready');
      })
      .catch((err) => {
        setStatus('error');
        setErrorMsg(err.message || '네트워크 오류가 발생했습니다.');
      });
  }, []);

  if (status === 'loading') {
    return (
      <div className="share-status-page">
        <div className="share-status-icon">🎵</div>
        <p>앨범을 불러오는 중...</p>
      </div>
    );
  }
  if (status === 'expired')  return <ShareExpiredPage />;
  if (status === 'notfound') return <ShareNotFoundPage message={errorMsg} />;
  if (status === 'error')    return <ShareErrorPage message={errorMsg} />;
  if (status === 'ready' && shareData) return <SharedAlbumPlayer shareData={shareData} />;
  return null;
}

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