/* TimelineShowcase.jsx — interactive multi-track timeline showcase */
(function () {
  'use strict';

  const TLCSS = `
    .tl-btn { background:transparent; border:1px solid #2e2e2e; color:#999; border-radius:4px; padding:4px 9px; font-size:10px; cursor:pointer; font-family:inherit; transition:all 0.12s; }
    .tl-btn:hover { background:#2d2d2d; border-color:rgba(0,255,0,0.4); color:#f5f5f5; box-shadow:0 0 6px rgba(0,255,0,0.25); }
    .tl-btn.active { background:#2d2d2d; border-color:rgba(0,255,0,0.5); color:#00FF00; box-shadow:0 0 6px rgba(0,255,0,0.3); }
    ::-webkit-scrollbar { width:6px; height:6px; }
    ::-webkit-scrollbar-track { background:#111; }
    ::-webkit-scrollbar-thumb { background:#2a2a2a; border-radius:3px; }
    ::-webkit-scrollbar-thumb:hover { background:#00FF00; }
  `;

  const PPS_DEFAULT = 80; // pixels per second

  const INIT_CLIPS = [
    { id:'va', track:'video', start:0,   dur:5.2, name:'Interview.mp4', color:'#1e3a1e', border:'#2a5a2a', accent:'#00cc44', type:'video' },
    { id:'vb', track:'video', start:5.5, dur:3.5, name:'B-Roll.mp4',    color:'#1a1a3e', border:'#2a2a5a', accent:'#4488ff', type:'video' },
    { id:'am', track:'audio', start:0,   dur:10,  name:'Background Music.mp3', color:'#141e14', border:'#1a2a1a', accent:'#00aa33', type:'audio' },
    { id:'tt', track:'text',  start:1.5, dur:2.3, name:'TITLE CARD',    color:'#2a1a3e', border:'#3a2a5a', accent:'#cc88ff', type:'text' },
  ];

  const TRACKS = [
    { id:'video', label:'🎬', name:'Video', height:64 },
    { id:'audio', label:'🎵', name:'Audio', height:64 },
    { id:'text',  label:'T',  name:'Text',  height:40 },
  ];

  // Generate a waveform path for audio clips
  function waveformPath(w, h, seed) {
    let d = `M 0,${h/2}`;
    for (let x = 0; x <= w; x += 2) {
      const phase = x * 0.08 + seed;
      const amp = (Math.sin(phase) * 0.6 + Math.sin(phase*2.3)*0.25 + Math.sin(phase*5)*0.15) * h * 0.42;
      d += ` L ${x},${h/2 - amp}`;
    }
    return d;
  }

  function TlClip({ clip, pps, trackHeight, selected, muted, tool, onSelect, onSplit, onDelete }) {
    const [dragOff, setDragOff]   = React.useState(null);
    const [localStart, setLS]     = React.useState(null);
    const effective = localStart !== null ? localStart : clip.start;
    const w = Math.max(14, clip.dur * pps);
    const isAudio = clip.type === 'audio';
    const isText  = clip.type === 'text';

    const handlePD = e => {
      if (tool === 'razor') return;
      e.stopPropagation();
      onSelect(clip.id);
      const startX = e.clientX;
      const startPx = effective;
      setDragOff(startX);
      const onMove = mv => {
        const dx = mv.clientX - startX;
        const newStart = Math.max(0, startPx + dx / pps);
        setLS(newStart);
      };
      const onUp = () => {
        onSelect(clip.id, localStart);
        setLS(null);
        setDragOff(null);
        window.removeEventListener('pointermove', onMove);
        window.removeEventListener('pointerup', onUp);
      };
      window.addEventListener('pointermove', onMove);
      window.addEventListener('pointerup', onUp);
    };

    const handleClick = e => {
      if (tool === 'razor') {
        e.stopPropagation();
        const rect = e.currentTarget.getBoundingClientRect();
        const relX = e.clientX - rect.left;
        const splitT = relX / pps;
        onSplit(clip.id, splitT);
      }
    };

    return (
      <div
        onPointerDown={handlePD}
        onClick={handleClick}
        title={`${clip.name} · ${clip.dur}s`}
        style={{
          position:'absolute',
          left: effective * pps,
          width: w,
          height: trackHeight - 14,
          top: 7,
          borderRadius:4,
          background: clip.color,
          border: selected ? `1px solid ${clip.accent}` : `1px solid ${clip.border}`,
          borderLeft: `3px solid ${clip.accent}`,
          overflow:'hidden',
          cursor: tool === 'razor' ? 'crosshair' : 'grab',
          opacity: muted ? 0.35 : 1,
          boxShadow: selected ? `0 0 0 1px ${clip.accent},0 0 8px ${clip.accent}55` : 'none',
          transition: dragOff !== null ? 'none' : 'box-shadow 0.12s',
          userSelect:'none',
        }}>
        {/* Thumbnail strip for video */}
        {clip.type === 'video' && (
          <div style={{ position:'absolute', inset:0, display:'flex', gap:1, opacity:0.3, padding:'3px 0 0 4px' }}>
            {Array.from({length: Math.ceil(w/18)}, (_,i) => (
              <div key={i} style={{ width:16, flexShrink:0, height:'100%', borderRadius:2, background:`hsl(${clip.accent === '#00cc44' ? 130+i*4:220+i*4},${40+i*5}%,${20+i*3}%)` }}/>
            ))}
          </div>
        )}
        {/* Waveform for audio */}
        {clip.type === 'audio' && (
          <svg style={{ position:'absolute', bottom:4, left:0, width:'100%', height:16, overflow:'visible' }}>
            <path d={waveformPath(w, 14, clip.id.charCodeAt(0))} fill="none" stroke={clip.accent} strokeWidth="1.2" opacity="0.7"/>
          </svg>
        )}
        {/* Text clip icon */}
        {clip.type === 'text' && (
          <div style={{ position:'absolute', left:5, top:'50%', transform:'translateY(-50%)', fontSize:16, color:clip.accent, fontWeight:900, opacity:0.5 }}>T</div>
        )}
        {/* Clip label */}
        <div style={{ position:'absolute', bottom:4, left:7, right:4, display:'flex', justifyContent:'space-between', alignItems:'center' }}>
          <span style={{ fontSize:10, color:'#fff', fontWeight:600, whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis', maxWidth:'70%' }}>{clip.name}</span>
          <span style={{ fontSize:9, color:'#777', flexShrink:0, marginLeft:4 }}>{clip.dur.toFixed(1)}s</span>
        </div>
      </div>
    );
  }

  function TimelineShowcase({ scale = 1, style = {}, className = '' }) {
    const [clips, setClips]         = React.useState(INIT_CLIPS);
    const [playhead, setPlayhead]   = React.useState(1.8);
    const [playing, setPlaying]     = React.useState(false);
    const [tool, setTool]           = React.useState('select');
    const [snap, setSnap]           = React.useState(true);
    const [pps, setPPS]             = React.useState(PPS_DEFAULT);
    const [mutedTracks, setMuted]   = React.useState(new Set());
    const [selectedClip, setSel]    = React.useState(null);
    const [userDid, setUD]          = React.useState(false);
    const rafRef                    = React.useRef(null);
    const lastTRef                  = React.useRef(null);
    const phRef                     = React.useRef(playhead);
    phRef.current = playhead;

    React.useEffect(() => { return () => cancelAnimationFrame(rafRef.current); }, []);

    const interact = () => { if (!userDid) setUD(true); };

    const startPlay = () => {
      setPlaying(true);
      lastTRef.current = performance.now();
      const tick = now => {
        const dt = (now - lastTRef.current) / 1000;
        lastTRef.current = now;
        const next = phRef.current + dt;
        if (next >= 10) { setPlayhead(0); setPlaying(false); return; }
        setPlayhead(next);
        rafRef.current = requestAnimationFrame(tick);
      };
      rafRef.current = requestAnimationFrame(tick);
    };

    const stopPlay = () => {
      cancelAnimationFrame(rafRef.current);
      setPlaying(false);
    };

    const togglePlay = () => { interact(); playing ? stopPlay() : startPlay(); };

    const handleRulerClick = e => {
      interact();
      const rect = e.currentTarget.getBoundingClientRect();
      const x = e.clientX - rect.left;
      setPlayhead(Math.max(0, Math.min(10, x / pps)));
    };

    const handleSelect = (id, newStart) => {
      interact();
      setSel(id);
      if (newStart !== undefined) {
        setClips(cs => cs.map(c => c.id === id ? { ...c, start: Math.round(newStart * 10) / 10 } : c));
      }
    };

    const handleSplit = (id, relT) => {
      interact();
      setClips(cs => {
        const clip = cs.find(c => c.id === id);
        if (!clip || relT <= 0 || relT >= clip.dur) return cs;
        const a = { ...clip, id: clip.id+'a', dur: Math.round(relT*10)/10 };
        const b = { ...clip, id: clip.id+'b', start: clip.start + relT, dur: Math.round((clip.dur - relT)*10)/10 };
        return cs.filter(c => c.id !== id).concat([a, b]);
      });
    };

    const toggleMute = (tid) => {
      interact();
      setMuted(prev => { const n = new Set(prev); n.has(tid) ? n.delete(tid) : n.add(tid); return n; });
    };

    const formatTC = t => {
      const h = 0, m = 0, s = Math.floor(t), f = Math.round((t%1)*30);
      return `00:00:${String(s).padStart(2,'0')}:${String(f).padStart(2,'0')}`;
    };

    const HEADER_W = 80;
    const RULER_H  = 24;
    const TOTAL_SECS = 10;

    return (
      <div onMouseDown={interact} className={className}
        style={{
          width:900, background:'#0f0f0f', border:'1px solid #2e2e2e',
          borderRadius:8, overflow:'hidden',
          fontFamily:"'Inter',-apple-system,sans-serif",
          transform: scale !== 1 ? `scale(${scale})` : undefined,
          transformOrigin:'top left',
          ...style,
        }}>
        <style>{TLCSS}</style>

        {/* ── Toolbar ── */}
        <div style={{ height:34, background:'#111', borderBottom:'1px solid #1f1f1f', display:'flex', alignItems:'center', padding:'0 10px', gap:6, flexShrink:0 }}>
          {[
            { label:'Select (V)', id:'select' },
            { label:'Razor (C)', id:'razor' },
          ].map(t => (
            <button key={t.id} className={`tl-btn${tool===t.id?' active':''}`} onClick={() => { setTool(t.id); interact(); }}>
              {t.label}
            </button>
          ))}
          <div style={{ width:1, height:16, background:'#2e2e2e', margin:'0 2px' }}/>
          <button className={`tl-btn${snap?' active':''}`} onClick={() => { setSnap(s => !s); interact(); }}>
            Snap: {snap?'ON':'OFF'}
          </button>
          <button className="tl-btn" title="Undo">↩ Undo</button>
          <button className="tl-btn" title="Redo">↪ Redo</button>
          <div style={{ flex:1 }}/>
          <span style={{ fontSize:10, color:'#666' }}>Zoom</span>
          <button className="tl-btn" onClick={() => { setPPS(p => Math.max(40, p-15)); interact(); }}>–</button>
          <button className="tl-btn" onClick={() => { setPPS(p => Math.min(200, p+15)); interact(); }}>+</button>
        </div>

        {/* ── Timeline body ── */}
        <div style={{ display:'flex', flexDirection:'column', overflowX:'auto' }}>
          {/* Ruler */}
          <div style={{ display:'flex', flexShrink:0, height:RULER_H, borderBottom:'1px solid #1f1f1f' }}>
            <div style={{ width:HEADER_W, flexShrink:0, background:'#141414', borderRight:'1px solid #1f1f1f' }}/>
            <div style={{ background:'#111', flex:1, position:'relative', minWidth: TOTAL_SECS * pps, cursor:'pointer' }}
              onClick={handleRulerClick}>
              {Array.from({length: TOTAL_SECS * 2 + 1}, (_,i) => {
                const s = i * 0.5;
                const isMaj = s % 2 === 0;
                return (
                  <div key={i} style={{ position:'absolute', left: s * pps, display:'flex', flexDirection:'column', alignItems:'flex-start', height:'100%' }}>
                    <div style={{ width:1, height: isMaj ? 10 : 5, background: isMaj ? '#444' : '#2e2e2e', marginTop: RULER_H - (isMaj?10:5) }}/>
                    {isMaj && <span style={{ position:'absolute', top:2, left:2, fontSize:9, color:'#666' }}>{s}s</span>}
                  </div>
                );
              })}
            </div>
          </div>

          {/* Tracks */}
          <div style={{ position:'relative' }}>
            {TRACKS.map((track, ti) => (
              <div key={track.id} style={{ display:'flex', borderBottom:'1px solid #1a1a1a' }}>
                {/* Track header */}
                <div style={{ width:HEADER_W, flexShrink:0, background:'#141414', borderRight:'1px solid #1f1f1f', height:track.height, display:'flex', alignItems:'center', padding:'0 8px', gap:6 }}>
                  <span style={{ fontSize:13 }}>{track.label}</span>
                  <span style={{ fontSize:10, color:'#666', flex:1 }}>{track.name}</span>
                  <button onClick={() => toggleMute(track.id)}
                    style={{ background:'transparent', border:'none', cursor:'pointer', fontSize:12, color: mutedTracks.has(track.id) ? '#666' : '#999', padding:0 }}>
                    {mutedTracks.has(track.id) ? '🔇' : '🔊'}
                  </button>
                </div>

                {/* Clip area */}
                <div style={{ flex:1, position:'relative', background:'#0d0d0d', height:track.height, minWidth: TOTAL_SECS * pps }}>
                  {/* Grid lines */}
                  {Array.from({length: TOTAL_SECS * 2}, (_,i) => (
                    <div key={i} style={{ position:'absolute', left: (i+1) * 0.5 * pps, top:0, bottom:0, width:1, background:'#151515', pointerEvents:'none' }}/>
                  ))}
                  {/* Clips for this track */}
                  {clips.filter(c => c.track === track.id).map(c => (
                    <TlClip key={c.id} clip={c} pps={pps} trackHeight={track.height}
                      selected={selectedClip === c.id}
                      muted={mutedTracks.has(track.id)}
                      tool={tool}
                      onSelect={handleSelect}
                      onSplit={handleSplit}
                      onDelete={id => setClips(cs => cs.filter(c => c.id !== id))}
                    />
                  ))}
                  {/* Playhead line for this track */}
                  <div style={{ position:'absolute', top:0, bottom:0, left: playhead * pps, width:2, background:'rgba(255,40,40,0.7)', pointerEvents:'none', zIndex:10 }}/>
                </div>
              </div>
            ))}

            {/* Playhead triangle cap (above all tracks) */}
            <div style={{ position:'absolute', top:0, left: HEADER_W + playhead * pps - 7, zIndex:20, pointerEvents:'none' }}>
              <div style={{ width:0, height:0, borderLeft:'7px solid transparent', borderRight:'7px solid transparent', borderTop:'10px solid #ff2828' }}/>
            </div>
          </div>
        </div>

        {/* ── Play controls ── */}
        <div style={{ height:42, background:'#111', borderTop:'1px solid #1f1f1f', display:'flex', alignItems:'center', padding:'0 12px', gap:8 }}>
          <button className="tl-btn" onClick={() => { interact(); setPlayhead(0); }}>⏮</button>
          <button className="tl-btn" onClick={() => { interact(); setPlayhead(p => Math.max(0, p - 1/30)); }}>⏪</button>
          <button className={`tl-btn${playing?' active':''}`} onClick={togglePlay}
            style={{ minWidth:40, fontWeight:700, fontSize:14 }}>
            {playing ? '⏸' : '▶'}
          </button>
          <button className="tl-btn" onClick={() => { interact(); setPlayhead(p => Math.min(10, p + 1/30)); }}>⏩</button>
          <button className="tl-btn" onClick={() => { interact(); setPlayhead(10); stopPlay(); }}>⏭</button>
          <div style={{ width:1, height:20, background:'#2e2e2e', margin:'0 4px' }}/>
          <span style={{ fontFamily:'monospace', fontSize:12, color:'#f5f5f5', letterSpacing:1 }}>{formatTC(playhead)}</span>
          <span style={{ fontSize:10, color:'#666', marginLeft:4 }}>/ 00:00:10:00</span>
          <div style={{ flex:1 }}/>
          {selectedClip && (
            <div style={{ background:'#1a1a1a', border:'1px solid #333', borderRadius:4, padding:'4px 10px', fontSize:10, color:'#999' }}>
              {clips.find(c => c.id === selectedClip)?.name} selected
            </div>
          )}
        </div>
      </div>
    );
  }

  window.TimelineShowcase = TimelineShowcase;
})();
