// FloatingPortfolio
// --------------------------------------------------------------------------
// Auto-loads every file dropped into  /assets/portfolio/  and renders it as a
// tile in the scrolling strip. The folder is scanned by assets/portfolio/list.php
// (PHP runs on Hostinger by default). Drop a .mp4/.webm/.gif in that folder and
// it appears here on refresh — no code editing.
//
// The caption is derived from the file name:  "01-haya-bitar.mp4" -> "Haya Bitar"
//
// If list.php can't be reached (e.g. a plain local preview with no PHP), it
// falls back to the demo tiles below so the section never looks empty.
// --------------------------------------------------------------------------

const PORTFOLIO_DIR = 'assets/portfolio/';

const VIDEO_EXTS = ['mp4', 'webm', 'mov', 'm4v', 'ogv'];

// Shown only when the live folder can't be read (local preview without PHP).
// Kept in sync with the real files in assets/portfolio/ so the preview matches.
const FALLBACK_TILES = [
  { src: 'assets/portfolio/1.mp4', caption: '' },
  { src: 'assets/portfolio/2.mp4', caption: '' },
  { src: 'assets/portfolio/3.mp4', caption: '' },
  { src: 'assets/portfolio/4.mp4', caption: '' },
  { src: 'assets/portfolio/5.mp4', caption: '' },
  { src: 'assets/portfolio/6.mp4', caption: '' },
  { src: 'assets/portfolio/7.mp4', caption: '' },
  { src: 'assets/portfolio/8.mp4', caption: '' },
  { src: 'assets/portfolio/9.mp4', caption: '' },
];

function captionFromFilename(name) {
  const base = name.replace(/\.[^.]+$/, ''); // drop extension
  // Treat order-only / code-style names (e.g. "1", "01", "a1", "b2") as no caption.
  if (/^\d+$/.test(base) || /^[a-z]\d+$/i.test(base)) return '';
  return base
    .replace(/^\s*\d+\s*[-_.]\s*/, '') // drop a leading order prefix like "01-"
    .replace(/[-_]+/g, ' ')         // dashes/underscores -> spaces
    .replace(/\s+/g, ' ')
    .trim()
    .replace(/\b\w/g, (c) => c.toUpperCase()); // Title Case
}

function isVideo(src) {
  const ext = (src.split('.').pop() || '').toLowerCase();
  return VIDEO_EXTS.includes(ext);
}

function FloatingPortfolio() {
  const [tiles, setTiles] = React.useState(null); // null = still loading

  React.useEffect(() => {
    let cancelled = false;
    fetch(PORTFOLIO_DIR + 'list.php', { cache: 'no-cache' })
      .then((r) => (r.ok ? r.json() : Promise.reject()))
      .then((files) => {
        if (cancelled) return;
        if (Array.isArray(files) && files.length) {
          setTiles(
            files.map((f) => ({ src: PORTFOLIO_DIR + f, caption: captionFromFilename(f) }))
          );
        } else {
          setTiles(FALLBACK_TILES); // folder reachable but empty
        }
      })
      .catch(() => {
        if (!cancelled) setTiles(FALLBACK_TILES); // no PHP / not found
      });
    return () => { cancelled = true; };
  }, []);

  const list = tiles || FALLBACK_TILES;

  // Duplicate the array for a seamless marquee loop.
  const loop = [...list, ...list];

  return (
    <section style={{
      position: 'relative',
      padding: '40px 0 60px',
      overflow: 'hidden',
      isolation: 'isolate',
    }}>
      {/* edge fades */}
      <div aria-hidden style={{
        position: 'absolute',
        top: 0, bottom: 0, left: 0,
        width: 140,
        background: 'linear-gradient(90deg, var(--bg) 0%, transparent 100%)',
        zIndex: 3,
        pointerEvents: 'none',
      }} />
      <div aria-hidden style={{
        position: 'absolute',
        top: 0, bottom: 0, right: 0,
        width: 140,
        background: 'linear-gradient(270deg, var(--bg) 0%, transparent 100%)',
        zIndex: 3,
        pointerEvents: 'none',
      }} />

      <div className="marquee" style={{ gap: 14, animationDuration: '60s' }}>
        {loop.map((tile, i) => (
          <div key={i} style={{
            flex: '0 0 auto',
            width: 148,
            aspectRatio: '9/16',
            borderRadius: 14,
            overflow: 'hidden',
            position: 'relative',
            border: '1px solid var(--line)',
            background: '#0a0e18',
            boxShadow: '0 10px 30px rgba(0,0,0,0.4)',
          }}>
            {isVideo(tile.src) ? (
              <video
                src={tile.src}
                autoPlay
                muted
                loop
                playsInline
                preload="metadata"
                style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}
              />
            ) : (
              <img
                src={tile.src}
                alt={tile.caption}
                loading="lazy"
                style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}
              />
            )}
            {tile.caption ? (
              <div style={{
                position: 'absolute',
                left: 10, bottom: 8,
                fontSize: 11,
                color: '#fff',
                textShadow: '0 1px 4px rgba(0,0,0,0.8)',
                letterSpacing: '-0.01em',
              }}>{tile.caption}</div>
            ) : null}
          </div>
        ))}
      </div>
    </section>
  );
}

Object.assign(window, { FloatingPortfolio });
