import React, { useRef, useEffect, useCallback } from 'react';
import { useStudioStore } from '../store/useStudioStore';
import { Keyframe } from '../utils/timeline';
import './Timeline.css';

const Timeline: React.FC = () => {
  const {
    objects, selectedId,
    tracks, playhead, setPlayhead,
    timelinePlaying, setTimelinePlaying,
    timelineDuration, setTimelineDuration,
    addKeyframe, removeKeyframe,
  } = useStudioStore();

  const rafRef      = useRef<number>(0);
  const lastTimeRef = useRef<number>(0);
  const playheadRef = useRef<number>(playhead);   // ← ref so tick closure stays fresh
  const rulerRef    = useRef<HTMLDivElement>(null);

  // Keep ref in sync with store value
  useEffect(() => { playheadRef.current = playhead; }, [playhead]);

  // ── Playback loop ─────────────────────────────────────────────
  useEffect(() => {
    if (!timelinePlaying) {
      cancelAnimationFrame(rafRef.current);
      return;
    }
    const tick = (now: number) => {
      const delta = (now - lastTimeRef.current) / 1000;
      lastTimeRef.current = now;
      const next = playheadRef.current + delta;
      if (next >= timelineDuration) {
        setPlayhead(timelineDuration);
        setTimelinePlaying(false);
        return;
      }
      setPlayhead(next);
      rafRef.current = requestAnimationFrame(tick);
    };
    lastTimeRef.current = performance.now();
    rafRef.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(rafRef.current);
  }, [timelinePlaying, timelineDuration, setPlayhead, setTimelinePlaying]);

  // ── Add keyframe at playhead for selected object ──────────────
  const handleAddKeyframe = useCallback(() => {
    if (!selectedId) return;
    const obj = objects.find(o => o.id === selectedId);
    if (!obj) return;
    const kf: Keyframe = {
      id:       Math.random().toString(36).slice(2),
      time:     parseFloat(playheadRef.current.toFixed(3)),
      position: [...obj.position] as [number, number, number],
      rotation: [...obj.rotation] as [number, number, number],
      scale:    [...obj.scale]    as [number, number, number],
      easing:   'ease-in-out',
    };
    addKeyframe(selectedId, kf);
  }, [selectedId, objects, addKeyframe]);

  // ── Keyboard shortcut: I = insert keyframe ────────────────────
  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      if (e.key === 'i' || e.key === 'I') handleAddKeyframe();
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, [handleAddKeyframe]);

  // ── Click ruler to seek ───────────────────────────────────────
  const handleRulerClick = useCallback((e: React.MouseEvent<HTMLDivElement>) => {
    const rect = rulerRef.current?.getBoundingClientRect();
    if (!rect) return;
    const t = ((e.clientX - rect.left) / rect.width) * timelineDuration;
    setPlayhead(Math.max(0, Math.min(timelineDuration, t)));
  }, [timelineDuration, setPlayhead]);

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

  const playheadPct = (playhead / timelineDuration) * 100;

  return (
    <div className="timeline">

      {/* ── Controls bar ── */}
      <div className="tl-controls">
        <button className="tl-btn" title="Rewind"
          onClick={() => { setPlayhead(0); setTimelinePlaying(false); }}>⏮</button>

        <button
          className={`tl-btn tl-play ${timelinePlaying ? 'playing' : ''}`}
          onClick={() => setTimelinePlaying(!timelinePlaying)}
        >
          {timelinePlaying ? '⏸' : '▶'}
        </button>

        <button className="tl-btn" title="Go to end"
          onClick={() => { setPlayhead(timelineDuration); setTimelinePlaying(false); }}>⏭</button>

        <div className="tl-time">{fmt(playhead)} / {fmt(timelineDuration)}</div>

        <button
          className={`tl-btn tl-kf-btn ${!selectedId ? 'disabled' : ''}`}
          onClick={handleAddKeyframe}
          disabled={!selectedId}
          title="Add keyframe at playhead (I)"
        >
          ◆ ADD KEY
        </button>

        <div className="tl-duration">
          <label>Dur</label>
          <input
            type="number" min={1} max={120} step={1}
            value={timelineDuration}
            onChange={(e) => setTimelineDuration(parseInt(e.target.value) || 5)}
          />
          <span>s</span>
        </div>
      </div>

      {/* ── Track area ── */}
      <div className="tl-body">

        {/* Object labels column */}
        <div className="tl-labels">
          {objects.length === 0 && (
            <div className="tl-empty">Load a model first</div>
          )}
          {objects.map(obj => {
            const kfCount = tracks.find(t => t.objectId === obj.id)?.keyframes.length ?? 0;
            return (
              <div key={obj.id}
                className={`tl-label ${selectedId === obj.id ? 'active' : ''}`}>
                <span className="tl-label-dot">◈</span>
                <span className="tl-label-name">{obj.name}</span>
                {kfCount > 0 && <span className="tl-kf-count">{kfCount}K</span>}
              </div>
            );
          })}
        </div>

        {/* Ruler + tracks column */}
        <div className="tl-tracks-wrap">

          {/* Ruler */}
          <div className="tl-ruler" ref={rulerRef} onClick={handleRulerClick}>
            {Array.from({ length: timelineDuration + 1 }, (_, i) => (
              <div key={i} className="tl-tick"
                style={{ left: `${(i / timelineDuration) * 100}%` }}>
                <span>{i}s</span>
              </div>
            ))}
            <div className="tl-playhead" style={{ left: `${playheadPct}%` }} />
          </div>

          {/* Keyframe tracks */}
          <div className="tl-tracks">
            {objects.map(obj => {
              const track  = tracks.find(t => t.objectId === obj.id);
              const sorted = track
                ? [...track.keyframes].sort((a, b) => a.time - b.time)
                : [];
              return (
                <div key={obj.id}
                  className={`tl-track ${selectedId === obj.id ? 'active' : ''}`}>

                  {/* Connection lines */}
                  {sorted.map((kf, i) => {
                    if (i === sorted.length - 1) return null;
                    const x1 = (kf.time          / timelineDuration) * 100;
                    const x2 = (sorted[i+1].time / timelineDuration) * 100;
                    return (
                      <div key={kf.id + '-line'} className="tl-kf-line"
                        style={{ left: `${x1}%`, width: `${x2 - x1}%` }} />
                    );
                  })}

                  {/* Keyframe diamonds */}
                  {sorted.map(kf => (
                    <div key={kf.id}
                      className="tl-kf-diamond"
                      style={{ left: `${(kf.time / timelineDuration) * 100}%` }}
                      title={`${kf.time.toFixed(2)}s  •  click to delete`}
                      onClick={(e) => { e.stopPropagation(); removeKeyframe(obj.id, kf.id); }}
                    >◆</div>
                  ))}

                  {/* Playhead ghost line */}
                  <div className="tl-track-playhead"
                    style={{ left: `${playheadPct}%` }} />
                </div>
              );
            })}
          </div>

        </div>
      </div>
    </div>
  );
};

export default Timeline;