// Scene 3: The Fix — Tasks snap into time-blocks (9–17s)
// Camera reveals a clean Timeblind app. Empty rail appears. Tasks fly in
// from the sides (Todoist + GCal sources) and snap into colored blocks.

const SCHEDULE = [
  { id: 'wake',  startMin: 7*60,         dur: 30, title: 'Morning routine',   icon: '☀',  color: TB.peach,    src: 'todoist',  delay: 0.0 },
  { id: 'focus', startMin: 8*60,         dur: 90, title: 'Deep work · Q3 doc',icon: '✦',  color: TB.orangeSoft,src: 'todoist', delay: 0.3 },
  { id: 'sync',  startMin: 9*60+30,      dur: 30, title: 'Team standup',      icon: '◐',  color: TB.sky,      src: 'gcal',     delay: 0.6 },
  { id: 'walk',  startMin: 10*60+15,     dur: 30, title: 'Walk + coffee',     icon: '◇',  color: TB.sage,     src: 'todoist',  delay: 0.9 },
  { id: 'lunch', startMin: 12*60,        dur: 45, title: 'Lunch with Sam',    icon: '◉',  color: TB.butter,   src: 'gcal',     delay: 1.2 },
  { id: 'rev',   startMin: 13*60,        dur: 60, title: 'Design review',     icon: '◑',  color: TB.lavender, src: 'gcal',     delay: 1.5 },
  { id: 'kids',  startMin: 15*60+30,     dur: 30, title: 'Pick up kids',      icon: '♡',  color: TB.rose,     src: 'todoist',  delay: 1.8 },
  { id: 'home',  startMin: 17*60,        dur: 60, title: 'Family dinner',    icon: '✿',  color: TB.mint,     src: 'gcal',     delay: 2.1 },
];

const RAIL_START_MIN = 6 * 60;       // 6:00 am
const RAIL_END_MIN   = 19 * 60;      // 7:00 pm
const RAIL_HEIGHT    = 940;          // px on the canvas
const PX_PER_MIN     = RAIL_HEIGHT / (RAIL_END_MIN - RAIL_START_MIN);

function Scene3Build() {
  const { localTime, progress, duration } = useSprite();

  // Camera: small inward push during build
  const camScale = 1 + 0.02 * progress;

  return (
    <div style={{
      position: 'absolute', inset: 0,
      background: TB.bg,
      transform: `scale(${camScale})`,
      transformOrigin: 'center center',
    }}>
      {/* App chrome */}
      <AppChrome localTime={localTime}/>

      {/* Side panels for source apps (left: Todoist, right: GCal) */}
      <LocalSprite start={0.0} end={duration - 0.4}>
        <SourcePanel side="left"  source="todoist" />
      </LocalSprite>
      <LocalSprite start={0.0} end={duration - 0.4}>
        <SourcePanel side="right" source="gcal" />
      </LocalSprite>

      {/* The hero rail */}
      <Rail localTime={localTime}/>

      {/* Tasks flying in and snapping */}
      {SCHEDULE.map(b => (
        <FlyingTask key={b.id} block={b} sceneTime={localTime}/>
      ))}

      {/* Caption */}
      <LocalSprite start={5.4} end={duration - 0.2}>
        <BuildCaption/>
      </LocalSprite>
    </div>
  );
}

function AppChrome({ localTime }) {
  const t = clamp(localTime / 0.4, 0, 1);
  const o = Easing.easeOutCubic(t);
  return (
    <div style={{
      position: 'absolute', top: 0, left: 0, right: 0, height: 76,
      background: '#fff',
      borderBottom: `1px solid ${TB.rail}`,
      display: 'flex', alignItems: 'center',
      padding: '0 40px',
      opacity: o,
    }}>
      <div style={{
        width: 32, height: 32,
        borderRadius: 8,
        background: TB.orange,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        marginRight: 14,
        boxShadow: `0 4px 10px ${TB.orange}55`,
      }}>
        <div style={{ width: 14, height: 14, border: '2.5px solid #fff', borderRadius: '50%', borderTopColor: 'transparent' }}/>
      </div>
      <div style={{ fontFamily: TB.display, fontWeight: 800, fontSize: 22, color: TB.fg, letterSpacing: '-0.02em' }}>
        Timeblind
      </div>
      <div style={{ flex: 1 }}/>
      <div style={{ display: 'flex', gap: 28, alignItems: 'center' }}>
        {['Today', 'Schedules', 'Inbox', 'Share'].map((label, i) => (
          <div key={label} style={{
            fontFamily: TB.body, fontSize: 16, fontWeight: i === 0 ? 700 : 500,
            color: i === 0 ? TB.fg : TB.muted,
            position: 'relative',
            paddingBottom: 4,
            borderBottom: i === 0 ? `2px solid ${TB.orange}` : 'none',
          }}>{label}</div>
        ))}
      </div>
      <div style={{ width: 36, height: 36, borderRadius: '50%', background: TB.lavender, marginLeft: 28,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontFamily: TB.display, fontWeight: 700, fontSize: 14, color: '#3a1f5a' }}>
        AC
      </div>
    </div>
  );
}

function Rail({ localTime }) {
  const t = clamp((localTime - 0.2) / 0.6, 0, 1);
  const o = Easing.easeOutCubic(t);
  const railTop = 110;

  // Rail "draws in" from top to bottom
  const drawT = clamp((localTime - 0.4) / 0.8, 0, 1);
  const drawnHeight = RAIL_HEIGHT * Easing.easeOutCubic(drawT);

  // "Now" line position
  const nowMin = 9 * 60 + 47; // 9:47am — matches Scene 1
  const nowY = (nowMin - RAIL_START_MIN) * PX_PER_MIN;
  const nowAppear = clamp((localTime - 1.0) / 0.4, 0, 1);

  return (
    <div style={{
      position: 'absolute',
      left: '50%',
      top: railTop,
      transform: 'translateX(-50%)',
      width: 720,
      height: RAIL_HEIGHT + 40,
      opacity: o,
    }}>
      {/* Date header */}
      <div style={{
        fontFamily: TB.display, fontWeight: 800, fontSize: 32, color: TB.fg,
        letterSpacing: '-0.02em', marginBottom: 4,
      }}>Tuesday</div>
      <div style={{
        fontFamily: TB.body, fontSize: 16, color: TB.muted, marginBottom: 22, fontWeight: 500,
      }}>April 28 · 8 blocks · 5h 25m planned</div>

      <div style={{ position: 'relative', display: 'grid', gridTemplateColumns: '70px 1fr', gap: 12, height: RAIL_HEIGHT }}>
        {/* Hour gutter */}
        <div style={{ position: 'relative', height: RAIL_HEIGHT }}>
          {Array.from({ length: 14 }, (_, i) => {
            const h = 6 + i;
            const y = i * 60 * PX_PER_MIN;
            return (
              <div key={h} style={{
                position: 'absolute', left: 0, top: y - 8,
                fontFamily: TB.mono, fontSize: 13, color: TB.muted,
                fontWeight: 500, letterSpacing: '0.04em',
              }}>
                {String(h).padStart(2, '0')}:00
              </div>
            );
          })}
        </div>

        {/* Block area */}
        <div style={{ position: 'relative', height: RAIL_HEIGHT, overflow: 'hidden' }}>
          {/* Hour gridlines — drawn in */}
          {Array.from({ length: 14 }, (_, i) => {
            const y = i * 60 * PX_PER_MIN;
            const lineT = clamp((localTime - 0.3 - i * 0.04) / 0.3, 0, 1);
            return (
              <div key={i} style={{
                position: 'absolute', left: 0, right: 0, top: y,
                height: 1, background: TB.rail,
                transform: `scaleX(${lineT})`,
                transformOrigin: 'left',
                opacity: lineT,
              }}/>
            );
          })}

          {/* Drawn rail mask cover (reveals from top down) */}
          {drawT < 1 && (
            <div style={{
              position: 'absolute', left: 0, right: 0,
              top: drawnHeight,
              bottom: 0,
              background: TB.bg,
              zIndex: 5,
            }}/>
          )}

          {/* Now line */}
          {nowAppear > 0 && (
            <div style={{
              position: 'absolute', left: -12, right: 0, top: nowY,
              opacity: nowAppear,
              transform: `translateX(${(1 - nowAppear) * -12}px)`,
              zIndex: 4,
            }}>
              <div style={{
                position: 'absolute', left: 0, right: 0, top: -1, height: 2,
                background: TB.orange,
                boxShadow: `0 0 8px ${TB.orange}66`,
              }}/>
              <div style={{
                position: 'absolute', left: -8, top: -7, width: 14, height: 14,
                borderRadius: '50%', background: TB.orange,
                boxShadow: `0 0 0 4px ${TB.orange}33`,
              }}/>
              <div style={{
                position: 'absolute', right: -2, top: -22,
                fontFamily: TB.mono, fontSize: 12, fontWeight: 700,
                color: TB.orange, letterSpacing: '0.08em',
              }}>NOW · 9:47</div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

function FlyingTask({ block, sceneTime }) {
  // Each block: appears as a "raw task" near a source panel,
  // then flies to its rail position and morphs into a colored block.
  const flyStart = 1.4 + block.delay;
  const flyDur = 0.7;
  const settleT = clamp((sceneTime - flyStart) / flyDur, 0, 1);
  const eased = Easing.easeInOutCubic(settleT);

  // Rail target position (in canvas coords)
  const railLeft = STAGE_W / 2 - 360 + 70 + 12;  // rail center - half + gutter
  const railTopY = 110 + 64; // chrome 76 + header 80ish... using calibrated value
  const targetX = railLeft;
  const targetY = railTopY + (block.startMin - RAIL_START_MIN) * PX_PER_MIN;
  const targetW = 638;
  const targetH = block.dur * PX_PER_MIN;

  // Source position (off the rail, at side panels)
  const sourceX = block.src === 'todoist' ? 60 : STAGE_W - 360;
  const sourceY = 220 + (block.delay * 60); // staggered down the panel
  const sourceW = 280;
  const sourceH = 56;

  // Position interpolation
  const x = sourceX + (targetX - sourceX) * eased;
  const y = sourceY + (targetY - sourceY) * eased;
  const w = sourceW + (targetW - sourceW) * eased;
  const h = sourceH + (targetH - sourceH) * eased;

  // Don't render before flying
  if (sceneTime < flyStart - 0.1) return null;

  // Fade in source ticks at start
  const sourceFadeIn = clamp((sceneTime - (flyStart - 0.1)) / 0.15, 0, 1);

  // Snap pulse on arrival
  const snapPulse = settleT > 0.95
    ? Math.sin((settleT - 0.95) * 60) * (1 - settleT) * 0.04
    : 0;

  // While flying, show as small "task" with checkbox; after settled, show as block
  const morphT = clamp((settleT - 0.7) / 0.3, 0, 1);

  return (
    <div style={{
      position: 'absolute',
      left: x, top: y,
      width: w, height: h,
      background: block.color,
      borderRadius: 14 + 4 * (1 - morphT),
      boxShadow: settleT < 1
        ? '0 12px 32px rgba(0,0,0,0.18), 0 4px 8px rgba(0,0,0,0.1)'
        : '0 2px 6px rgba(0,0,0,0.04)',
      transform: `scale(${1 + snapPulse})`,
      opacity: sourceFadeIn,
      padding: settleT < 0.9 ? '14px 18px' : '14px 20px',
      display: 'flex',
      alignItems: morphT < 0.5 ? 'center' : 'flex-start',
      gap: 14,
      overflow: 'hidden',
      zIndex: 6,
      transition: 'box-shadow 0.3s',
    }}>
      {/* Icon dot */}
      <div style={{
        width: morphT < 0.5 ? 24 : 30,
        height: morphT < 0.5 ? 24 : 30,
        borderRadius: morphT < 0.5 ? 6 : 9,
        background: 'rgba(0,0,0,0.18)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        color: '#fff', fontWeight: 800, fontSize: 16,
        flexShrink: 0,
      }}>{block.icon}</div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{
          fontFamily: TB.display,
          fontWeight: 700,
          fontSize: morphT < 0.5 ? 16 : 19,
          color: 'rgba(0,0,0,0.78)',
          letterSpacing: '-0.01em',
          whiteSpace: 'nowrap',
          overflow: 'hidden',
          textOverflow: 'ellipsis',
        }}>{block.title}</div>
        {h > 50 && morphT > 0.3 && (
          <div style={{
            fontFamily: TB.mono,
            fontSize: 13,
            color: 'rgba(0,0,0,0.55)',
            marginTop: 4,
            opacity: morphT,
            fontWeight: 500,
          }}>
            {fmtTime12(block.startMin)} – {fmtTime12(block.startMin + block.dur)}
          </div>
        )}
      </div>
    </div>
  );
}

function SourcePanel({ side, source }) {
  const { localTime } = useSprite();
  const t = clamp((localTime - 0.2) / 0.5, 0, 1);
  const o = Easing.easeOutCubic(t) * 0.85;

  const isLeft = side === 'left';
  const config = source === 'todoist'
    ? { name: 'Todoist',         color: '#e44332', dot: '⬢' }
    : { name: 'Google Calendar', color: '#1a73e8', dot: '◇' };

  return (
    <div style={{
      position: 'absolute',
      [isLeft ? 'left' : 'right']: 36,
      top: 130,
      width: 280,
      opacity: o,
      transform: `translateX(${isLeft ? -1 : 1}${(1 - t) * 16}px)`,
    }}>
      <div style={{
        display: 'flex', alignItems: 'center', gap: 10,
        marginBottom: 12,
        fontFamily: TB.body, fontSize: 13, color: TB.muted,
        textTransform: 'uppercase', letterSpacing: '0.16em', fontWeight: 700,
      }}>
        <div style={{ width: 8, height: 8, borderRadius: 2, background: config.color }}/>
        {config.name}
      </div>
      <div style={{
        fontFamily: TB.body, fontSize: 13, color: TB.muted, fontWeight: 500,
        marginBottom: 16,
      }}>connected · syncing</div>
      {/* Small task placeholders (so panel doesn't look empty after tasks fly out) */}
      <div style={{
        height: 480,
        background: '#fff',
        border: `1px solid ${TB.rail}`,
        borderRadius: 12,
        padding: 14,
        display: 'flex', flexDirection: 'column', gap: 10,
      }}>
        {Array.from({ length: 6 }).map((_, i) => (
          <div key={i} style={{
            height: 14, borderRadius: 4,
            background: TB.rail,
            width: `${60 + (i % 3) * 14}%`,
            opacity: 0.5,
          }}/>
        ))}
      </div>
    </div>
  );
}

function BuildCaption() {
  const { localTime, duration } = useSprite();
  const inT = clamp(localTime / 0.4, 0, 1);
  const outT = clamp((localTime - (duration - 0.4)) / 0.4, 0, 1);
  const o = Easing.easeOutCubic(inT) * (1 - outT);

  return (
    <div style={{
      position: 'absolute',
      left: 60, bottom: 60,
      opacity: o,
      transform: `translateY(${(1 - inT) * 12}px)`,
    }}>
      <div style={{
        fontFamily: TB.mono, fontSize: 14, color: TB.orange,
        letterSpacing: '0.2em', textTransform: 'uppercase', fontWeight: 700,
        marginBottom: 8,
      }}>The fix</div>
      <div style={{
        fontFamily: TB.display, fontSize: 56, fontWeight: 800, color: TB.fg,
        letterSpacing: '-0.025em', lineHeight: 1.05, maxWidth: 640,
      }}>
        Your tasks, on a day<br/>you can <em style={{ color: TB.orange, fontStyle: 'normal' }}>see</em>.
      </div>
    </div>
  );
}

window.Scene3Build = Scene3Build;
window.SCHEDULE = SCHEDULE;
window.RAIL_START_MIN = RAIL_START_MIN;
window.RAIL_END_MIN = RAIL_END_MIN;
window.RAIL_HEIGHT = RAIL_HEIGHT;
window.PX_PER_MIN = PX_PER_MIN;
window.AppChrome = AppChrome;
